最近,我一直在思考可以遍历数组的所有方法,并想知道其中哪种方法效率最高(和最低)。我写了一个假设问题和五个可能的解决方案。
问题
给定一个包含多个元素的int
数组,为每个元素分配任意数字的最有效方法是什么?arr
len
42
解决方案 0:显而易见
for (unsigned i = 0; i < len; ++i)
arr[i] = 42;
解决方案 1:相反的明显
for (unsigned i = len - 1; i >= 0; --i)
arr[i] = 42;
解决方案 2:地址和迭代器
for (unsigned i = 0; i < len; ++i)
{ *arr = 42;
++arr;
}
解决方案3:反向地址和迭代器
for (unsigned i = len; i; --i)
{ *arr = 42;
++arr;
}
解决方案 4:解决疯狂问题
int* end = arr + len;
for (; arr < end; ++arr)
*arr = 42;
推测
显而易见的解决方案几乎总是被使用,但我想知道下标运算符是否会导致乘法指令,就好像它被写成*(arr + i * sizeof(int)) = 42
.
反向解决方案试图利用如何比较而i
不是0
可能len
减轻减法运算。因此,我更喜欢解决方案 3而不是解决方案 2。另外,我读到数组被优化为可以向前访问,因为它们是如何存储在缓存中的,这可能会给解决方案 1带来问题。
我不明白为什么解决方案 4会比解决方案 2效率低。解决方案 2增加了地址和迭代器,而解决方案 4只增加了地址。
最后,我不确定我更喜欢这些解决方案中的哪一个。我认为答案也因编译器的目标架构和优化设置而异。
如果有的话,你更喜欢哪一个?