Which value is better to use? Boolean true or Integer 1?
使用哪个值更好?布尔真还是整数1?
The above topic made me do some experiments with bool
and int
in if
condition. So just out of curiosity I wrote this program:
以上题目让我在if条件下对bool和int做了一些实验。出于好奇,我写了这个节目:
int f(int i)
{
if ( i ) return 99; //if(int)
else return -99;
}
int g(bool b)
{
if ( b ) return 99; //if(bool)
else return -99;
}
int main(){}
g++ intbool.cpp -S
generates asm code for each functions as follows:
g++ intbool。cpp -S为每个功能产生的asm代码如下:
-
asm code for
f(int)
asm代码f(int)
__Z1fi: LFB0: pushl %ebp LCFI0: movl %esp, %ebp LCFI1: cmpl $0, 8(%ebp) je L2 movl $99, %eax jmp L3 L2: movl $-99, %eax L3: leave LCFI2: ret
-
asm code for
g(bool)
asm代码g(保龄球)
__Z1gb: LFB1: pushl %ebp LCFI3: movl %esp, %ebp LCFI4: subl $4, %esp LCFI5: movl 8(%ebp), %eax movb %al, -4(%ebp) cmpb $0, -4(%ebp) je L5 movl $99, %eax jmp L6 L5: movl $-99, %eax L6: leave LCFI6: ret
Surprisingly, g(bool)
generates more asm
instructions! Does it mean that if(bool)
is little slower than if(int)
? I used to think bool
is especially designed to be used in conditional statement such as if
, so I was expecting g(bool)
to generate less asm instructions, thereby making g(bool)
more efficient and fast.
令人惊讶的是,g(bool)生成了更多的asm指令!这是否意味着if(bool)比if(int)慢一点?我曾经认为bool是专门设计用于条件语句的,比如if,所以我希望g(bool)生成更少的asm指令,从而使g(bool)更高效、更快速。
EDIT:
编辑:
I'm not using any optimization flag as of now. But even absence of it, why does it generate more asm for g(bool)
is a question for which I'm looking for a reasonable answer. I should also tell you that -O2
optimization flag generates exactly same asm. But that isn't the question. The question is what I've asked.
目前我还没有使用任何优化标志。但即使没有它,为什么它会为g(bool)产生更多的asm,我正在寻找一个合理的答案。我还应该告诉你-O2优化标志产生的asm完全相同。但这不是问题所在。问题是我问的是什么。
8 个解决方案
#1
94
Makes sense to me. Your compiler apparently defines a bool
as an 8-bit value, and your system ABI requires it to "promote" small (< 32-bit) integer arguments to 32-bit when pushing them onto the call stack. So to compare a bool
, the compiler generates code to isolate the least significant byte of the 32-bit argument that g receives, and compares it with cmpb
. In the first example, the int
argument uses the full 32 bits that were pushed onto the stack, so it simply compares against the whole thing with cmpl
.
对我来说是有意义的。显然,编译器将bool定义为8位值,而系统ABI要求它在将小(< 32位)整数参数推入调用堆栈时将其“提升”为32位。因此,为了比较bool,编译器生成代码来隔离g接收的32位参数中最不重要的字节,并将其与cmpb进行比较。在第一个示例中,int参数使用被推到堆栈上的全部32位,因此它只与cmpl进行比较。
#2
76
Compiling with -03
gives the following for me:
使用-03编译时,我得到以下信息:
f:
f:
pushl %ebp
movl %esp, %ebp
cmpl $1, 8(%ebp)
popl %ebp
sbbl %eax, %eax
andb $58, %al
addl $99, %eax
ret
g:
旅客:
pushl %ebp
movl %esp, %ebp
cmpb $1, 8(%ebp)
popl %ebp
sbbl %eax, %eax
andb $58, %al
addl $99, %eax
ret
.. so it compiles to essentially the same code, except for cmpl
vs cmpb
. This means that the difference, if there is any, doesn't matter. Judging by unoptimized code is not fair.
. .除了cmpl和cmpb,它的编译代码基本上是一样的。这意味着,如果存在差异,那么差异并不重要。通过未优化的代码进行判断是不公平的。
Edit to clarify my point. Unoptimized code is for simple debugging, not for speed. Comparing the speed of unoptimized code is senseless.
编辑以澄清我的观点。未优化的代码是为了简单的调试,而不是为了速度。比较未优化代码的速度是没有意义的。
#3
26
When I compile this with a sane set of options (specifically -O3), here's what I get:
当我用一组合理的选项(特别是-O3)来编译它时,我得到的是:
For f()
:
f():
.type _Z1fi, @function
_Z1fi:
.LFB0:
.cfi_startproc
.cfi_personality 0x3,__gxx_personality_v0
cmpl $1, %edi
sbbl %eax, %eax
andb $58, %al
addl $99, %eax
ret
.cfi_endproc
For g()
:
对g():
.type _Z1gb, @function
_Z1gb:
.LFB1:
.cfi_startproc
.cfi_personality 0x3,__gxx_personality_v0
cmpb $1, %dil
sbbl %eax, %eax
andb $58, %al
addl $99, %eax
ret
.cfi_endproc
They still use different instructions for the comparison (cmpb
for boolean vs. cmpl
for int), but otherwise the bodies are identical. A quick look at the Intel manuals tells me: ... not much of anything. There's no such thing as cmpb
or cmpl
in the Intel manuals. They're all cmp
and I can't find the timing tables at the moment. I'm guessing, however, that there's no clock difference between comparing a byte immediate vs. comparing a long immediate, so for all practical purposes the code is identical.
它们在比较时仍然使用不同的指令(布尔值为cmpb, int值为cmpl),但在其他情况下,主体是相同的。快速浏览一下英特尔的手册就会知道:……什么也不行。在英特尔手册中没有cmpb或cmpl。他们都是cmp,我现在找不到时间表。但是,我猜想,在比较一个字节和比较一个字节之间没有时钟上的差别,所以对于所有实际的目的来说,代码是相同的。
edited to add the following based on your addition
根据您的添加进行编辑,以添加以下内容
The reason the code is different in the unoptimized case is that it is unoptimized. (Yes, it's circular, I know.) When the compiler walks the AST and generates code directly, it doesn't "know" anything except what's at the immediate point of the AST it's in. At that point it lacks all contextual information needed to know that at this specific point it can treat the declared type bool
as an int
. A boolean is obviously by default treated as a byte and when manipulating bytes in the Intel world you have to do things like sign-extend to bring it to certain widths to put it on the stack, etc. (You can't push a byte.)
在未优化的情况下,代码不同的原因是它没有优化。(是的,我知道是圆形的。)当编译器遍历AST并直接生成代码时,它不“知道”任何东西,除了它所在的AST的最近点。在这一点上它缺乏所有上下文信息需要知道,在这个特定的时刻它可以治疗宣布bool类型为int。布尔显然是默认视为一个字节时,操纵字节在英特尔世界你要做的事情像sign-extend带来一定的宽度在堆栈上,等。(你不能把一个字节)。
When the optimizer views the AST and does its magic, however, it looks at surrounding context and "knows" when it can replace code with something more efficient without changing semantics. So it "knows" it can use an integer in the parameter and thereby lose the unnecessary conversions and widening.
但是,当优化器查看AST并执行它的魔法时,它会查看周围的上下文并“知道”何时可以用更有效的东西替换代码,而不需要更改语义。因此它“知道”它可以在参数中使用一个整数,从而丢失不必要的转换和扩展。
#4
13
With GCC 4.5 on Linux and Windows at least, sizeof(bool) == 1
. On x86 and x86_64, you can't pass in less than an general purpose register's worth to a function (whether via the stack or a register depending on the calling convention etc...).
至少在Linux和Windows上使用GCC 4.5, sizeof(bool) = 1。在x86和x86_64上,不能将值小于通用寄存器值的值传递给函数(根据调用约定,可以通过堆栈或寄存器)。
So the code for bool, when un-optimized, actually goes to some length to extract that bool value from the argument stack (using another stack slot to save that byte). It's more complicated than just pulling a native register-sized variable.
因此,bool的代码在未优化时,实际上会从参数堆栈中提取bool值(使用另一个堆栈插槽来保存这个字节)。这比只拉一个本地注册大小的变量要复杂得多。
#5
9
At the machine level there is no such thing as bool
Very few instruction set architectures define any sort of boolean operand type, although there are often instructions that trigger an action on non-zero values. To the CPU, usually, everything is one of the scalar types or a string of them.
很少有指令集体系结构定义任何类型的布尔操作类型,尽管通常会有指令触发对非零值的操作。对于CPU,通常情况下,所有东西都是标量类型或字符串。
A given compiler and a given ABI will need to choose specific sizes for int
and bool
and when, like in your case, these are different sizes they may generate slightly different code, and at some levels of optimization one may be slightly faster.
一个给定的编译器和一个给定的ABI将需要为int和bool选择特定的大小,当,像在您的情况中,这些是不同的大小,它们可能产生稍微不同的代码,在某些级别的优化可能会稍微快一些。
Why is bool one byte on many systems?
It's safer to choose a char
type for bool because someone might make a really large array of them.
为bool选择char类型更安全,因为某人可能会生成一个非常大的字符数组。
Update: by "safer", I mean: for the compiler and library implementors. I'm not saying people need to reimplement the system type.
更新:“更安全”的意思是:对于编译器和库实现者。我不是说人们需要重新实现系统类型。
#6
7
Yeah, the discussion's fun. But just test it:
是的,很有趣的讨论。只是测试它:
Test code:
测试代码:
#include <stdio.h>
#include <string.h>
int testi(int);
int testb(bool);
int main (int argc, char* argv[]){
bool valb;
int vali;
int loops;
if( argc < 2 ){
return 2;
}
valb = (0 != (strcmp(argv[1], "0")));
vali = strcmp(argv[1], "0");
printf("Arg1: %s\n", argv[1]);
printf("BArg1: %i\n", valb ? 1 : 0);
printf("IArg1: %i\n", vali);
for(loops=30000000; loops>0; loops--){
//printf("%i: %i\n", loops, testb(valb=!valb));
printf("%i: %i\n", loops, testi(vali=!vali));
}
return valb;
}
int testi(int val){
if( val ){
return 1;
}
return 0;
}
int testb(bool val){
if( val ){
return 1;
}
return 0;
}
Compiled on a 64-bit Ubuntu 10.10 laptop with: g++ -O3 -o /tmp/test_i /tmp/test_i.cpp
编译在一个64位的Ubuntu 10.10笔记本上:g++ -O3 -o /tmp/test_i /tmp/test_i.cpp
Integer-based comparison:
基于整数比较:
sauer@trogdor:/tmp$ time /tmp/test_i 1 > /dev/null
real 0m8.203s
user 0m8.170s
sys 0m0.010s
sauer@trogdor:/tmp$ time /tmp/test_i 1 > /dev/null
real 0m8.056s
user 0m8.020s
sys 0m0.000s
sauer@trogdor:/tmp$ time /tmp/test_i 1 > /dev/null
real 0m8.116s
user 0m8.100s
sys 0m0.000s
Boolean test / print uncommented (and integer commented):
布尔测试/打印未注释(和整数注释):
sauer@trogdor:/tmp$ time /tmp/test_i 1 > /dev/null
real 0m8.254s
user 0m8.240s
sys 0m0.000s
sauer@trogdor:/tmp$ time /tmp/test_i 1 > /dev/null
real 0m8.028s
user 0m8.000s
sys 0m0.010s
sauer@trogdor:/tmp$ time /tmp/test_i 1 > /dev/null
real 0m7.981s
user 0m7.900s
sys 0m0.050s
They're the same with 1 assignment and 2 comparisons each loop over 30 million loops. Find something else to optimize. For example, don't use strcmp unnecessarily. ;)
它们与一个赋值和两个比较是一样的每个循环超过3000万个。找一些其他的东西来优化。例如,不要不必要地使用strcmp。,)
#7
2
It will mostly depend on the compiler and the optimization. There's an interesting discussion (language agnostic) here:
它主要取决于编译器和优化。这里有一个有趣的讨论(语言不可知论者):
Does "if ([bool] == true)" require one more step than "if ([bool])"?
“if ([bool] = true)”需要比“if ([bool])”多一步吗?
Also, take a look at this post: http://www.linuxquestions.org/questions/programming-9/c-compiler-handling-of-boolean-variables-290996/
另外,看看这篇文章:http://www.linuxquestions.org/questions/programing-9/c -compiler-handling-of boolean- variabls -290996/
#8
0
Approaching your question in two different ways:
用两种不同的方式来回答你的问题:
If you are specifically talking about C++ or any programming language that will produce assembly code for that matter, we are bound to what code the compiler will generate in ASM. We are also bound to the representation of true and false in c++. An integer will have to be stored in 32 bits, and I could simply use a byte to store the boolean expression. Asm snippets for conditional statements:
如果您正在特别讨论c++或任何将为此生成汇编代码的编程语言,那么我们将绑定到编译器在ASM中生成的代码。在c++中,我们还绑定了真与假的表示。一个整数必须存储在32位中,我可以简单地使用一个字节来存储布尔表达式。条件语句的Asm代码片段:
For the integer:
整数:
mov eax,dword ptr[esp] ;Store integer
cmp eax,0 ;Compare to 0
je false ;If int is 0, its false
;Do what has to be done when true
false:
;Do what has to be done when false
For the bool:
bool:
mov al,1 ;Anything that is not 0 is true
test al,1 ;See if first bit is fliped
jz false ;Not fliped, so it's false
;Do what has to be done when true
false:
;Do what has to be done when false
So, that's why the speed comparison is so compile dependent. In the case above, the bool would be slightly fast since cmp
would imply a subtraction for setting the flags. It also contradicts with what your compiler generated.
这就是为什么速度比较如此依赖于编译。在上面的例子中,bool会稍微快一点,因为cmp意味着设置标志需要减法。它还与编译器生成的内容相矛盾。
Another approach, a much simpler one, is to look at the logic of the expression on it's own and try not to worry about how the compiler will translate your code, and I think this is a much healthier way of thinking. I still believe, ultimately, that the code being generated by the compiler is actually trying to give a truthful resolution. What I mean is that, maybe if you increase the test cases in the if statement and stick with boolean in one side and integer in another, the compiler will make it so the code generated will execute faster with boolean expressions in the machine level.
另一个更简单的方法是,查看它自己的表达式的逻辑,不要担心编译器会如何翻译你的代码,我认为这是一种更健康的思维方式。我仍然相信,最终编译器生成的代码实际上是在试图给出一个真实的解决方案。我的意思是,如果在if语句中增加测试用例,在一边使用布尔值,在另一边使用整数,编译器会使生成的代码在机器级别上使用布尔值表达式执行得更快。
I'm considering this is a conceptual question, so I'll give a conceptual answer. This discussion reminds me of discussions I commonly have about whether or not code efficiency translates to less lines of code in assembly. It seems that this concept is generally accepted as being true. Considering that keeping track of how fast the ALU will handle each statement is not viable, the second option would be to focus on jumps and compares in assembly. When that is the case, the distinction between boolean statements or integers in the code you presented becomes rather representative. The result of an expression in C++ will return a value that will then be given a representation. In assembly, on the other hand, the jumps and comparisons will be based in numeric values regardless of what type of expression was being evaluated back at you C++ if statement. It is important on these questions to remember that purely logicical statements such as these end up with a huge computational overhead, even though a single bit would be capable of the same thing.
我认为这是一个概念性的问题,所以我会给出一个概念性的答案。这个讨论让我想起了我通常所讨论的关于代码效率是否可以转换成更少的程序代码的讨论。这个概念似乎被普遍认为是正确的。考虑到跟踪ALU处理每个语句的速度是不可行的,第二个选项将是关注跳转并在程序集中进行比较。在这种情况下,您所展示的代码中的布尔语句或整数之间的区别就具有代表性了。c++中的表达式的结果将返回一个值,然后该值将得到一个表示。另一方面,在汇编语言中,跳转和比较将基于数值,而不管您c++ if语句的表达式是什么类型。在这些问题上,重要的是要记住,像这样纯粹的逻辑语句最终会产生巨大的计算开销,即使一个比特也能做同样的事情。
#1
94
Makes sense to me. Your compiler apparently defines a bool
as an 8-bit value, and your system ABI requires it to "promote" small (< 32-bit) integer arguments to 32-bit when pushing them onto the call stack. So to compare a bool
, the compiler generates code to isolate the least significant byte of the 32-bit argument that g receives, and compares it with cmpb
. In the first example, the int
argument uses the full 32 bits that were pushed onto the stack, so it simply compares against the whole thing with cmpl
.
对我来说是有意义的。显然,编译器将bool定义为8位值,而系统ABI要求它在将小(< 32位)整数参数推入调用堆栈时将其“提升”为32位。因此,为了比较bool,编译器生成代码来隔离g接收的32位参数中最不重要的字节,并将其与cmpb进行比较。在第一个示例中,int参数使用被推到堆栈上的全部32位,因此它只与cmpl进行比较。
#2
76
Compiling with -03
gives the following for me:
使用-03编译时,我得到以下信息:
f:
f:
pushl %ebp
movl %esp, %ebp
cmpl $1, 8(%ebp)
popl %ebp
sbbl %eax, %eax
andb $58, %al
addl $99, %eax
ret
g:
旅客:
pushl %ebp
movl %esp, %ebp
cmpb $1, 8(%ebp)
popl %ebp
sbbl %eax, %eax
andb $58, %al
addl $99, %eax
ret
.. so it compiles to essentially the same code, except for cmpl
vs cmpb
. This means that the difference, if there is any, doesn't matter. Judging by unoptimized code is not fair.
. .除了cmpl和cmpb,它的编译代码基本上是一样的。这意味着,如果存在差异,那么差异并不重要。通过未优化的代码进行判断是不公平的。
Edit to clarify my point. Unoptimized code is for simple debugging, not for speed. Comparing the speed of unoptimized code is senseless.
编辑以澄清我的观点。未优化的代码是为了简单的调试,而不是为了速度。比较未优化代码的速度是没有意义的。
#3
26
When I compile this with a sane set of options (specifically -O3), here's what I get:
当我用一组合理的选项(特别是-O3)来编译它时,我得到的是:
For f()
:
f():
.type _Z1fi, @function
_Z1fi:
.LFB0:
.cfi_startproc
.cfi_personality 0x3,__gxx_personality_v0
cmpl $1, %edi
sbbl %eax, %eax
andb $58, %al
addl $99, %eax
ret
.cfi_endproc
For g()
:
对g():
.type _Z1gb, @function
_Z1gb:
.LFB1:
.cfi_startproc
.cfi_personality 0x3,__gxx_personality_v0
cmpb $1, %dil
sbbl %eax, %eax
andb $58, %al
addl $99, %eax
ret
.cfi_endproc
They still use different instructions for the comparison (cmpb
for boolean vs. cmpl
for int), but otherwise the bodies are identical. A quick look at the Intel manuals tells me: ... not much of anything. There's no such thing as cmpb
or cmpl
in the Intel manuals. They're all cmp
and I can't find the timing tables at the moment. I'm guessing, however, that there's no clock difference between comparing a byte immediate vs. comparing a long immediate, so for all practical purposes the code is identical.
它们在比较时仍然使用不同的指令(布尔值为cmpb, int值为cmpl),但在其他情况下,主体是相同的。快速浏览一下英特尔的手册就会知道:……什么也不行。在英特尔手册中没有cmpb或cmpl。他们都是cmp,我现在找不到时间表。但是,我猜想,在比较一个字节和比较一个字节之间没有时钟上的差别,所以对于所有实际的目的来说,代码是相同的。
edited to add the following based on your addition
根据您的添加进行编辑,以添加以下内容
The reason the code is different in the unoptimized case is that it is unoptimized. (Yes, it's circular, I know.) When the compiler walks the AST and generates code directly, it doesn't "know" anything except what's at the immediate point of the AST it's in. At that point it lacks all contextual information needed to know that at this specific point it can treat the declared type bool
as an int
. A boolean is obviously by default treated as a byte and when manipulating bytes in the Intel world you have to do things like sign-extend to bring it to certain widths to put it on the stack, etc. (You can't push a byte.)
在未优化的情况下,代码不同的原因是它没有优化。(是的,我知道是圆形的。)当编译器遍历AST并直接生成代码时,它不“知道”任何东西,除了它所在的AST的最近点。在这一点上它缺乏所有上下文信息需要知道,在这个特定的时刻它可以治疗宣布bool类型为int。布尔显然是默认视为一个字节时,操纵字节在英特尔世界你要做的事情像sign-extend带来一定的宽度在堆栈上,等。(你不能把一个字节)。
When the optimizer views the AST and does its magic, however, it looks at surrounding context and "knows" when it can replace code with something more efficient without changing semantics. So it "knows" it can use an integer in the parameter and thereby lose the unnecessary conversions and widening.
但是,当优化器查看AST并执行它的魔法时,它会查看周围的上下文并“知道”何时可以用更有效的东西替换代码,而不需要更改语义。因此它“知道”它可以在参数中使用一个整数,从而丢失不必要的转换和扩展。
#4
13
With GCC 4.5 on Linux and Windows at least, sizeof(bool) == 1
. On x86 and x86_64, you can't pass in less than an general purpose register's worth to a function (whether via the stack or a register depending on the calling convention etc...).
至少在Linux和Windows上使用GCC 4.5, sizeof(bool) = 1。在x86和x86_64上,不能将值小于通用寄存器值的值传递给函数(根据调用约定,可以通过堆栈或寄存器)。
So the code for bool, when un-optimized, actually goes to some length to extract that bool value from the argument stack (using another stack slot to save that byte). It's more complicated than just pulling a native register-sized variable.
因此,bool的代码在未优化时,实际上会从参数堆栈中提取bool值(使用另一个堆栈插槽来保存这个字节)。这比只拉一个本地注册大小的变量要复杂得多。
#5
9
At the machine level there is no such thing as bool
Very few instruction set architectures define any sort of boolean operand type, although there are often instructions that trigger an action on non-zero values. To the CPU, usually, everything is one of the scalar types or a string of them.
很少有指令集体系结构定义任何类型的布尔操作类型,尽管通常会有指令触发对非零值的操作。对于CPU,通常情况下,所有东西都是标量类型或字符串。
A given compiler and a given ABI will need to choose specific sizes for int
and bool
and when, like in your case, these are different sizes they may generate slightly different code, and at some levels of optimization one may be slightly faster.
一个给定的编译器和一个给定的ABI将需要为int和bool选择特定的大小,当,像在您的情况中,这些是不同的大小,它们可能产生稍微不同的代码,在某些级别的优化可能会稍微快一些。
Why is bool one byte on many systems?
It's safer to choose a char
type for bool because someone might make a really large array of them.
为bool选择char类型更安全,因为某人可能会生成一个非常大的字符数组。
Update: by "safer", I mean: for the compiler and library implementors. I'm not saying people need to reimplement the system type.
更新:“更安全”的意思是:对于编译器和库实现者。我不是说人们需要重新实现系统类型。
#6
7
Yeah, the discussion's fun. But just test it:
是的,很有趣的讨论。只是测试它:
Test code:
测试代码:
#include <stdio.h>
#include <string.h>
int testi(int);
int testb(bool);
int main (int argc, char* argv[]){
bool valb;
int vali;
int loops;
if( argc < 2 ){
return 2;
}
valb = (0 != (strcmp(argv[1], "0")));
vali = strcmp(argv[1], "0");
printf("Arg1: %s\n", argv[1]);
printf("BArg1: %i\n", valb ? 1 : 0);
printf("IArg1: %i\n", vali);
for(loops=30000000; loops>0; loops--){
//printf("%i: %i\n", loops, testb(valb=!valb));
printf("%i: %i\n", loops, testi(vali=!vali));
}
return valb;
}
int testi(int val){
if( val ){
return 1;
}
return 0;
}
int testb(bool val){
if( val ){
return 1;
}
return 0;
}
Compiled on a 64-bit Ubuntu 10.10 laptop with: g++ -O3 -o /tmp/test_i /tmp/test_i.cpp
编译在一个64位的Ubuntu 10.10笔记本上:g++ -O3 -o /tmp/test_i /tmp/test_i.cpp
Integer-based comparison:
基于整数比较:
sauer@trogdor:/tmp$ time /tmp/test_i 1 > /dev/null
real 0m8.203s
user 0m8.170s
sys 0m0.010s
sauer@trogdor:/tmp$ time /tmp/test_i 1 > /dev/null
real 0m8.056s
user 0m8.020s
sys 0m0.000s
sauer@trogdor:/tmp$ time /tmp/test_i 1 > /dev/null
real 0m8.116s
user 0m8.100s
sys 0m0.000s
Boolean test / print uncommented (and integer commented):
布尔测试/打印未注释(和整数注释):
sauer@trogdor:/tmp$ time /tmp/test_i 1 > /dev/null
real 0m8.254s
user 0m8.240s
sys 0m0.000s
sauer@trogdor:/tmp$ time /tmp/test_i 1 > /dev/null
real 0m8.028s
user 0m8.000s
sys 0m0.010s
sauer@trogdor:/tmp$ time /tmp/test_i 1 > /dev/null
real 0m7.981s
user 0m7.900s
sys 0m0.050s
They're the same with 1 assignment and 2 comparisons each loop over 30 million loops. Find something else to optimize. For example, don't use strcmp unnecessarily. ;)
它们与一个赋值和两个比较是一样的每个循环超过3000万个。找一些其他的东西来优化。例如,不要不必要地使用strcmp。,)
#7
2
It will mostly depend on the compiler and the optimization. There's an interesting discussion (language agnostic) here:
它主要取决于编译器和优化。这里有一个有趣的讨论(语言不可知论者):
Does "if ([bool] == true)" require one more step than "if ([bool])"?
“if ([bool] = true)”需要比“if ([bool])”多一步吗?
Also, take a look at this post: http://www.linuxquestions.org/questions/programming-9/c-compiler-handling-of-boolean-variables-290996/
另外,看看这篇文章:http://www.linuxquestions.org/questions/programing-9/c -compiler-handling-of boolean- variabls -290996/
#8
0
Approaching your question in two different ways:
用两种不同的方式来回答你的问题:
If you are specifically talking about C++ or any programming language that will produce assembly code for that matter, we are bound to what code the compiler will generate in ASM. We are also bound to the representation of true and false in c++. An integer will have to be stored in 32 bits, and I could simply use a byte to store the boolean expression. Asm snippets for conditional statements:
如果您正在特别讨论c++或任何将为此生成汇编代码的编程语言,那么我们将绑定到编译器在ASM中生成的代码。在c++中,我们还绑定了真与假的表示。一个整数必须存储在32位中,我可以简单地使用一个字节来存储布尔表达式。条件语句的Asm代码片段:
For the integer:
整数:
mov eax,dword ptr[esp] ;Store integer
cmp eax,0 ;Compare to 0
je false ;If int is 0, its false
;Do what has to be done when true
false:
;Do what has to be done when false
For the bool:
bool:
mov al,1 ;Anything that is not 0 is true
test al,1 ;See if first bit is fliped
jz false ;Not fliped, so it's false
;Do what has to be done when true
false:
;Do what has to be done when false
So, that's why the speed comparison is so compile dependent. In the case above, the bool would be slightly fast since cmp
would imply a subtraction for setting the flags. It also contradicts with what your compiler generated.
这就是为什么速度比较如此依赖于编译。在上面的例子中,bool会稍微快一点,因为cmp意味着设置标志需要减法。它还与编译器生成的内容相矛盾。
Another approach, a much simpler one, is to look at the logic of the expression on it's own and try not to worry about how the compiler will translate your code, and I think this is a much healthier way of thinking. I still believe, ultimately, that the code being generated by the compiler is actually trying to give a truthful resolution. What I mean is that, maybe if you increase the test cases in the if statement and stick with boolean in one side and integer in another, the compiler will make it so the code generated will execute faster with boolean expressions in the machine level.
另一个更简单的方法是,查看它自己的表达式的逻辑,不要担心编译器会如何翻译你的代码,我认为这是一种更健康的思维方式。我仍然相信,最终编译器生成的代码实际上是在试图给出一个真实的解决方案。我的意思是,如果在if语句中增加测试用例,在一边使用布尔值,在另一边使用整数,编译器会使生成的代码在机器级别上使用布尔值表达式执行得更快。
I'm considering this is a conceptual question, so I'll give a conceptual answer. This discussion reminds me of discussions I commonly have about whether or not code efficiency translates to less lines of code in assembly. It seems that this concept is generally accepted as being true. Considering that keeping track of how fast the ALU will handle each statement is not viable, the second option would be to focus on jumps and compares in assembly. When that is the case, the distinction between boolean statements or integers in the code you presented becomes rather representative. The result of an expression in C++ will return a value that will then be given a representation. In assembly, on the other hand, the jumps and comparisons will be based in numeric values regardless of what type of expression was being evaluated back at you C++ if statement. It is important on these questions to remember that purely logicical statements such as these end up with a huge computational overhead, even though a single bit would be capable of the same thing.
我认为这是一个概念性的问题,所以我会给出一个概念性的答案。这个讨论让我想起了我通常所讨论的关于代码效率是否可以转换成更少的程序代码的讨论。这个概念似乎被普遍认为是正确的。考虑到跟踪ALU处理每个语句的速度是不可行的,第二个选项将是关注跳转并在程序集中进行比较。在这种情况下,您所展示的代码中的布尔语句或整数之间的区别就具有代表性了。c++中的表达式的结果将返回一个值,然后该值将得到一个表示。另一方面,在汇编语言中,跳转和比较将基于数值,而不管您c++ if语句的表达式是什么类型。在这些问题上,重要的是要记住,像这样纯粹的逻辑语句最终会产生巨大的计算开销,即使一个比特也能做同样的事情。