我已经是一个超过10年的Perl家伙,但是一位朋友说服我尝试使用Python并告诉我它比Perl快多少.所以只是为了踢,我把我用Perl编写的应用程序移植到Python中,发现它运行速度慢了3倍.最初,我的朋友告诉我,我一定做错了,所以我重写并重构,直到我不能重写和重构......它仍然慢得多.所以我做了一个简单的测试:
i = 0 j = 0 while (i < 100000000): i = i + 1 j = j + 1 print j
$ time python python.py
100000000真正的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
100000000实际0m24.757s
用户0m22.341s
sys 0m0.029s
慢了两倍,这似乎没有反映出我见过的任何基准测试......我的安装有问题还是Python真的比Perl慢得多?
挑剔的答案是你应该将它与惯用的Python进行比较:
原始代码在我的机器上需要34秒.
一个for
循环(FlorianH的答案),与+=
和xrange()
取21.
将整个功能放在一个功能中将其减少到9秒!
这比Perl快得多(在我的机器上15秒)!
说明:Python本地变量比全局变量快得多.
(为了公平起见,我也在Perl中尝试了一个函数 - 没有变化)
摆脱j变量将其减少到8秒:
print sum(1 for i in xrange(100000000))
Python具有奇怪的属性,更高级别的更短代码往往是最快的:-)
但真正的答案是你的"微观基准"毫无意义.语言速度的真正问题是:平均实际应用程序的性能如何?要知道这一点,你应该考虑到:
复杂代码中典型的操作组合.您的代码不包含任何数据结构,函数调用或OOP操作.
足够大的代码库可以感受缓存效果 - 许多解释器优化会为了速度而交换内存,而任何微小的基准都无法公平地衡量.
优化 机会:在您编写代码后,如果速度不够快,您可以轻松实现多快?
例如,将繁重的工作卸载到有效的C libriries有多难?
PyPy的基准测试和Octane是现实语言速度基准测试的好例子.
如果你想谈论数字运算,Python的IS与科学家令人惊讶的流行.他们喜欢简单的伪数学语法和简短的学习曲线,但也喜欢用于数组运算的优秀numpy库以及包装其他现有C代码的简易性.
然后有Psyco JIT可能会在1秒内运行你的玩具示例,但我现在无法检查它,因为它只适用于32位x86.
编辑:现在,跳过Psyco并使用PyPy,这是一个跨平台积极改进JIT.
所有这些微观基准测试都会变得有点傻!
例如.只需for
在Python和Perl中切换,就可以提供巨大的速度提升.如果使用原始Perl示例将快两倍for
:
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.
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 () { print "Found : $_\n" if /p06c/o; } } search();
结果非常接近并以这种方式调整或其他似乎不会改变结果.我不知道这是否是一个真正的基准,但我认为这是我用两种语言搜索日志文件的方式,所以我对相对表现进行了纠正.
谢谢克里斯.
如果你使用python语言的正确语法,Python运行速度非常快.它大致被描述为" pythonic ".
如果像这样重构代码,它的运行速度至少要快两倍(好吧,它在我的机器上运行):
j = 0 for i in range(10000000): j = j + 1 print j
每当你在python中使用while时,你应该检查你是否也可以使用"for X in range()".
对于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等价物来产生相同的结果