Perl 数据缓慢::随机

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

您好,我正在使用模块生成随机日期,但生成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_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)