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 给自己本科IT专业毕业的妹m找个实习工作
  • ¥15 用友U8:向一个无法连接的网络尝试了一个套接字操作,如何解决?
  • ¥30 我的代码按理说完成了模型的搭建、训练、验证测试等工作(标签-网络|关键词-变化检测)
  • ¥50 mac mini外接显示器 画质字体模糊
  • ¥15 TLS1.2协议通信解密
  • ¥40 图书信息管理系统程序编写
  • ¥20 Qcustomplot缩小曲线形状问题
  • ¥15 企业资源规划ERP沙盘模拟
  • ¥15 树莓派控制机械臂传输命令报错,显示摄像头不存在
  • ¥15 前端echarts坐标轴问题