我怎样才能加快我的Perl程序?
这实际上是两个问题,但它们非常相似,为了简单起见,我想我会把它们放在一起:
首先 :给定一个已建立的Perl项目,有什么体面的方法可以加速它不仅仅是简单的代码内优化?
其次 :在Perl中从头开始编写程序时,有什么方法可以大大提高性能?
对于第一个问题,假设你是一个写得很好的项目,你需要提高性能,但你似乎无法通过重构/优化获得很大的收益。 在这种情况下,你会怎么做才能加快速度,而不是像C一样重写它?
除非特定于Perl,否则请远离一般优化技术。
我之前曾问过这个关于Python的问题,并且我认为对其他语言来说可能是好的(我特别好奇的是,如果Perl的psycho和pyrex有推论的话)。
请记住优化俱乐部的规则:
所以,假设你实际上有工作代码,在Devel :: NYTProf下运行你的程序。
找到瓶颈。 然后回到这里告诉我们他们是什么。
如果您没有工作代码,请先让它工作。 你将做的最大的单一优化是从非工作到工作。
安迪已经提到了Devel :: NYTProf。 这很棒。 真的,真的很棒。 用它。
如果由于某种原因你不能使用Devel::NYTProf
,那么你可以回溯到很久以前已经与Perl标准一致的Devel :: DProf。 如果你有真正的函数(在数学意义上)需要很长的时间来计算(例如斐波那契数),那么你可能会发现Memoize提供了一些速度提升。
许多不良的性能来自不适当的数据结构和算法。 计算机科学的好课程可以在这里帮助很大。 如果你有两种做事方式,并且想比较他们的表现,那么Benchmark模块也可以证明是有用的。
下面的Perl提示也可能在这里证明有用:
免责声明:我写了一些上面的资源,所以我可能会偏向他们。
有很多事情你可能会改进,所以你首先必须弄清楚什么是缓慢的。 其他人已经回答了这个问题。 我也在掌握Perl中谈论这一点。
在您编写新代码时需要考虑的不完整列表:
用Devel :: NYTProf之类的配置文件来查看你在代码中的大部分时间。 有时候这是令人惊讶和容易解决的。 掌握Perl有很多关于这方面的建议。
Perl必须每次编译源代码,并且编译可能会很慢。 它必须找到所有的文件等。 例如,参见Jean-Louis Leroy的“及时开始”,他通过在@INC
优化模块位置来加快速度。 如果您的启动成本昂贵并且不可避免,那么您也可以查看持久化perls,如pperl,mod_perl等。
看看你使用的一些模块。 他们是否有长期的依赖关系只是为了做简单的事情? 当然,我们不喜欢重新发明,但如果你想要放在汽车上的轮子也带有三只小船,五只山羊和一个芝士汉堡,也许你想建立你自己的轮子(或者找到一个不同的轮子) 。
方法调用可能很昂贵。 例如,在Perl :: Critic测试套件中,它对isa
调用减慢了速度。 在任何情况下,这都不是你可以真正避免的,但应该记住。 有人引用了一个很棒的话:“没有人会放弃2倍;当你有10个人时,这样做很糟糕。” :) Perl v5.22对此有一些性能改进。
如果你一遍又一遍地调用相同的昂贵的方法,但得到相同的答案,像Memoize这样的东西可能适合你。 它是方法调用的代理。 如果它真的是一个函数(意思是说,相同的输入给出相同的输出而没有副作用),你并不需要重复调用它。
诸如Apache :: DBI之类的模块可以重复使用数据库句柄,以避免昂贵的数据库连接打开。 这是非常简单的代码,所以即使你不使用Apache,向内看也可以告诉你如何做到这一点。
Perl不会为你进行尾递归优化,所以不要从Lisp过来,以为你会制作这些超快速的递归算法。 您可以轻松地将这些转换为迭代解决方案(我们在中级Perl中讨论这些问题。
看看你的正则表达式。 许多开放式量词(例如.*
)可能导致很多回溯。 查看Jeffrey Freidl的主持正则表达式,了解所有血腥细节(以及多种语言)。 也检查他的正则表达式网站。
知道你的perl是如何编译的。 你真的需要线程和DDEBUGGING
吗? 这些让你放慢了一点。 查看perlbench实用程序以比较不同的perl二进制文件。
基准您的应用程序针对不同的Perls。 一些较新的版本加快了速度,但也有一些旧版本对于有限的操作集可以更快。 我没有特别的建议,因为我不知道你在做什么。
展开工作。 你可以在其他进程或远程计算机上执行一些异步工作吗? 当别人发现一些子问题时,让你的程序处理其他事情。 Perl有几个异步和负载转移模块。 但要小心,脚手架做好这些事情可能会失去任何好处。
上一篇: How can I speed up my Perl program?
下一篇: Speeding Up Python