我正在优化一些经常运行的Perl代码(每个文件每天一次)。
评论是否会降低Perl脚本的速度?我的实验倾向于否:
use Benchmark;
timethese(20000000, {
'comments' => '$b=1;
# comment ... (100 times)
', 'nocomments' => '$b=1;'});
给出几乎相同的值(除噪音外)。
Benchmark: timing 10000000 iterations of comments, nocomments...
comments: 1 wallclock secs ( 0.53 usr + 0.00 sys = 0.53 CPU) @ 18832391.71/s (n=10000000)
nocomments: 0 wallclock secs ( 0.44 usr + 0.00 sys = 0.44 CPU) @ 22935779.82/s (n=10000000)
Benchmark: timing 20000000 iterations of comments, nocomments...
comments: 0 wallclock secs ( 0.86 usr + -0.01 sys = 0.84 CPU) @ 23696682.46/s (n=20000000)
nocomments: 1 wallclock secs ( 0.90 usr + 0.00 sys = 0.90 CPU) @ 22099447.51/s (n=20000000)
如果我将评论和无评论版本作为单独的Perl脚本运行,我会得到类似的结果。
这似乎是违反直觉的,如果没有别的,解释器每次都需要将注释读入内存。
答案 0 :(得分:18)
运行时性能?否。
解析和lexing性能?是的,当然。
由于Perl倾向于动态解析和lex,因此注释将影响“启动”性能。
他们会明显地影响它吗?不可能的。
答案 1 :(得分:13)
Perl是一种即时编译语言,因此注释和POD对运行时性能没有影响。
评论和POD对编译时有一个微不足道的影响,但它们对于Perl解析它来说非常容易和快速,几乎不可能测量性能。您可以通过使用-c
标志来编译来自行查看。
在我的Macbook上,一个包含2个语句和1000行70个字符注释的Perl程序需要相同的时间来编译为1000行空注释,只有2个打印语句。确保运行每个基准两次以允许您的操作系统缓存文件,否则您的基准测试是从磁盘读取文件的时间。
如果启动时间对您来说是个问题,那不是因为评论和POD。
答案 2 :(得分:8)
Perl编译脚本然后执行它。注释略微减慢了编译阶段,但对运行阶段没有影响。
答案 3 :(得分:7)
Perl不是一种与shell脚本相同的脚本语言。解释器不会逐行读取文件。 Perl程序的执行在两个基本阶段完成:编译和运行时[1]。在编译阶段,源代码被解析并转换为字节码。在运行时阶段,字节码在虚拟机上执行。
注释会减慢解析阶段,但与解析脚本本身所需的时间相比,差异可以忽略不计(对于大多数程序来说,这已经非常小了)。关于解析时间的唯一时间是在Web服务器环境中,每秒可以多次调用程序。 mod_perl的存在是为了解决这个问题。
您正在使用Benchmark
。非常好!您应该寻找改进算法的方法 - 而不是微优化。 Devel :: DProf可能有助于找到任何热点。绝对不应该在错误的尝试中删除评论,以使您的程序更快。你只会让它无法维护。
[1]这通常被称为“及时”编译。 Perl实际上还有几个阶段,如INIT
和END
,这里无所谓。
答案 4 :(得分:3)
重点是:优化瓶颈。阅读文件包括:
在这些步骤中,阅读是迄今为止最快的部分(我不确定关闭,它是一个系统调用,但你不必等待它完成)。即使它是整个事物的10%(我认为不是这样),然后将它减少一半只能使性能提高5%,但会以错误评论为代价(这是一件非常糟糕的事情)。对于解析器,抛弃以#开头的行不是有形的减速。之后,评论消失了,所以不会放缓。
现在,想象一下你可以通过剥离所有评论来实际上将“阅读脚本”部分提高5%(这是一个非常乐观的估计,见上文)。在脚本的整体时间消耗中“阅读脚本”的份额有多大?当然,取决于它做了多少,但由于perl脚本通常至少读取一个文件,最多只有50%,但由于perl脚本通常会做更多的事情,所以诚实的估计会将其降低到范围内1%。因此,剥离所有评论的预期效率提升 (非常乐观)2.5%,但非常接近0.05%。然后,它实际上提供超过1%的那些已经很快,因为它们几乎什么也没做,所以你再次在错误的点上进行优化。
总结,优化瓶颈。
答案 5 :(得分:2)
在这种情况下,Benchmark模块毫无用处。它只是测量一遍又一遍地运行代码的时间。由于您的代码实际上没有执行任何操作,因此大部分代码都会对其进行优化。这就是为什么你看到它每秒运行2200万次。
我在Mastering Perl几乎完整地讨论过这一章。 Benchmark技术中的测量误差约为7%。你的基准数字在这之内,所以几乎没有区别。
答案 6 :(得分:1)
来自Paul Tomblins的评论:
perl不进行某种即时编译吗?也许这些评论会被提前废弃? -
是Perl的确如此。
它是编译和解释之间的编程语言。代码即时编译然后运行。评论通常没有任何区别。它可能会产生的最大影响是,当它最初逐行解析文件并预先编译它时,您可能会看到纳秒的差异。
答案 7 :(得分:0)
我希望一条评论只能在循环中解析一次,而不是多次,所以我怀疑它是一个有效的测试。
我希望评论会稍微减慢编辑速度,但我认为这样做太小了,不能去除它们。
答案 8 :(得分:0)
Perl评论会减慢脚本速度吗?好吧,解析它,是的。解析后执行它?不。解析脚本的频率是多少?只有一次,所以如果你在for循环中有一个注释,那么注释会在脚本运行之前被解析器丢弃一次,一旦它开始运行,注释就已经消失了(并且脚本不是作为脚本内部存储的Perl),因此无论for循环重复多少次,评论都不会产生影响。解析器跳过评论的速度有多快? Perl评论的方式非常快,因此我怀疑你会注意到。如果您有5行代码,并且每行之间有1条Mio注释行,您会注意到更长的启动时间......但是这样做的可能性有多大以及注释的大小是什么?