【问题标题】:Why looping over array using array indexing is slower than that of pointer access?为什么使用数组索引循环数组比指针访问慢?
【发布时间】:2014-10-07 16:40:16
【问题描述】:

我正在阅读 Kochan 的书“C 语言编程”。在第 10 页的指针和数组部分中。 264 他说:

一般来说,索引数组的过程比执行索引需要更多的时间 访问指针内容的过程。其实这是主要原因之一 为什么使用指针来访问数组的元素——生成的代码是 一般效率更高。当然,如果对数组的访问一般不是顺序的, 就这个问题而言,指针什么也没做,因为表达式 *(pointer + j) 与表达式 array[j] 的执行时间一样长。

有人可以解释什么比什么更快吗?具体来说,如果array[j]的速度= *(pointer + j)的速度那么索引数组的过程访问指针内容的过程 /em> ?另外,关于 SO 的问题和答案提到 array[j] 在编译过程中被转换为 *(array+j) 所以应该没有任何区别。

总结: 请给我一个非常简单的例子来说明 Kochan 所说的话。 2段代码,指向更快的一段,不用解释为什么是真的。

【问题讨论】:

  • 那本书是哪一年的?
  • 我认为 Kochan 所说的是,将指针增加元素大小比将索引乘以元素大小并将其添加到基地址要快。这是差异足够小以至于可能无关紧要的情况之一,如果您的工作水平确实很重要,那么您可能已经很清楚这种差异。
  • 这是第 3 版,我想是 2005 年
  • Afaik,这曾经是正确的,并且仍然经常在没有优化的情况下进行编译(如果您将 C 视为“可移植的汇编语言”,那么通过递增指针来遍历数组在抽象机器)。今天,总的来说,它不是。对于更复杂的循环,这甚至可以加强编译器的别名分析并导致代码效率降低。 (这是我在上次实验中记得的,我需要大量的restricts 用于非平凡的循环,以使指针增量版本与数组索引版本同样快,并且没有让它们更快。 )

标签: c arrays pointers


【解决方案1】:

看sn-p

int arr[5] = {0};
int *p = arr;
int c = 1;

现在,看循环 1:

for(int i = 0; i < 5; i++)
     arr[i] = c++ + 1;

循环 2:

for(int i = 0; i < 5; i++)
     *p++ = c++ + 1; 

这两个循环之间的区别在于它们的主体。第一个循环包含arr[i] = c++ + 1。这相当于*(arr + i) = c++ + 1*(arr + i) 是什么意思?
这意味着:

  • 获取基指针地址。
  • 获取i的值
  • i 的值添加到基地址。
  • 取消引用最终地址。

而对于第二个循环的主体*p++ 表示:

  • 获取p的值
  • 在增加地址之前取消引用地址。
  • 将地址增加1

当然第二个会执行得更快。但是,现在现代编译器已经足够聪明,可以优化这些代码,而且很可能你会在两个循环中得到相同的结果。

【讨论】:

  • 我猜你的意思是int *p = arr;
  • @MaciejSzpakowski;哎呀!那是错字。
  • 另一个哎呀,值'i'必须乘以数组类型的大小。 (即 char 数组什么也不做,但 int 数组乘以 4 等)
  • @user3629249 好吧,是的,但让我们明确一点:不在任何代码本身中 - 仅在随后的概念解释中,因为无论黑客谈论添加到地址,它实际上是添加到指针,如果我们假设大多数人将“地址”读取为具有 1-char 分辨率的数量,这将是非常不同的:typedPointer + n 等同于castToCharPointer + sizeof(*typedPointer)。这将受益于更清晰的 IMO。
猜你喜欢
  • 2011-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-08
  • 2019-09-02
  • 1970-01-01
  • 2016-09-09
  • 1970-01-01
相关资源
最近更新 更多