我有一个while循环看起来像:
while (str[i] != *p)
++i;
并且一位朋友突然出现并提到它会更快:
char c = *p;
while (str[i] != c)
++i;
我想问题是:
如果我多次取消引用指针,那么创建临时变量的速度会更快。
答案 0 :(得分:3)
如果*p
不是volatile
限定的,则允许编译器仅加载*p
一次并执行您的朋友提议的操作。
因此,在“普通”代码中,您应该更喜欢可读性和可维护性,并让编译器完成其工作。如果有疑问,您可以查看编译器生成的汇编程序,通常使用选项-S
。
答案 1 :(得分:2)
可能会快一点。它不会快得多。如果你真的在乎,你必须要测量它。
比微优化更重要的是清晰度和准确性。根据程序中指针p
的用法,可能非常明显的是它指向要比较的字符的含义,这意味着str[i] != *p
是一个很好的,明确的测试,并且引入新变量c
会使代码更难以遵循。或者,如果*p
与被比较的字符不是很明显,那么引入一个新变量 - 也许称之为character_being_compared_to
- 会使代码更清晰(并且也许那点快一点。)
但也有p
的价值是否会发生变化的问题,这意味着它指向的角色会变得不同。如果p
的值可以更改,则将*p
复制到c
意味着您将继续与旧值进行比较,这可能是一个错误。
您添加到程序中的每个变量都需要付出代价:它会让您(以及维护代码的每个人)花费精力去追踪。因此,变量必须承担其重量,并且必须 。 不引入新变量有一定的好处,特别是如果新变量的值必须与其他变量的值保持同步。通过添加新变量(在这种情况下,所谓的加速)获得的好处必须大于添加它的成本。
你的朋友正在做许多没有经验的程序员所做的事情:想象一下,计算机是一台虚弱,低效,喘息的机器,并且我们的工作就是让事情变得更容易。但这完全倒退了:计算机实际上非常快,并且 >。所以,一般来说,首先编写明确且有效的代码,如果它有性能问题,那么可能会担心如何加快速度,但不要担心像这样的微不足道的小问题这台可怜的旧电脑更难。
答案 2 :(得分:0)
如果编译器按原样生成代码,则不进行任何优化。
* p将生成取消引用内存位置的代码
虽然char c = * p会创建一个临时变量 a)放入堆栈并取消引用它 b)放入一个寄存器并将其用于整个循环
通常,当循环更复杂并且在生成需要不多寄存器的简单循环时发生b时会发生这种情况。
因此,根据p指向的位置,是否存在优化,循环是否足够简单以及更多因素,您可能会得到不同的结果。
但要回答你的问题,除非你很清楚编译器会产生什么,否则通常最好创建那个char。
当* p是一个像GetSize()之类的函数调用时,这将很好用,但这是另一个主题。