我已经成为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 慢得多?
答案 0 :(得分:51)
挑剔的答案是你应该将它与惯用的Python进行比较:
for
循环(FlorianH's answer)+=
和xrange()
21 。 摆脱j变量将其缩小为 8 秒:
print sum(1 for i in xrange(100000000))
Python具有奇怪的特性,即更高级别的较短代码往往是最快的: - )
但真正的答案是你的“微观基准”毫无意义。 语言速度的真正问题是:平均实际应用程序的性能如何?要知道这一点,你应该考虑到:
复杂代码中典型的操作组合。 您的代码不包含任何数据结构,函数调用或OOP操作。
足够大的代码库可以感受缓存效果 - 许多解释器优化会将内存换成速度,而任何微小基准都无法公平地衡量。
Optimization opportunities:编写代码后,如果速度不够快, 你能轻松地做多快?
E.g。将重物卸下到有效的C libriries有多难?
PyPy's benchmarks和Octane是现实语言速度基准测试的好例子。
如果你想谈论数字运算,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)
如果像这样重构代码,它的运行速度至少要快两倍(好吧,它在我的机器上运行):
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个编程语言的性能”。
它们只是很小的基准程序,但它们仍然比你定时的代码片段做得更多 -