Perl 数据缓慢::随机
您好,我正在使用模块生成随机日期,但生成100万样本数据的速度非常慢。如何提高它的速度?这是我用过的代码Perl 数据缓慢::随机,perl,Perl,您好,我正在使用模块生成随机日期,但生成100万样本数据的速度非常慢。如何提高它的速度?这是我用过的代码 #!/usr/bin/perl -w use Data::Random qw(:all); my $randDate_Start = '1900-01-01'; my $randDate_End = '2010-12-31'; open Outfile, ">", "D:/Test.txt"; for(0..1000000) { my $randDate = rand
#!/usr/bin/perl -w
use Data::Random qw(:all);
my $randDate_Start = '1900-01-01';
my $randDate_End = '2010-12-31';
open Outfile, ">", "D:/Test.txt";
for(0..1000000)
{
my $randDate = rand_date( min=>$randDate_Start, max=>$randDate_End);
print Outfile $randDate."\n";
}
close Outfile;
有没有其他方法可以生成随机日期我首先展开循环。您可能无法将其展开一百万次,但您可能可以展开大量次,而循环次数要少得多。这将有助于加快它的速度,因为它不必为下一个项目返回分支。我做了一个简短的测试,速度提高了5到10倍。以下是我对100万循环的建议(如果我的数学正确:) 当我这样做的时候,如果我循环一百万次需要107秒,如果我使用上面的方法生成一百万个项目需要28秒
如果这还不够快,那么你可能不得不做一个例行程序来生成日期。考虑到这一范围,将有111年,每年365.25天,这将是40543个日期的范围。可以在开始时生成一次。您可以为时间范围内的每个日期创建一个数组。然后使用rand可以生成一个介于0和40543之间的数字。这将为您提供索引,并将其索引到数组中,以便选择日期。如果以上确实提供了足够的加速,那么这比上面的工作要多一些 使用@Glenn推荐的第二种技术,不进行任何优化
use 5.010;
use strict;
use warnings;
use Date::Calc qw(Delta_Days Add_Delta_Days);
#create an array for each day
my $numdays = Delta_Days(1900,1,1, 2010,12,31) + 1;
my @dates = map { sprintf("%d-%02d-%02d", Add_Delta_Days(1900,1,1, $_)) } 0..$numdays;
say $dates[ rand($numdays) ] for(1..100_000_000);
运行
$ time perl dat | wc -l
100000000
real 0m32.227s
user 0m31.439s
sys 0m1.159s
对于100\u 000\u 000
。一百万等于1.2秒…我建议使用
如以下基准所示,它的性能提高了6倍
如果缓存可能的日期值,则可以得到100万个值的即时结果:
#!/usr/bin/perl -w
use strict;
use warnings;
use autodie;
use Benchmark;
use Data::Random qw(:all);
use Time::Piece;
use Time::Seconds;
my $randDate_Start = '1900-01-01';
my $randDate_End = '2010-12-31';
my $tp_start = Time::Piece->strptime( "$randDate_Start 12:00:00", "%Y-%m-%d %T" );
my $tp_end = Time::Piece->strptime( "$randDate_End 12:00:00", "%Y-%m-%d %T" );
my $tp_days = ( $tp_end - $tp_start )->days;
my @tp_cached = map { ( $tp_start + ONE_DAY * $_ )->strftime('%Y-%m-%d') } ( 0 .. $tp_days );
# Compare Data Methods
timethese(
1_000_000,
{ 'Data::Random' => sub { rand_date( min => $randDate_Start, max => $randDate_End ) },
'Time::Piece' => sub { ( $tp_start + ONE_DAY * int rand $tp_days )->strftime('%Y-%m-%d') },
'Time::Piece (cached)' => sub { $tp_cached[ rand $tp_days ] },
}
);
产出:
Benchmark: timing 1000000 iterations of Data::Random, Time::Piece, Time::Piece (cached)...
Data::Random: 61 wallclock secs (60.20 usr + 0.07 sys = 60.27 CPU) @ 16592.00/s (n=1000000)
Time::Piece: 10 wallclock secs ( 9.95 usr + 0.01 sys = 9.96 CPU) @ 100401.61/s (n=1000000)
Time::Piece (cached): 0 wallclock secs ( 0.08 usr + 0.00 sys = 0.08 CPU) @ 12500000.00/s (n=1000000)
(warning: too few iterations for a reliable count)
生成更少的样本数据?@ialarmedalien:汽车的速度不取决于您行驶的距离,而数据的速度::Random不受您的世代数的影响。@RenéNyffenegger但汽车行驶所需的时间取决于行驶的距离。再说一次,重要的不是目的地,而是旅程。@RenéNyffenegger还有其他方法生成随机日期吗?@lazy-谷歌快速搜索揭示,再加上其他在线选项…谢谢!!!我会尝试你的方法,现在为100万,然后我也要尝试10亿!你能给我例行公事的样品吗?我以前从未听说过…0..1000是1001倍,而不是1000倍您的代码要快得多,因为评估失败了。你说的对,拆开包装是不可能提高速度的。我发现了问题,并更新了代码示例和更新时间。谢谢你指出这一点。在我睡觉之前,我得看着回答问题。
Benchmark: timing 1000000 iterations of Data::Random, Time::Piece, Time::Piece (cached)...
Data::Random: 61 wallclock secs (60.20 usr + 0.07 sys = 60.27 CPU) @ 16592.00/s (n=1000000)
Time::Piece: 10 wallclock secs ( 9.95 usr + 0.01 sys = 9.96 CPU) @ 100401.61/s (n=1000000)
Time::Piece (cached): 0 wallclock secs ( 0.08 usr + 0.00 sys = 0.08 CPU) @ 12500000.00/s (n=1000000)
(warning: too few iterations for a reliable count)