在阅读“Intermediate Perl”这本书时,我注意到有关Schwartzian变换的部分,并尝试了练习中的示例(9.9.2),但注意到多次运行导致该变换比常规排序花费更多的时间。此处的代码根据文件大小对windows\system32目录中的文件执行简单的排序-
#!/usr/bin/perl
use strict;
use warnings;
use Benchmark;
my $time = timethese( 10, {
testA => sub { map $_->[0],
sort {$a->[1] <=> $b->[1]}
map [$_, -s $_],
glob "C:\\Windows\\System32\\*";
},
testB => sub { sort { -s $a <=> -s $b } glob "C:\\Windows\\System32\\*";
},
}
);
输出是-
Benchmark: timing 10 iterations of testA, testB...
testA: 11 wallclock secs ( 1.89 usr + 8.38 sys = 10.27 CPU) @ 0.97/s (n=10)
testB: 5 wallclock secs ( 0.89 usr + 4.11 sys = 5.00 CPU) @ 2.00/s (n=10)
我的理解是,由于需要在testB情况下反复重复文件操作(-s),因此它的运行速度应比testA慢很多。尽管输出与该观察结果有偏差。我在这里想念什么?
最佳答案
对我来说,输出看起来有些不同:
testA: 1 wallclock secs ( 0.16 usr + 0.11 sys = 0.27 CPU) @ 37.04/s (n=10)
(warning: too few iterations for a reliable count)
testB: 0 wallclock secs ( 0.09 usr + 0.02 sys = 0.11 CPU) @ 90.91/s (n=10)
(warning: too few iterations for a reliable count)
用一个不错的迭代值(我选择了100,000)作为基准,我得到以下结果:
testA: 23 wallclock secs (12.15 usr + 10.05 sys = 22.20 CPU) @ 4504.50/s (n=100000)
testB: 11 wallclock secs ( 6.02 usr + 5.57 sys = 11.59 CPU) @ 8628.13/s (n=100000)
看一下代码,我发现这两个子程序可能大部分时间都在遍历文件,所以我这样做了:
my @files = glob "C:\\Windows\\System32\\*";
my $time = timethese( 1_000_000, {
testA => sub {
map $_->[0],
sort {$a->[1] <=> $b->[1]}
map [$_, -s $_],
@files;
},
testB => sub {
sort { -s $a <=> -s $b } @files;
},
}
);
并获得:
testA: 103 wallclock secs (56.93 usr + 45.61 sys = 102.54 CPU) @ 9752.29/s (n=1000000)
testB: -1 wallclock secs ( 0.12 usr + 0.00 sys = 0.12 CPU) @ 8333333.33/s (n=1000000)
(warning: too few iterations for a reliable count)
这里有些腥味,不是吗?
因此,让我们看一下文档:
perldoc -f排序
啊哈!因此,让我们再试一次:
my @files = glob "C:\\Windows\\System32\\*";
my $time = timethese( 100_000, {
testA => sub {
my @arr= map $_->[0],
sort {$a->[1] <=> $b->[1]}
map [$_, -s $_],
@files;
},
testB => sub {
my @arr = sort { -s $a <=> -s $b } @files;
},
}
);
这给了我:
testA: 12 wallclock secs ( 7.44 usr + 4.55 sys = 11.99 CPU) @ 8340.28/s (n=100000)
testB: 34 wallclock secs ( 6.44 usr + 28.30 sys = 34.74 CPU) @ 2878.53/s (n=100000)
所以。回答您的问题:只要您以有意义的方式使用Schwartzian变换,它就会为您提供帮助。当您以有意义的方式进行基准测试时,基准测试将显示此信息。
关于perl - Schwartzian转换何时有用?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/594257/