【问题标题】:For loop execution time different conditionsFor循环执行时间不同条件
【发布时间】:2014-08-28 08:40:47
【问题描述】:

为什么是代码:

for( i = 0, j = 0; i < 4 ,  j < 3; i++, j++)

 for( i = 0, j = 0; i < 4 &&  j < 3; i++, j++)

详细说明一些用户提出两个 if 语句比一个带有 && 运算符的 if 语句花费更多时间:我在没有 for 循环的情况下对其进行了测试,但事实并非如此。两个 if 语句比一个带有 && 运算符的语句快。

【问题讨论】:

  • 每个循环实际运行了多少次?
  • 它们运行的​​次数相同:3 次。
  • 为什么你说第一个比第二个慢?
  • 因为我测量了执行时间。
  • 对未优化的代码进行基准测试是没有用的。很可能,GCC 优化可能会展开循环体(您没有在问题中显示)。

标签: c for-loop


【解决方案1】:

第一个代码并不慢;至少在gcc 没有优化。其实应该更快

当你编译两个代码并反汇编它们时,你会发现第一个代码是这样的:

cmpl   $0x2,-0x8(%rbp)
jle    26 <main+0x26>

这是第二个:

cmpl   $0x3,-0x4(%rbp)
jg     44 <main+0x44>
cmpl   $0x2,-0x8(%rbp)
jle    26 <main+0x26>

在第一个例子中,gcc 只计算第二部分,因为第一个没有效果,也没有在比较中使用。在第二个中,它必须检查第一个,如果为真,则检查第二个。

因此,在一般情况下,第一个示例应该比第一个示例。如果您发现第一个较慢,可能是您测量它的方法不是 100% 正确。

【讨论】:

  • 这不是完全有效的.....你要解释的是在 & 的情况下发生的事情,但不是 &&
【解决方案2】:

他们的可能在执行时间上没有变化,但可能是迭代次数,因为:

如果我们将逗号分隔的条件放在for循环中,它会评估最后一个的值。所以基本上无论你先写哪个条件,它都会被忽略,第二个条件会被检查。所以j = 0; i &lt; 4 将始终检查i&lt;4,而i &lt; 4 &amp;&amp; j &lt; 3 将检查并返回true,当且仅当两个条件都是true

Reference

【讨论】:

    【解决方案3】:

    如果我们确实检查了您拥有的代码的程序集,您可能会看到差异

    程序

    int main()
    {
        int x,y;
        for(x=0,y=0;x<4,y<5;x++,y++);
    
        printf("New one");
    
        for(x=0,y=0;x<4 && y<5;x++,y++);
    
    }
    

    获取程序集的命令:gcc -S &lt;program name&gt;

    组装

              .file   "for1.c"
        .section    .rodata
    .LC0:
        .string "New one"
        .text
        .globl  main
        .type   main, @function
    main:
    .LFB0:
        .cfi_startproc
        pushl   %ebp
        .cfi_def_cfa_offset 8
        .cfi_offset 5, -8
        movl    %esp, %ebp
        .cfi_def_cfa_register 5
        andl    $-16, %esp
        subl    $32, %esp
        movl    $0, 24(%esp)
        movl    $0, 28(%esp)
        jmp .L2
    .L3:
        addl    $1, 24(%esp)
        addl    $1, 28(%esp)
    .L2:
        cmpl    $4, 28(%esp) //Here only one condition
        jle .L3
        movl    $.LC0, (%esp)
        call    printf
        movl    $0, 24(%esp)
        movl    $0, 28(%esp)
        jmp .L4
    .L6:
        addl    $1, 24(%esp)
        addl    $1, 28(%esp)
    .L4:
        cmpl    $3, 24(%esp) //First Condition
        jg  .L7
        cmpl    $4, 28(%esp) //Second Condition
        jle .L6
    .L7:
        leave
        .cfi_restore 5
        .cfi_def_cfa 4, 4
        ret
        .cfi_endproc
    .LFE0:
        .size   main, .-main
        .ident  "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
        .section    .note.GNU-stack,"",@progbits
    

    所以,很明显,如果我们有 2 个条件,那么需要更多的时间。

    【讨论】:

      【解决方案4】:

      第一个选项是两个如果, 第二个选项是一个数学方程和一个如果,通常更快, 在这里,如果通过计算,您可以节省一个,这会花费更少的处理时间。

      第一个选项 -> if() && if(),

      第二个选项-> if(() && ())

      【讨论】:

      • 可能值得一提的是,第一个i &lt; 4 是多余的。
      • first for 会导致if(i&lt;4,j&lt;3),和if(j&lt;3)一样
      • 不,逗号计算并忽略 i
      • i
      • 不,它总是多余的。 a=(b,c); 始终是 a=c,无论 b 是什么。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-01
      • 1970-01-01
      • 2011-07-10
      相关资源
      最近更新 更多