【问题标题】:Array Access Complexity数组访问复杂度
【发布时间】:2014-01-04 03:18:59
【问题描述】:

在 Java 中,假设我需要在代码中多次访问 array1[index]

即使对于非常大的数组,我是否可以假设每个单独的数组访问都需要恒定的时间?
这在语言或底层架构之间会有所不同吗?

【问题讨论】:

标签: java optimization data-structures time-complexity


【解决方案1】:

数组查找总是 O(1)。它不依赖于数组的大小。数组的基本思想是它包含具有固定大小的对象/引用,因此您只需执行size * index 即可获得您要查找的对象的位置。

所以它不像LinkedList(即O(n),也不是HashMap,即O(1) 摊销。

我认为大多数语言都是这种情况。 javascript 可能是一个例外,因此请务必检查您使用的语言的文档。

【讨论】:

  • 在考虑到较大的数组可能不适合内存页面时,数组大小肯定会发挥作用。
  • 每种语言都不一样 - 例如,其他答案之一提到了 javascript。
  • 这是内存分页问题而不是语言问题。
  • 但是内存分页会改变访问时间。
  • 我认为你可以说在那种极端情况下访问时间是摊销的O(1)
【解决方案2】:

对于 array1 大小为 N 的大值,我可以假设每个单个数组访问 (array1[index]) 需要恒定时间吗?

在 Java 中,是的。同样在 C、C++ 和 C# 中,除非可能超出范围的操作系统级内存分页问题。

此访问时间是否取决于语言(java 与 C++)或底层架构?

它可以,如果所讨论的语言将事物称为“数组”,而不是通常的“连续内存块”意义上的真正数组。 (JavaScript 会这样做;它的 Array ([]) 类型 is really a map;PHP 使用术语“数组”作为“关联数组”[例如,映射]的简写。)因此,对于给定的环境/语言,它是值得的检查该术语没有被滥用或随意使用。

【讨论】:

    【解决方案3】:

    访问数组中的元素是常数时间(它只是计算地址偏移量)。对于您列出的所有语言,此行为都是一致的。虽然不应该假定它适用于所有语言,但它适用于大多数语言。

    在缓存未命中/命中、管道等方面存在一些复杂性,但基本上是恒定时间。

    List 并非如此。一些 List 实现为不同的操作提供了不同的性能特征。

    扩展复杂性:

    问题是“大型数组的访问速度会变慢”。正确答案是“是”。

    就访问顺序而言,它将保持 O(1),但实际访问可能需要相当长的时间。例如,如果数组的大小导致您出现缓存未命中(因此数据需要从主内存获取到处理器的缓存)和/或内存分页问题(因此需要从磁盘获取数据),它将变得更慢,尽管那是任何大型数据集的属性,而不是数组。

    在大多数情况下,这种差异并不值得担心。在您开始担心诸如缓存未命中之类的事情之前,我们正在谈论相当重的优化。然而,正如这个问题所说明的那样,这些事情是值得了解的:

    Why is it faster to process a sorted array than an unsorted array?

    由于处理器工作方式的细节,代码上看似无关的细节(数组的预排序)从表面上看应该总是花费相同的时间运行速度提高五倍。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-26
      • 1970-01-01
      • 2010-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-09
      • 1970-01-01
      相关资源
      最近更新 更多