为什么我的Python版本比我的Perl版本慢?

时间:2009-12-31 10:34:40

标签: python performance perl

我已经成为Perl家伙超过10年,但是一位朋友说服我尝试使用Python并告诉我它比Perl快多少。所以只是为了踢,我把我用Perl编写的应用程序移植到Python中,发现它运行速度慢了3倍。最初,我的朋友告诉我,我一定做错了,所以我重写并重构,直到我不能重写和重构......它仍然慢得多。所以我做了一个简单的测试:

i = 0
j = 0

while (i < 100000000):
    i = i + 1
    j = j + 1

print j
  

$ time python python.py
  亿

     

真实0m48.100s
  用户0m45.633s
  sys 0m0.043s

my $i = 0;
my $j = 0;

while ($i < 100000000) {
    ++$i; # also tested $i = $i + 1 to be fair, same result
    ++$j;
}

print $j;
  

$ time perl perl.pl
  亿

     

真实0m24.757s
  用户0m22.341s
  sys 0m0.029s

慢了两倍,这似乎没有反映出我见过的任何基准测试......我的安装是否存在问题,或者是否真的比Perl 慢得多?

9 个答案:

答案 0 :(得分:51)

挑剔的答案是你应该将它与惯用的Python进行比较:

  • 我的机器上的原始代码需要 34 秒。
  • for循环(FlorianH's answer+=xrange() 21
  • 将整个事物放入一个函数会将其减少到 9 秒! 比Perl 快得多(我的机器上15秒)! 说明:Python local vars are much faster than globals
    (为了公平起见,我还在Perl中尝试了一个函数 - 没有变化)
  • 摆脱j变量将其缩小为 8 秒:

    print sum(1 for i in xrange(100000000))

Python具有奇怪的特性,即更高级别的较短代码往往是最快的: - )

但真正的答案是你的“微观基准”毫无意义。 语言速度的真正问题是:平均实际应用程序的性能如何?要知道这一点,你应该考虑到:

  • 复杂代码中典型的操作组合。 您的代码不包含任何数据结构,函数调用或OOP操作。

  • 足够大的代码库可以感受缓存效果 - 许多解释器优化会将内存换成速度,而任何微小基准都无法公平地衡量。

  • Optimization opportunities:编写代码后,如果速度不够快, 你能轻松地做多快?

    E.g。将重物卸下到有效的C libriries有多难?

PyPy's benchmarksOctane是现实语言速度基准测试的好例子。

如果你想谈论数字运算,Python IS 非常受科学家欢迎。 他们喜欢简单的伪数学语法和简短的学习曲线,也喜欢用于数组运算的优秀numpy库以及包装其他现有C代码的简易性。

然后有Psyco JIT可能会在1秒内运行你的玩具示例,但我现在无法检查它,因为它只能在32位x86上运行。
EDIT :现在,跳过Psyco并使用PyPy这是一个跨平台积极改进JIT。

答案 1 :(得分:8)

所有这些微观基准测试都会变得有点傻!

例如。只需切换到Python和&amp;中的for Perl提供了巨大的减速带。如果使用for,原始的Perl示例将快两倍:

my $j = 0;

for my $i (1..100000000) {
    ++$j;
}

print $j;


我可以用这个来削减一点:

++$j for 1..100000000;
print $j;


甚至更傻,我们可以把它降到1秒; - )

print {STDOUT} (1..10000000)[-1];

/ I3az /

ref :使用Perl 5.10.1。

答案 2 :(得分:7)

Python在数值计算方面并不是特别快,我确信它在文本处理方面比perl慢。

由于你是一位经验丰富的Perl手,我不知道这是否适用于你,但从长远来看Python程序往往更易于维护并且开发速度更快。对于大多数情况来说,速度“足够”,并且当确实需要提升性能时,您可以灵活地下载到C语言中。

更新

好。我刚刚创建了一个包含随机数据的大文件(1GB)(主要是ascii)并将其分成相等长度的行。这应该是模拟日志文件。

然后我运行简单的perl和python程序,逐行搜索文件以获得现有模式。

使用Python 2.6.2,结果是

