数组访问总是恒定时间/ O(1)?

时间:2014-11-05 01:45:06

标签: arrays performance optimization

来自Richard Bird, Pearls of Functional Algorithm Design (2010),第6页:

  

对于纯函数式编程器,更新操作采用数组大小​​的对数时间。公平地说,程序程序员也很欣赏恒定时间索引和更新   只有当数组很小时才有可能。

在什么条件下数组有非恒定时间访问?这与CPU缓存有关吗?

4 个答案:

答案 0 :(得分:5)

大多数现代机器架构都试图提供小型单位时间内存访问。

他们失败了。相反,我们看到不同速度的缓存层。

问题很简单:光速。如果你需要一个巨大的记忆[数组](在极端情况下,想象一个像仙女座星系大小的记忆),它将占用巨大的空间,光线不能在短时间内穿越巨大的空间。信息的传播速度不能超过光速。你从一开始就被物理学搞砸了。

所以你能做的最好的事情就是建立记忆的一部分"附近"其中光仅需要几分之一纳秒来遍历(因此寄存器和L1缓存),并且部分内存远离磁盘驱动器(磁盘驱动器)。其他实际的复杂情况随之而来,例如电容(想想惯性),以减缓对更远的物品的访问。

现在,如果您愿意将最远的内存元素的访问时间作为" unit"时间,是的,访问所有内容需要相同的时间,例如,O(1)。在实际计算中,我们大多数时候都会以这种方式处理RAM内存,而我们会忽略其他较慢的设备,以避免搞砸我们的简单模型。

然后你会发现那些对此并不满意的人,瞧,你有人优化缓存线访问。因此理论上它可能是O(1),对于小数组(适合第一级缓存)就像O(1)一样,但它通常不在实践中。

一个极端实际的例子是一个不适合主存储器的阵列;现在,数组访问可能会导致从磁盘进行分页。

有时即使在这种情况下我们也不在乎。谷歌本质上是一个巨大的缓存。我们倾向于将Google搜索视为O(1)。

答案 1 :(得分:2)

橘子会变成红色吗?

是的,由于多种原因,它们可能会变红 -

  • 你把它们涂成红色。
  • 你种植了转基因品种。
  • 你在火星这个红色星球上生长它们,每个东西都应该看起来是红色的。
  • 一些实用(给定今天的技术)和不切实际的(虚构的/或未来的现实)的(理论)清单继续...

关键是,我认为你问的问题,实际上是关于两个正交概念。即 -

Big O Notation - " 在数学中,大O符号描述了当参数倾向于特定值或无穷大时函数的限制行为,通常是在更简单的函数方面。"

VS

实用性(硬件和软件),一个优秀的软件工程师应该注意,同时架构/设计他们的应用程序和编写代码。

换句话说,虽然Big O Notation的概念可以称为学术性的,但它是最合适的分类算法复杂性(时间/空间)的方式..那就是它结束了。 没有必要在正交问题上混淆水域。

要明确的是,我说人们不应该知道底层实施细节和工作情况,这会影响您编写的软件的性能..但是有没有必要将两者混合在一起。例如,说 -

是否有意义

数组没有持续时间访问(带索引),因为 -

  • 大型数组不适合CPU缓存,因此会导致高速缓存未命中成本。
  • 在内存压力较大的系统上,数组(无论大小)都已从物理内存换成硬盘,不仅会受到缓存未命中的影响,还会影响硬页错误。
  • 在极端CPU负载下的系统上,读取假定数组的线程可以被抢占,并且可能无法执行几秒钟。
  • 在一个假设的操作系统上,它不仅使用磁盘支持其内存,而且在世界另一端的另一台计算机上支持额外的内存,将使阵列访问速度难以想象地慢。

就像我的苹果和橙色的例子一样,当你阅读我越来越荒谬的例子时,希望我想说明的一点是明确的。

结论 - 任何一天,我都会回答问题" Do Arrays有持续时间O(1)访问权限(带索引)&# 34;,因为是..毫无疑问或ifs和buts,他们确实


修改

换句话说 - 如果O(1)不是答案..那么O(log n),O(n log n),O(n ^ 2)或O(n ^ 3)都不是.....当然不是42。

答案 2 :(得分:1)

他在谈论计算模型,特别是基于单词的RAM机器

RAM机器是与实际计算机非常相似的形式化:我们将计算机存储器建模为每个w位的大型存储器字,我们可以在O(1)时间内读/写任何字

但我们还有一些重要的事情要定义:一个词应该有多大?

我们需要字大小w≥Ω(log n)才能至少解决输入的n个部分。 因此,基于字的RAM通常假定字长为O(log n)

但是让机器的单词长度取决于输入的大小看起来很奇怪和不切实际

如果我们保持字长固定怎么办?然后即使在指针之后需要Ω(log n)时间来读取整个指针

我们需要Ω(log n)字来存储指针和Ω(log n)时间来访问输入元素

答案 3 :(得分:0)

如果一种语言支持稀疏数组,则访问该数组必须通过一个目录,而一个树形结构的目录将具有非线性访问时间。或者你的意思是现实条件? ; - )