【发布时间】:2014-02-06 07:06:51
【问题描述】:
我假设当我们写:arr[i](相当于*(arr+i))时会发生内部转换。因为i 可以是例如short、int 或long 或这三个中任何一个的无符号变体。
所以我的问题很简单:i 应该是哪种类型才能不发生内部转换?这样代码才能最高效地运行?
粗略猜测:size_t?
【问题讨论】:
-
如果您为
int8_t直到并包括ptrdiff_t(我的提名人)设置测试用例,我会更感兴趣,以查看发布级 asm 的实际外观以及差异是(或不是)。 -
FWIW,我可以确认使用“错误”的索引大小确实会导致数组访问的符号/零扩展指令。但与此同时,编译器非常擅长通过common subexpression elimination 优化它们。
-
@StackedCrooked 不是真的。在我的机器上,
int是 32 位。但我可以做 64 位索引。 -
@makhlaghi 因此编译器将首先对其进行编译以对每个数组访问进行扩展。但随后它会看到对同一个变量的扩展一次又一次地完成。所以它会做一次并重用扩展的结果。 (又名通用子表达式消除)
-
访问数组最快的方法是根本不使用下标运算符。比如
for (int i = 0; i < n; i++) f(array[i])最好写成for (array_type* p = array; p < array+n; p++) f(*p)这样,你只需要加一个地址和一个整数一次。还有一点:说到性能,不要争论,要衡量!如果您执行 user2485710 建议的操作,则可以使用例如对代码进行一次基准测试。size_t和ptrdiff_t一次,看看它是否有什么不同。只有这样,您才需要考虑使用哪个。
标签: c performance pointers pointer-arithmetic