评论会影响Perl的性能吗?

时间:2008-11-06 19:59:40

标签: performance perl comments

我正在优化一些经常运行的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脚本运行,我会得到类似的结果。

这似乎是违反直觉的,如果没有别的,解释器每次都需要将注释读入内存。

9 个答案:

答案 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实际上还有几个阶段,如INITEND,这里无所谓。

答案 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注释行,您会注意到更长的启动时间......但是这样做的可能性有多大以及注释的大小是什么?