我找到了一个聪明的技巧来为字符串预分配内存,但是下面的代码片段比没有技巧的情况下表现更差(通过用语句注释掉语句)vec($str, 0x100000, 8)=0;.
use Time::HiRes qw( gettimeofday );
my $big = "a" x 100;
my $str = "";
vec($str, 0x100000, 8)=0;
$ts = getTS();
for ($i=0; $i < 1000000; $i ++) {
$str = "";
for ($j=0; $j<100; $j++) {
$str .= $big;
}
}
printf "took %f secs\n", getTS() - $ts;
sub getTS {
my ($seconds, $microseconds) = gettimeofday;
return $seconds + (0.0+ $microseconds)/1000000.0;
}
Run Code Online (Sandbox Code Playgroud)
凭借巧妙的技巧,它需要9.1秒.如果没有巧妙的技巧,它需要7.8秒.
聪明的技巧应该更快,因为它不需要这么多realloc().知道为什么吗?
我建议你应该避免聪明的伎俩.Perl对字符串内存的处理在十年内得到了极大的改进:它现在按比例将每个字符串预先扩展到其原始大小,并保留在程序重复相同行为时分配的任何内存
通过使用词法变量并避免使用C风格的for循环,您可以从算法中再挤出10%的性能
此外,Time::HiRes已经提供tv_interval了计算两次调用之间的差异gettimeofday
use strict;
use warnings 'all';
use Time::HiRes qw/ gettimeofday tv_interval /;
my $big = 'a' x 100;
my $start = [ gettimeofday ];
for my $i (1 .. 1_000_000 ) {
my $str;
for my $j ( 1 .. 100 ) {
$str .= $big;
}
}
my $end = [ gettimeofday ];
printf "took %.3f secs\n", tv_interval( $start, $end );
Run Code Online (Sandbox Code Playgroud)
took 8.324 secs
Run Code Online (Sandbox Code Playgroud)
顺便提一下,在 ARM处理器上运行Android 7.1.2的Pixel C 平板电脑上运行的相同程序返回21.683秒.我觉得这很不错.
| 归档时间: |
|
| 查看次数: |
105 次 |
| 最近记录: |