【问题标题】:Does accessing array elements by index take longer if the indices are further apart?如果索引相距更远,按索引访问数组元素是否需要更长的时间?
【发布时间】:2018-05-26 19:05:46
【问题描述】:

做类似的事情

Console.WriteLine(arr[0]);
Console.WriteLine(arr[1]);

Console.WriteLine(arr[0]);
Console.WriteLine(arr[1823]);

出于硬件级别的原因?

【问题讨论】:

  • 一般情况下没有。但是有一些与缓存相关的细微差别。
  • 在大多数情况下是的。假设数组包含整数,并且第一个元素不在任何 CPU 缓存中,应该从主内存中获取。它不会单独获取,它只有 4 个字节,仅获取这 4 个字节效率不高。相反,更大的连续内存块被获取并缓存在 CPU 中。现在,当您在下一行访问第二个元素时 - 它现在在 CPU 缓存中的可能性很高,并且不需要打扰主内存。从缓存中获取比从内存中获取要快得多。如果您下次访问第 1823 个元素 - 它不太可能在缓存中,需要再次访问内存。
  • 我不同意 EVK。内存就是内存,如果它是主内存或缓存,则不应有所作为。微处理器有扇区,只要内存扇区有效,就应该有所作为。如今,微处理器可以使用扇区和地址(64 位)访问内存位置,并且可以一次获取位置。任何偏移量(最多 64 位)也可以添加到一条微处理器指令中。如果您正在处理大小大于 64 位的巨大内存,则需要更长的时间。
  • 它比 Evk 说的还要复杂。例如,假设您的算法读取整个数组,但只是以随机顺序。如果整个数组适合缓存,那么您仍然会读取相同数量的主内存,就好像您顺序读取数组一样,因此所用时间将相同。您的问题无法真正孤立地回答。

标签: c# .net arrays


【解决方案1】:

访问数组元素或多或少是 O(1)。那是因为,当您执行myIntArray[500] 时,您实际上是在执行以下操作:memory_location + 500 * sizeof(int)

现在,从技术上讲,较大的数字相乘需要更长的时间,但这种差异非常小,所以我们可以称之为 O(1),因此您的示例中的差异可能永远不会被感受到。

【讨论】:

  • 这太简单了。主存和缓存之间的交互是驱动实际性能的因素。
  • 这是我搜索后发现的。
  • 你发现了什么?你的回答,还是我的评论?
  • 我的回答,通过几个 StackOverflow 问题。
  • 恐怕你认为你发现的不正确。
猜你喜欢
  • 2019-07-28
  • 1970-01-01
  • 2019-01-27
  • 2019-08-10
  • 2014-12-08
  • 1970-01-01
  • 1970-01-01
  • 2019-09-02
  • 2010-12-18
相关资源
最近更新 更多