栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

x> -1 vs x> = 0,是否存在性能差异

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

x> -1 vs x> = 0,是否存在性能差异

在现实世界中没有任何区别。

让我们看一下各种编译器为各种目标生成的代码。

  • 我假设一个有符号的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)
    VS
    cmp r0,#0
    (x >= 0)
    。第一条指令的操作码长两个字节。我想这可能会增加一些时间,所以我们称此为
    (x >= 0)
  • MSVC针对x86使用
    cmp ecx, -1
    (x > -1)
    VS
    test ecx, ecx
    (x >= 0)
    。第一条指令的操作码长一个字节。我想这可能会增加一些时间,所以我们称此为
    (x >= 0)

请注意,GCC和IAR为两种比较生成了相同的机器代码(可能使用了哪个寄存器除外)。因此,根据这项调查,似乎

(x >=0)
“变快”的可能性很小。但是,最小操作码字节编码可能具有的任何优势(我强调) 可能 会被其他因素完全掩盖。

如果您发现Java或C#的混合输出有什么不同,我会感到惊讶。我怀疑即使对于8位AVR这样的很小的目标,您也会发现音符有什么不同。

简而言之,不必担心这种微优化。我想我在这里写的文章已经花了更多的时间,而我一生中所有执行它们的CPU上所积累的这些表达式的性能的任何差异所花费的时间。如果您有能力测量性能差异,请将您的精力投入到更重要的事情上,例如研究亚原子粒子的行为或其他事情。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/451523.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号