【发布时间】:2013-08-01 21:22:02
【问题描述】:
[Strawberry Perl v5.16.3,Windows 7 x64,通过cmd执行,例如c:\strawberry> perl test.pl 100000]
症状:以下代码:foreach (1..$ARGV[0]) { foo($_); },执行速度比我在它之前包含此额外行时慢大约 20%:my $num = $ARGV[0];
问题:谁能帮我理解为什么?
注意,在第二种情况下,在我初始化并设置$num 之后,我不会在循环参数中使用$num。如果是这种情况,我可能会确信在 forloop 中反复测试 $ARGV[0] 会比我自己定义的变量慢...但事实并非如此。
为了跟踪时间,我在脚本顶部使用:use Time::HiRes; my $time = [Time::HiRes::gettimeofday()];,在底部使用:print "\n1: ", Time::HiRes::tv_interval($time);。
困惑!
谢谢,
迈克尔
编辑
我包含了整个脚本,并在违规行之前添加了注释...有趣的是,时间差异似乎至少部分取决于我对 %h 和 @chain 的冗余初始化。 . 这越来越奇怪了。
use Time::HiRes; my $time = [Time::HiRes::gettimeofday()];
#my $max=$ARGV[0];
my %h = (1=>1,89=>89);
$h{1}=1;
$h{89}=89;
my @chain=();
my $ans=0;
sub sum{my $o=0; foreach (@_){$o+=$_}; return $o;}
foreach (1..$ARGV[0]-1){
my $x=$_;
my @chain = ();
while(!exists($h{$x})){
push(@chain,$x);
$x = sum(map {$_**2} split('',$x));
}
foreach (@chain){$h{$_}=$h{$x} if !exists($h{$_});}
}
print "\n1: ", Time::HiRes::tv_interval($time);
foreach (1..$ARGV[0]){$ans++ if ($h{$_}==89);}
print "\n2: ", Time::HiRes::tv_interval($time);
【问题讨论】:
-
无法最终重现。您能否发布完整的基准测试代码和状态 perl 版本/操作系统?
-
感谢您的反馈。帖子已编辑以包含一些信息。仍在尝试包含重要代码而不使我的帖子变得丑陋...
-
您的代码似乎产生了 1E-5 秒(10 微秒)范围内的计时。这对于提供可用的结果来说太小了。此外,您的代码并不清楚您的时间安排。当以足够的迭代次数运行benchmark 时,看不到真正的区别。
-
尝试 100,000 的参数。在未注释该行的情况下,我得到的时间约为 0.83 秒。评论,我得到 1.20 秒。增加了 50%。
-
我添加了一个分析作为答案。收集多个时间后我无法检测到任何差异。如果您可以使用我的工具提供可重现的数据,那么我会非常感兴趣。
标签: performance perl cmd argv