【发布时间】:2011-10-11 11:20:15
【问题描述】:
例如,这里有两种设置整数变量的方法(比如 C++):
int x = 0xFF;
int y = 255;
哪个语句会编译更快地将实际位设置为整数值?
已编辑:*编译从执行更改。我假设转换为二进制是在执行时,但似乎是在编译时给出@muntoo 的回答
【问题讨论】:
例如,这里有两种设置整数变量的方法(比如 C++):
int x = 0xFF;
int y = 255;
哪个语句会编译更快地将实际位设置为整数值?
已编辑:*编译从执行更改。我假设转换为二进制是在执行时,但似乎是在编译时给出@muntoo 的回答
【问题讨论】:
执行时间绝对没有差异,编译速度可能没有差异。
添加以回应评论:
这就是发生的事情。编译器有一个解析器,可能是递归下降的,在底部它调用一个词法分析器来获取标记。在这种情况下,= 之后的标记是一个数字,它可以通过前导数字来判断,所以它是这样的,其中 pc 是指向当前字符的指针:
if (isdigit(*pc)){
intpart = 0;
if (pc[0]=='0' && pc[1]=='x'){
pc += 2;
while(ishexdigit(*pc)){
intpart *= 16;
if (isdigit(*pc)){
intpart += (*pc - '0')
}
else {
intpart += (tolower(*pc) - 'a' + 10);
}
pc++;
}
}
else {
while(isdigit(*pc)){
intpart *= 10;
intpart += (*pc - '0');
pc++;
}
if (*pc == '.'){
// ... handle fractional part
}
}
}
无论如何,如您所见,这是一个非常紧凑的循环,对数字中的每个字符执行一次或两次isdigit 或ishexdigit 或tolower,以及乘法、减法和加法。假设这些函数是内联的,我们说的每个字符可能有 10-20 条指令。
在十六进制情况下,每个字符的指令可能略多一些,但十进制数会有更多的字符,所以很难告诉 a-priori 哪个应该更快。
这只发生在你有能力在代码中输入的整数的总数中,比如大约 100。
如果机器每秒可以执行 10^8 条指令,它可以以每秒 10^7 左右的速度读取数字,或者每个字符大约 100 纳秒,或者文件中的所有数字为 10 微秒,给出或取一个数量级。
一旦编译器知道它是一个数字,它就会成为抽象语法树的一部分,用于生成汇编语言。到那时,它是十六进制或十进制的事实早已被遗忘。它只知道它是一个特定值的二进制整数,因此汇编语言将是相同的。
【讨论】:
0xFF 与255 相同,从您的编译器的角度来看。两者都将生成完全相同的代码。您的编译器将它们都“转换”为11111111b。
编译速度完全取决于编译器及其编译方式。
例如,0xFF 可以识别为十六进制数字(忽略正则表达式,这将是首选方法):
bool myishex(string sz)
{
if(sz[0] == '0' && sz[1] == 'x')
{
for(size_t i = 2; i < sz.length(); ++i)
if(!(sz[i] >= '0' && sz[i] <= '9') || !(sz[i] >= 'A' && sz[i] <= 'F') || !(sz[i] >= 'a' && sz[i] <= 'f'))
return(false);
}
else
{
return(false);
}
return(true);
}
与myisnum()相比:
bool myisnum(string sz)
{
for(size_t i = 0; i < sz.length(); ++i)
if(!(sz[i] >= '0' && sz[i] <= '9'))
return(false);
return(true);
}
嗯,myisnum()通常比myishex()快。 (A-F或a-f的概率高于0-9。)
但是从FF 到二进制数的转换可能比255 慢快。
int myhex2bin(string sz)
{
int b = 0;
sz = sz.substr(2); // Cut the "0x" out.
for(size_t i = 0; i < sz.length(); ++i)
{
sz[i] = tolower(sz[i]);
b += myhexdigit2dec(sz[i]) << ((sz.length() - (i + 1)) << 2);
}
return(b);
}
// Unsafe. Optimized for speed.
int myhexdigit2dec(char c)
{
return(c < 'A' ? c - '0' : (c < 'a' ? c - 'A' + 10 : c - 'a' + 10));
}
虽然你没有得到十进制到二进制的位移,但你也没有得到A-F 和a-f。
int mydec2bin(string sz)
{
int b = 0;
int factor = 1;
for(size_t i = sz.length(); i > 0; --i)
{
b += (sz[i - 1] - '0') * factor;
factor *= 10;
}
return(b);
}
结论:仍然取决于编译器,但255可能编译得更快。 :)
【讨论】: