在任何现实世界中都没有区别。
让我们看一下各种编译器针对各种目标生成的一些代码。
下面是他们每个人为比较操作产生的结果:
针对 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,#+0
01D4 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) 之间出现的任何注释的差异:
- 针对 ARM 的 MSVC 使用
cmp r0,#0xFFFFFFFF 代表 (x > -1) 而 cmp r0,#0 代表 (x >= 0)。第一条指令的操作码长了两个字节。我想这可能会引入一些额外的时间,所以我们将其称为 (x >= 0) 的优势
- 针对 x86 的 MSVC 使用
cmp ecx, -1 代表 (x > -1) 而 test ecx, ecx 代表 (x >= 0)。第一条指令的操作码长一个字节。我想这可能会带来一些额外的时间,所以我们称之为(x >= 0) 的优势
请注意,GCC 和 IAR 为两种比较生成了相同的机器代码(可能使用了哪个寄存器除外)。因此,根据这项调查,(x >= 0) 似乎“更快”的可能性很小。但是,无论最小化的操作码字节编码可能具有什么优势(我强调可能有),肯定会完全被其他因素所掩盖。
如果您发现 Java 或 C# 的 jitted 输出有什么不同,我会感到惊讶。即使对于像 8 位 AVR 这样非常小的目标,我怀疑你会发现任何不同之处。
简而言之,不用担心这种微优化。我认为我在这里写的时间已经超过了这些表达式在我有生之年执行它们的所有 CPU 上累积的性能差异所花费的时间。如果您有能力衡量性能差异,请将您的精力投入到更重要的事情上,例如研究亚原子粒子的行为或其他事情。