real    0m18.364s
user    0m9.209s
sys 0m0.956s

和Perl 5.10.0

real    0m17.639s
user    0m5.692s
sys 0m0.844s

程序如下(如果我做了些蠢事,请告诉我)

import re
regexp = re.compile("p06c")

def search():
    with open("/home/arif/f") as f:
        for i in f:
            if regexp.search(i):
                print "Found : %s"%i

search()

sub search() {
  open FOO,"/home/arif/f" or die $!;
  while (<FOO>) {
    print "Found : $_\n" if /p06c/o;
  }
}

search();

结果非常接近并以这种方式调整或其他似乎不会改变结果。我不知道这是否是 true 基准测试,但我认为这是我用两种语言搜索日志文件的方式,因此我对相对性能进行了纠正。

谢谢Chris。

答案 3 :(得分:7)

如果使用python语言的正确语法,Python运行速度非常快。它大致描述为“pythonic”。

如果像这样重构代码,它的运行速度至少要快两倍(好吧,它在我的机器上运行):

j = 0
for i in range(10000000):
    j = j + 1
print j

每当你在python中使用while时,你应该检查你是否也可以使用“for X in range()”。

答案 4 :(得分:7)

对于OP,在Python中这段代码:

j = 0
for i in range(10000000):
    j = j + 1
print j

相同
print range(10000001)[-1]

,在我的机器上,

$ time python test.py
10000000

real    0m1.138s
user    0m0.761s
sys     0m0.357s

运行大约1秒。 range()(或xrange)是Python的内部和“内部”,它已经可以为你生成一系列数字。因此,您不必使用自己的循环创建自己的迭代。现在,你去找一个可以运行1秒的Perl等价物来产生相同的结果

答案 5 :(得分:4)

Python在字典中维护全局变量。因此,每次有一个赋值时,解释器就会对模块字典执行查找,这有点贵,这就是为什么你发现你的例子这么慢的原因。

为了提高性能,您应该使用本地分配,比如创建一个函数。 Python解释器将局部变量存储在一个数组中,访问速度更快 但是,应该注意的是,这是CPython的实现细节;我怀疑IronPython会导致完全不同的结果。

最后,有关此主题的更多信息,我建议您从GvR撰写一篇有趣的文章,关于Python的优化:Python Patterns - An Optimization Anecdote

答案 6 :(得分:2)

python比perl慢。开发可能会更快,但它执行速度更快,这是一个基准http://xodian.net/serendipity/index.php?/archives/27-Benchmark-PHP-vs.-Python-vs.-Perl-vs.-Ruby.html - 编辑 - 一个可怕的基准,但它至少是一个真正的基准数字,而不是一些猜测。为了坏,没有来源或测试其他循环。

答案 7 :(得分:1)

我对Python的所有内容都不及时了解,但我对这个基准测试的第一个想法是Perl和Python数字之间的区别。在Perl中,我们有数字。它们不是对象,它们的精度仅限于架构强加的大小。在Python中,我们拥有任意精度的对象。对于小数字(那些适合32位的数字),我希望Perl更快。如果我们查看体系结构的整数大小,Perl脚本甚至无需进行一些修改就可以工作。

我在MacBook Air(32位)上使用我自己编译的Perl 5.10.1和Leopard附带的Python 2.5.1看到了类似的原始基准测试结果:

但是,我使用bignum

为Perl程序添加了任意精度
 use bignum;

现在我想知道Perl版本是否会完成。 :)当它完成时我会发布一些结果,但它看起来会有一个数量级的差异。

有些人可能已经看到了关于What are five things you hate about your favorite language?的问题。 Perl的默认数字是我讨厌的事情之一。我永远不应该考虑它,它不应该慢。在Perl中,我两者都输了。但请注意,如果我需要在Perl中进行数字处理,我可以使用PDL

答案 8 :(得分:0)

  

是Python真的慢得多   Perl的?

查看计算机语言基准游戏 - “使用≈12个有缺陷的基准和≈1100个程序比较≈30个编程语言的性能”。

它们只是很小的基准程序,但它们仍然比你定时的代码片段做得更多 -

http://shootout.alioth.debian.org/u32/python.php