IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

Benchmark 做 Perl 的性能测试

扶凯 2011-02-06 22:07:03 累计浏览 2,220 次
本机暂存

当我们深入使用 Perl 时,慢慢的写一些重要的应用,又需要占用大量 CPU 时, 我们开始大量的关注程序的性能.因为性能可能会要决定你这个程序的生死.
他是否能在公司的机器上跑,还是沦落到需要被 C 替换的命运,所以这些,我们在程序写完时,对内部结构做一些性能调整就非常有必要了.这时需要使用详细的了解每个部分所占用的 CPU .刚好 Perl 本身有很多不错的模块来帮大家做性能的评定.不然你写完上线才发现性能是如此的糟糕可不行.

先讲最最麻烦的 Benchmark.这是大家最麻烦,也最细的一个性能测试的软件 了.基本有几个基本的子函数的功能我们需要,一个是 timethis 来看基本的性能,如果有几个要对比,可以使用 timethese,cmpthese 是对比一些东西

Benchmark 中的 timethis 功能

基本函数,块的性能对比,这个可以使用 sub 和 eval 之类来做性能的测试。可以看下面的例子,这个 timethis 的第一个参数是运行的次数,如果是负数,就变成了使用的时间,所以我们会更加常用时间来测试(默认为 3 秒).第二个参数是代码块(子函数,eval),比如下面的例子我使用的是测试 foreach 运行 4 秒所占用的 CPU .

#!/usr/bin/perl
use strict;
use Benchmark;
timethis (-4, sub { foreach(1..100){} });

timethis 功能的输出时,主要关注后面的二个部分,可以见到后面的数字 (n=802806) 是指在这 4 秒,对后面这个代码块(子函数,eval)运行的次数,也就是 foreach 1..100 可以做 802806 次。 195806.34/s 是指每秒可以运行 195806.34 次。

timethis for 4: 4 wallclock secs ( 4.10 usr + 0.00 sys = 4.10 CPU) @ 195806.34/s (n=802806)

Benchmark 中的 timethese 功能

上面我们可以见到 timethis 只对放一个代码块,这个地方可以放二个以上的代码块来对比.这样可以方便我们对比多种写法实现同样的功能时,性能最好是其中什么写法。下面是我的示例代码. timethis 参数也是一样,第一个参数是时间,但这个时间是指每个代码块所使用的时间.下面然后我接了二个子函数的块,每个块给了一个名字,方便输出时分析,一个叫 directly 一个叫 indirectly.

#!/usr/bin/perl
use strict;
use Benchmark;
 
timethese (
        -5, 
        {   
        directly    => sub { my $i; for (1 .. 100) { $i += $_ } },
        indirectly  => sub { my $i; for (1 .. 100) { $i =  $_ + $i} },
        }   
 );

下面是 timethese 的输出,我们可以见到,直接使用 $i += $_ 和 $i = $_ + $i;时,是没有性能分别的。基本上非常非常接近.下面的结果也和上面的 thmethis 是一样的.

Benchmark: running directly, indirectly for at least 5 CPU seconds...
directly: 5 wallclock secs ( 5.25 usr + 0.00 sys = 5.25 CPU) @ 73769.71/s (n=387291)
indirectly: 6 wallclock secs ( 5.22 usr + 0.00 sys = 5.22 CPU) @ 74193.68/s (n=387291)

Benchmark 中的 cmpthese 功能

上面的 timethese 是一个加强版的 thmethis 分别是一个只能运行一个块,一个可以多个,但当多个代码块时,我们很难对比输出的结果,这时我们可以看看
cmpthese 的这个函数.
这个基本和上面的程序一样,只变化一个函数就行了.如下,参数什么的也一样.

#!/usr/bin/perl
use strict;
use Benchmark qw(:all);
 
cmpthese (
        -5,
        {
        directly    => sub { my $i; for (1 .. 100) { $i += $_ } },
        indirectly  => sub { my $i; for (1 .. 100) { $i =  $_ + $i} },
        }
 );

容易使用吧.输出也很容易直接就是参数的结果,下面比较容易看出结果吧。这时使用的是 % 来做输出更加方便对比

              Rate indirectly   directly
indirectly 74041/s         --        -5%
directly   77727/s         5%         --

有关一些其它的测试软件(Devel::DProf,Devel::SmallProf, Devel::FastProf),可以看我原来的文章: perl 的调试和性能测试

同分类推荐文章

  1. 等了十年的 Go 链式管道,终于来了:seq 让你像写 Scala 一样写 Go (2026-06-25 18:38:18)
  2. Go 实验特性详解 (2026-06-21 10:05:27)
  3. amd64 微架构级别对 Go 程序性能提升多少? (2026-06-21 09:38:49)

查看更多 后端 文章 →

建议继续学习

  1. 记录一个软中断问题 (累计阅读 16,954)
  2. Go Reflect 性能 (累计阅读 14,155)
  3. perl更新/修改/删除文本文件内容 (累计阅读 10,648)
  4. perl大牛flw传说 (累计阅读 7,714)
  5. AWStats是一个基于Perl的WEB日志分析工具。 (累计阅读 7,174)
  6. perl模块Getopt::Std用法及实例-从命令行读取参数模块 (累计阅读 7,018)
  7. 关于Apache调优点滴 (累计阅读 6,635)
  8. [Perl] Template::Toolkit 模板技术. (累计阅读 6,344)
  9. Perl命令行常见用法及技巧 (累计阅读 5,912)
  10. PHP将死,何以为继? (累计阅读 5,918)