【问题标题】:Perl performance: for(1..200000) vs for($_=1;$_<=200000;$_++)Perl 性能:for(1..200000) 与 for($_=1;$_<=200000;$_++)
【发布时间】:2011-05-18 20:01:12
【问题描述】:

for(1..200000) {...}for($_=1;$_&lt;=200000;$_++) {...}

第一个必须创建一个包含 200,000 个项目的数组,还是与第二个差不多?

【问题讨论】:

标签: perl performance memory


【解决方案1】:
$ time perl -e '$a=0;for(1..10000000){$a++;}'

real 0m0.523s
user 0m0.520s
sys  0m0.000s

$ time perl -e '$a=0;for($_=1;$_<=10000000;$_++){$a++;}'

real    0m1.309s
user    0m1.300s
sys  0m0.000s

所以前者更快,这表明您的问题的答案是否定的。它很可能已优化为 for i in xrange(n) 在 Python 中。

【讨论】:

  • 在两个不同的硬件上与 5.12.1 和 5.13.4 的结果相当。
  • @vol7ron 这可能是因为后一种方法可以在删除对 $a 的访问时将所有内容保存在整个循环的寄存器中。
  • 我把它移到我的答案,你可能想在那里留下相同的评论。
【解决方案2】:

我很好奇是不是因为您在第二个中增加了 $_$a,而第一个执行了内部增量。

  • time perl -e 'for($_=1;$_&lt;=10000000;){$_++;}'

    real    0m0.544s
    user    0m0.540s
    sys     0m0.000s
    
  • time perl -e 'for($_=1;$_&lt;=10000000;$_++){$a;}'

    real    0m0.593s
    user    0m0.580s
    sys     0m0.000s
    

    都去掉了附加变量,也得到了更接近的结果,但并不等同于原来的例子


与 JavaScript 一样,反向 while 循环甚至比您的第二种方法更快,但比您的第一种方法稍慢:

  • time perl -e '$a=0;for($_=10000000;$_--;){$a++;}'

    real    0m0.543s
    user    0m0.530s
    sys     0m0.000s
    
  • time perl -e '$a=0;$_=10000000;while($_--){$a++;}'

    real    0m0.569s
    user    0m0.550s
    sys     0m0.010s
    

    两者都等同于原始示例;但是,如果您不能后退,它可能无法使用。他们更接近你的第一个结果

【讨论】:

    【解决方案3】:

    我可以肯定地说,for 具有范围 ($lower .. $upper) 不会在内存中创建实际的临时列表。 It did 12 years ago, but not anymore. 事实上,它比显式 C 风格的 for 循环提供了 更好 的性能(正如其他基准所显示的那样),因为 Perl 能够很好地完成计数循环,高效的内部代码。你不应该害怕使用它。

    【讨论】:

    • 我什至没看到他这么问:) 我专注于问题关键字:性能
    • 这解释了 p_for 与 c_for 相比,性能提高了 85%(在我自己的基准测试中,使用草莓 5.12.1)。
    • @vol7ron 就我而言,这是一个更重要的问题。几乎不应该担心每次迭代会产生几纳秒的开销,但是应该应该担心不必要的 O(n) 内存使用,而它可能是 O(1)。但幸运的是,这次事情很简单——for (1..n) 在所有类别中获胜。
    • 我两个都担心 :) 是的,没错,这是一个重要的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-13
    • 1970-01-01
    • 2012-11-18
    • 2013-11-11
    • 2011-02-22
    • 1970-01-01
    相关资源
    最近更新 更多