
在现实世界中没有任何区别。
让我们看一下各种编译器为各种目标生成的代码。
- 我假设一个有符号的int *** 作(这似乎是OP的意图)
- 通过调查,我仅限于C和我手边的编译器(诚然是一个很小的示例-GCC,MSVC和IAR)
- 启用了基本优化(
-O2
针对GCC,/Ox
针对MSVC,-Oh
针对IAR) 使用以下模块:
void my_puts(char const* s);
void cmp_gt(int x)
{
if (x > -1) {
my_puts(“non-negative”);
}
else {
my_puts(“negative”);
}
}void cmp_gte(int x)
{
if (x >= 0) {
my_puts(“non-negative”);
}
else {
my_puts(“negative”);
}
}
这是它们每个人为比较 *** 作产生的结果:
针对ARM的MSVC 11:
// if (x > -1) {...00000 |cmp_gt| PROC 00000 f1b0 3fff cmp r0,#0xFFFFFFFF 00004 dd05 ble |$LN2@cmp_gt|// if (x >= 0) {... 00024 |cmp_gte| PROC 00024 2800 cmp r0,#0 00026 db05 blt |$LN2@cmp_gte|针对x64的MSVC 11:
// if (x > -1) {...cmp_gt PROC 00000 83 f9 ff cmp ecx, -1 00003 48 8d 0d 00 00 // speculative load of argument to my_puts() 00 00 lea rcx, OFFSET FLAT:$SG1359 0000a 7f 07 jg SHORT $LN5@cmp_gt// if (x >= 0) {...cmp_gte PROC 00000 85 c9 test ecx, ecx 00002 48 8d 0d 00 00 // speculative load of argument to my_puts() 00 00 lea rcx, OFFSET FLAT:$SG1367 00009 79 07 jns SHORT $LN5@cmp_gte针对x86的MSVC 11:
// if (x > -1) {..._cmp_gt PROC 00000 83 7c 24 04 ff cmp DWORD PTR _x$[esp-4], -1 00005 7e 0d jle SHORT $LN2@cmp_gt// if (x >= 0) {..._cmp_gte PROC 00000 83 7c 24 04 00 cmp DWORD PTR _x$[esp-4], 0 00005 7c 0d jl SHORT $LN2@cmp_gte针对x64的GCC 4.6.1
// if (x > -1) {...cmp_gt: .seh_endprologue test ecx, ecx js .L2// if (x >= 0) {...cmp_gte: .seh_endprologue test ecx, ecx js .L5针对x86的GCC 4.6.1:
// if (x > -1) {..._cmp_gt: mov eax, DWORD PTR [esp+4] test eax, eax js L2// if (x >= 0) {..._cmp_gte: mov edx, DWORD PTR [esp+4] test edx, edx js L5针对ARM的GCC 4.4.1:
// if (x > -1) {...cmp_gt: .fnstart.LFB0: cmp r0, #0 blt .L8// if (x >= 0) {...cmp_gte: .fnstart.LFB1: cmp r0, #0 blt .L2针对ARM Cortex-M3的IAR 5.20:
// if (x > -1) {...cmp_gt:80B5 PUSH {R7,LR}.... LDR.N R1,??DataTable1 ;; `?<Constant "non-negative">`0028 CMP R0,#+001D4 BMI.N ??cmp_gt_0// if (x >= 0) {...cmp_gte: 80B5 PUSH {R7,LR} .... LDR.N R1,??DataTable1 ;; `?<Constant "non-negative">` 0028 CMP R0,#+0 01D4 BMI.N ??cmp_gte_0如果您仍然与我在一起,则这里是评估
(x > -1)与
(x >= 0)显示之间任何注释的区别:
- MSVC针对ARM用途
cmp r0,#0xFFFFFFFF
为(x > -1)
VScmp r0,#0
的(x >= 0)
。第一条指令的 *** 作码长两个字节。我想这可能会增加一些时间,所以我们称此为(x >= 0)
- MSVC针对x86使用
cmp ecx, -1
为(x > -1)
VStest ecx, ecx
的(x >= 0)
。第一条指令的 *** 作码长一个字节。我想这可能会增加一些时间,所以我们称此为(x >= 0)
请注意,GCC和IAR为两种比较生成了相同的机器代码(可能使用了哪个寄存器除外)。因此,根据这项调查,似乎
(x >=0)“变快”的可能性很小。但是,最小 *** 作码字节编码可能具有的任何优势(我强调) 可能 会被其他因素完全掩盖。
如果您发现Java或C#的混合输出有什么不同,我会感到惊讶。我怀疑即使对于8位AVR这样的很小的目标,您也会发现音符有什么不同。
简而言之,不必担心这种微优化。我想我在这里写的文章已经花了更多的时间,而我一生中所有执行它们的CPU上所积累的这些表达式的性能的任何差异所花费的时间。如果您有能力测量性能差异,请将您的精力投入到更重要的事情上,例如研究亚原子粒子的行为或其他事情。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)