访问运算符示例:
void print_elements ( int * arr, int n )
{
for (int k = 0; k < n; ++k) printf("%d\n", arr[k]);
}
指针算术示例:
void print_elements ( int * arr, int n )
{
for (int * pa(arr), * pb(arr+n); pa != pb; ++pa) printf("%d\n", *pa);
}
第二个涉及循环的2个变量pa
和pb
,而第一个只涉及1个额外变量k
。然后,在第二个你正在做
increment pa by 1, dereference
而在你正在做的第一个
increment k by 1, add k to the pointer arr, derefence
以便第一个使用较少的操作来迭代循环。
所有事情都考虑了,哪个更快?对于整数类型,比较器<
的速度是否比!=
快?使用<
似乎更安全&#34;因为像pa != pb
这样的条件会因为pa
如果重建循环内的算法而pb
跳过1
,所以总是会感到非理性的恐惧。将指针递增1
通常比递增大于{{1}}的指针要快吗?我想考虑 一切 。
答案 0 :(得分:3)
这将属于&#34;过早优化&#34;的范围。除非你有一个特定的(测量的)原因,否则你通常应该首先选择最简单和最直接的代码(在这种情况下你的第一个函数)。有可能现在任何编译器都会优化两个函数,如果不完全相同的话,大致相同。
如果您怀疑可以进行一些优化,那么您应该通过基准测试/分析来衡量事物第一,尽管即使在这样的简单函数中,您也必须小心,因为您很容易得到错误的结果。 / p>
如果我们用以下内容替换您的功能:
volatile int Output = 0;
void print_elements1(int * arr, int n)
{
for (int k = 0; k < n; ++k) Output += arr[k];
}
void print_elements2(int * arr, int n)
{
for (int * pa(arr), *pb(arr + n); pa != pb; ++pa) Output += *pa;
}
原因是printf()
是&#34;慢&#34;如果我们对原始功能进行基准测试,我们真的只会测试它的速度。测试这些函数的数组大小为1亿,以获得合适/可重复的时序:
啊,我们看到指针访问速度是数组索引的两倍多......但速度不快!让我们反转测试订单,看看我们得到了什么:
相同的时间,至少在我的基准计时器的误差范围内。
故事的寓意是,如今编译器和计算机都是复杂的机器,很可能你的编译器在优化大多数代码方面做得比你好。当您进行优化时,首先通过分析/基准测量来测量事物,以确定要处理的代码的最有效区域(如果有的话)。
答案 1 :(得分:3)
何时使用指针进行数组与使用访问运算符有什么好的一般规则?
始终尽可能使用数组索引语法,因为它更具可读性。指针算术语法难以阅读,通常不应用于迭代。
第二个涉及2个变量
源代码中使用的变量数量是性能和内存消耗的非常差的度量。无论是否明确声明变量,实际的机器代码都需要在某处存储结果。如果您声明的变量多于机器代码实际需要的变量,编译器很可能会优化它们。
循环需要知道何时结束迭代。它可以通过在循环中的每一圈运行时计算arr+n
(不太可能发生,因为它会很慢),或者可以通过将arr+n
保存在临时内存位置来实现,然后再启动环。在第一个示例中,您声明没有这样的变量,因此实际的机器代码中可能会有一个未命名的变量用于此目的。使两个例子都相同。
这样第一个使用较少的操作来遍历循环
不是,不。 C标准强制arr[i]
100%等同于*(arr + i)
。数组语法只是&#34;语法糖&#34;。两种情况极有可能产生相同的机器代码。
(上述等价规则是C允许some weird, ugly crap)
的原因所有事情都考虑了,哪个更快?
出于上述原因,它们同样快速。
比较器&lt;快于!=对于整数类型?
一般来说应该没有区别。这一切都归结为给定CPU上可用的汇编指令。所有比较方式都很可能同样快,除了与0比较的那些,它们可以在某些CPU上节省几纳秒。
我想考虑一切可能。
然后我强烈建议您考虑程序的可读性和维护,而不是手动微优化。前者是今天成为优秀程序员的原因,而不是后者。我们不再是20世纪80年代了。
答案 2 :(得分:1)
正如其他人所指出的那样,性能问题不会导致我们访问数组元素中的一种或另一种符号。
如果有多种方法可以表达同样的事情,请使用更好理解的方式。
再次尝到味道。
我更喜欢索引运算符[]
并执行[1],因为我不需要获取数组元素的地址。在后一种情况下,我使用+
- 运算符,即a + 1
而不是&a[1]
。