【问题标题】:php: output[] w/ join vs $output .=php: output[] w/join vs $output .=
【发布时间】:2016-01-18 18:46:48
【问题描述】:

我正在修改原作者使用数组构建网页的一些代码:

 $output[]=$stuff_from_database;
 $output[]='more stuff';
 // etc
 echo join('',$output);

任何人都可以想出一个原因,为什么这更可取(反之亦然):

 $output =$stuff_from_database;
 $output .='more stuff';
 // etc
 echo $output;

【问题讨论】:

    标签: php string-concatenation


    【解决方案1】:

    它可能是由来自字符串不可变语言的人编写的,因此连接成本很高。如以下测试所示,PHP 不是其中之一。所以第二种方法在性能方面更好,更好。我能想到的使用第一种方法的唯一另一个原因是能够用另一个替换数组的某些部分,但这意味着要跟踪索引,这没有指定。

    ~$ cat join.php
    <?php
    
    for ($i=0;$i<50000;$i++) {
    $output[] = "HI $i\n";
    }
    
    echo join('',$output);
    ?>
    
    
    ~$ time for i in `seq 100`; do php join.php >> outjoin ; done
    
    real    0m19.145s
    user    0m12.045s
    sys     0m3.216s
    
    ~$ cat dot.php
    <?php
    
    for ($i=0;$i<50000;$i++) {
    $output.= "HI $i\n";
    }
    
    echo $output;
    ?>
    
    
    ~$ time for i in `seq 100`; do php dot.php >> outdot ; done
    
    real    0m15.530s
    user    0m8.985s
    sys     0m2.260s
    

    【讨论】:

    • 这是对 PHP 4 的明显改进,而 PHP 4 则完全相反。
    【解决方案2】:

    这有点离题了,但是

    $output =$stuff_from_database;
    $output .='more stuff';
    // etc
    echo $output;
    

    远慢于:

    echo = $stuff_from_database;
    echo 'more stuff';
    

    其实在 PHP 中构建字符串最快的方法是:

    ob_start();
    echo = $stuff_from_database;
    echo 'more stuff';
    $output = ob_get_contents();
    ob_end_clean();
    

    由于输出缓冲区的工作方式等,它是构建字符串的最快方式。显然,只有在您确实需要优化 sting 构建时才会这样做,因为它很丑陋并且不会导致代码易于阅读。并且大家都知道“过早的优化是万恶之源”。

    【讨论】:

    • 在 "echo =" 和输出 '$output' 周围进行少量代码更正,这是最快的,因为输出缓冲分配为 4 或 8KB 块,而不是按需分配(尽可能少1 个字节)。
    【解决方案3】:

    再一次,有点离题(不是很远),但是如果您的目标是在要输出的数组项之间放置一些东西,那么如果只有几行要连接,join(', ', $output ) 会足够容易和快速地做到这一点。这会更容易编写,并且不必检查列表的末尾(您不希望尾随 ',')。

    对于程序员而言,由于它比 CPU 周期贵 1000 倍,如果它不打算每秒运行 10,0000 次以上,我通常会将其放入连接中.

    就所花费的时间与节省的 CPU 时间而言,这样的编码后微优化很少值得。

    【讨论】:

      【解决方案4】:

      !-- 已编辑以前的评论 -->

      我的代码似乎有错误,所以我没有执行任何操作并忘记检查。

      这似乎与之前的测试相反,并且阅读了之前关于该主题的博客, 至少对于我可以置换的上述代码的所有变体,以下结论实际上是(经过测试的)不真实

      1. UNTRUE:字符串插值比字符串连接慢。 (!)
      2. UNTRUE:SprintF 最快。

      在实际测试中,Sprintf 最慢,插值最快

      PHP 5.2.6-pl7-gentoo (cli) (内置: Sep 21 2008 13:43:03) 版权所有 (c) 1997-2008 PHP 集团 Zend Engine v2.2.0,版权所有 (c) 1998-2008 Zend Technologies 使用 Xdebug v2.0.3,版权所有 (c) 2002-2007,作者 Derick Rethans

      这可能取决于我的设置,但它仍然很奇怪。 :/

      【讨论】:

        【解决方案5】:

        我认为最快的方法是使用回声。它不够漂亮,而且速度可能还不够快,值得付出可读性的代价。

        echo $stuff_from_database
           , 'more stuff'
           , 'yet more'
           // etc
           , 'last stuff';
        

        【讨论】:

          【解决方案6】:

          底部会重复重新分配 $output 字符串,而我相信顶部只会将每个部分存储在一个数组中,然后在最后将它们全部连接起来。结果,原始示例最终可能会更快。如果这对性能不敏感,那么我可能会追加,而不是加入。

          【讨论】:

            【解决方案7】:

            这部分代码对性能不敏感;它用于在低流量网站上格式化和显示用户的购物车信息。此外,数组(或字符串)每次都是从头开始构建的,无需寻址或搜索特定元素。听起来数组效率更高一些,但我想这两种方式都无关紧要。感谢您提供所有信息!

            【讨论】:

              【解决方案8】:

              如果您要生成一个列表(例如购物车),您应该有一些代码可以从从数据库中获取的每个条目生成 HTML。

              for ($prod in $cart)
              {
                $prod->printHTML();
              }
              

              或者类似的东西。这样,代码就变得干净多了。当然,这是假设你有很好的对象代码,而不是像我的公司那样(并且正在替换)一团糟的烂摊子。

              【讨论】:

                【解决方案9】:

                已经说过了,但我认为一个明确的答案会有所帮助。

                最初的程序员是这样写的,因为他认为这样更快。事实上,在 PHP 4 下,它确实更快,尤其是对于大字符串。

                【讨论】:

                  【解决方案10】:

                  如果加入implode()join(),PHP 能够更好地优化它。它遍历列表中的所有字符串,计算长度并分配所需的空间并填充空间。与 ".=" 相比,它必须不断地为 free()malloc() 留出空间。

                  【讨论】:

                  • 你提出了一个很好的观点。测量内存消耗会很有趣......也许这可能是大型数据集的瓶颈。
                  猜你喜欢
                  • 2021-09-28
                  • 1970-01-01
                  • 2012-07-08
                  • 1970-01-01
                  • 1970-01-01
                  • 2016-11-23
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-01-26
                  相关资源
                  最近更新 更多