近来工作中遇到一个问题:要求把指定目录下的所有C++源文件连接成一个单独的文件。作者写了一个Perl程序来实现这个功能。因为作者一直想了解Perl语言的确切运行效率,所以花了点时间写了相同功能的C程序,比较了一下两者的运行速度。
Perl源程序如下:
#!perl -w
# Usage: fjoin.pl <dir>
# This program print all .cpp/.h files in <dir> to stdout
use 5.010;
use strict;
use warnings;
# Sub: print a file to stdout
# Arguments:
# $_[0] The file name
sub printFile
{
my $success = open FHANDLE, "<", $_[0];
if(! $success)
{
return;
}
while(<FHANDLE>)
{
print $_;
}
close FHANDLE;
}
# The main program
my $dir = $ARGV[0];
my @allFiles;
my $file;
if(!defined($dir))
{
die "Directory not defined";
}
# Iterate all files in the dir
@allFiles = <$dir/*>;
if(! @allFiles)
{
die "Can not open the directory $dir";
}
foreach $file (@allFiles)
{
if($file =~ //.cpp$/)
{
printFile($file);
}
elsif($file =~ //.h$/)
{
printFile($file);
}
}
C源程序较长,我还不知道怎样添加链接,就暂不贴出。
两个程序的大体思路一样:对命令行参数指定的目录中的所有.h和.cpp文件,读出它们的内容,输出到标准输出。两个程序主要的不同是Perl程序读入和输出文件时以行为单位,C程序一次能全部读入源文件内容,一次全部输出到标准输出。
我的测试方法为:对eMule 0.49c的源程序的eMule0.49c-Source/srchybrid目录执行这两个程序,运行5次,取均值比较。因为打印到标准输出较慢,所以我将它们的标准输出重定向到文件。
我使用的硬件平台为:
CPU: Athlon 64 X 2 4800+
RAM: 2GB
软件环境为:
Ubuntu 9.04 for AMD64
Linux 2.6.28-15
gcc 4.3.3
Perl 5.10.0
Glibc 2.9-4ubuntu6.1
C程序的编译选项为:-O2 -fomit-frame-pointer -Wall
运行结果为:
C程序:0.0214秒
Perl程序:0.3726秒
在这个特定情况下,C程序的速度是Perl程序的10倍以上。
当然,这次比较有不公平的地方:Perl程序的输入输出方法不如C程序高效。后续我还将实现与C程序同样算法的Perl程序,再次比较。