Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 不会';";直到;循环会更有效率吗?_Performance_Loops_Conditional Statements - Fatal编程技术网

Performance 不会';";直到;循环会更有效率吗?

Performance 不会';";直到;循环会更有效率吗?,performance,loops,conditional-statements,Performance,Loops,Conditional Statements,我是编程新手,我注意到一种反复出现的模式是我必须在while循环中频繁使用否定,例如while(!isEmpty()) 如果有一个“直到”循环(例如,在某个条件为真之前执行某项操作),性能不是会更好吗?我确实意识到否定发生在寄存器上,速度非常快,但它看起来仍然是可以避免的 或者也许汇编语言中有某种东西使得使用当前建立的方法更可取,即使它经常需要否定?否定很可能不会以一种需要任何时间的方式显式发生 首先,朴素的“while”实现在x86上看起来是这样的 _loophead: call _isE

我是编程新手,我注意到一种反复出现的模式是我必须在
while
循环中频繁使用否定,例如
while(!isEmpty())

如果有一个“直到”循环(例如,在某个条件为真之前执行某项操作),性能不是会更好吗?我确实意识到否定发生在寄存器上,速度非常快,但它看起来仍然是可以避免的


或者也许汇编语言中有某种东西使得使用当前建立的方法更可取,即使它经常需要否定?

否定很可能不会以一种需要任何时间的方式显式发生

首先,朴素的“while”实现在x86上看起来是这样的

_loophead:
  call _isEmpty
  test eax, eax ; return value is in eax
  jnz _loopend  ; break out of loop if condition is not zero
  ... ; loop body here
  jmp _loophead
_loopend:
这里没有实际的否定,只有一个“如果不是零就跳”的
jnz
。什么不是零?影响“标志”的最后一个因素是它上面测试
isEmpty()返回值的测试

更好的“while”实现(因为每次迭代只需要1个分支)如下所示

  jmp _looptest
_loopstart:
  ... ; loop body
_looptest:
  call _isEmpty
  test eax, eax
  jz _loopstart  ; continue loop if condition is zero
否定存在时,不需要额外的时间/指令/空间。在许多其他处理器上也是如此

此外,如果可以内联
\u isEmpty
,则条件很可能不在寄存器中,而是标志状态的一部分(特殊寄存器中的一个位)。诸如“布尔值是一个0或1的整数”之类的内容是概念语义的一部分,通常在实际实现中进行优化。您通常不需要该0/1值-大多数情况下,您要做的第一件事是将其重新放入标志寄存器中,以便可以在其上进行分支


即使是非常早期的C编译器也花了特别的精力将“bool用作条件”编译成比从中生成0/1整数更高效的代码。

我认为如果您非常关心性能(正如您所说,位求反非常快),那么汇编程序编程是您唯一的方法。用高级语言编写的代码的可读性和可维护性总是以降低性能为代价的。我同意前面的文字评论,但在精神上不同意。你应该学习一些汇编编程,看看真正的编译器的输出,基准测试(正确的!)等等,让你头脑中摆脱这种毫无意义、误导的“优化”思想。你的假设和建议的解决方案中存在的问题比我在一条评论中列举的要多。@delnan-你为什么不尝试一个答案呢?因为我没有时间在接下来的几个小时内写出一个高质量的答案(而不是一个几乎不连贯的注释列表),坦白地说,因为我对这类错误观念感到厌倦和沮丧。我的意思是无意冒犯,这不是你的错或其他什么,每个人都必须从某个地方开始。如果某个值不在寄存器上,处理器如何检查该值?@user2341104正如我提到的,这些标志实际上在一个特殊的寄存器中。x86也可以在普通寄存器上进行某种分支,但仅限于ecx,而且在大多数实现中效率较低。其他一些处理器使用不同的方式处理条件,例如合并“比较/分支”指令(如MIPS)。尽管如此,在几乎所有情况下,你不必否定任何东西。