dougaopu7938 2014-04-07 14:53
浏览 121
已采纳

PHP中while(true)和for(;;)之间有什么区别?

Is there any difference in PHP between while(true) and for(;;) besides syntax and readability?

Edit: I would not consider this a duplicate - I want to know the answer specific to PHP. Is there any real difference as far as the engine is concerned? Do they compile to the same thing? Do they have equal performance?

Edit 2: I would also not consider the relative performance and associated OpCodes to be based on opinion. There is scope for opinion in the readability but this is explicitly not the question.

  • 写回答

1条回答 默认 最新

  • douhui9380 2014-04-07 15:54
    关注

    Ok, so first off, let me say this: Use while(true), as it gives the most semantic meaning. You need to parse for (;;) as it's not something you see often.

    With that said, let's analyze:

    Opcodes

    The code

    while(true) {
        break;
    }
    echo "hi!";
    

    Compiles down to the opcodes:

    0: JMPZ(true, 3)
    1: BRK(1, 3)
    2: JMP(0)
    3: ECHO("hi!")
    

    So basically, it does a check if "true", and if not, jumps to the 4th opcode which is the echo opcode). Then it breaks (which is really just a static jump to the 4th opcode). Then the end of the loop would be an unconditional jump back to the original check

    Compare that to:

    for (;;) {
        break;
    }
    echo "hi!";
    

    Compiles down to:

    0: JMPZNZ(true, 2, 4)
    1: JMP(0)
    2: BRK(1, 4)
    3: JMP(1)
    4: ECHO("hi!")
    

    So we can immediately see that there's an extra opcode in the for(;;) version.

    Opcode Definitions

    JMPZ(condition, position)

    This opcode jumps if the condition is false. If it is true, it does nothing but advance one opcode.

    JMPZNZ(condition, pos1, pos2)

    This opcode jumps to pos1 if the condition is true, and pos2 if the condition is false.

    JMP(position)

    This opcode always jumps to the opcode at the specified position.

    BRK(level, position)

    This breaks level levels to the opcode at position

    ECHO(string)

    Outputs the string

    Are They The Same

    Well, looking at the opcodes, it's clear that they are not identical. They are ==, but not ===. The while(true) loop does a conditional jump followed by code followed by an unconditional jump. The for(;;) loop does a conditional jump, followed by code, followed by an unconditional jump, followed by another unconditional jump. So it does an extra jump.

    Opcache

    In 5.5, the Optimizer portion of opcache will optimize static conditional jumps.

    So that means the while(true) code will optimize down to:

    0: BRK(1, 2)
    1: JMP(0)
    2: ECHO("hi!")
    

    And for(;;) loop becomes:

    0: BRK(1, 2)
    1: JMP(0)
    2: ECHO("hi!")
    

    This is because the optimizer will find and optimize out jump-chains. So if you're using 5.5's built-in opcache, they will be identical...

    Caution

    This is a complete and utter micro-optimization to base a decision on. Use the readable one. Don't use one based on performance. The difference is there, but it's trivial.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 求数据集和代码#有偿答复
  • ¥15 关于下拉菜单选项关联的问题
  • ¥20 java-OJ-健康体检
  • ¥15 rs485的上拉下拉,不会对a-b<-200mv有影响吗,就是接受时,对判断逻辑0有影响吗
  • ¥15 使用phpstudy在云服务器上搭建个人网站
  • ¥15 应该如何判断含间隙的曲柄摇杆机构,轴与轴承是否发生了碰撞?
  • ¥15 vue3+express部署到nginx
  • ¥20 搭建pt1000三线制高精度测温电路
  • ¥15 使用Jdk8自带的算法,和Jdk11自带的加密结果会一样吗,不一样的话有什么解决方案,Jdk不能升级的情况
  • ¥15 画两个图 python或R