Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl -w
- #
- # Benchmarking various parsing methods for my specific case of parsing
- # format YYYY-MM-DD HH24:MI:SS.FF (like 2014-01-29 15:23:22.721485)
- use strict;
- use feature 'state';
- use DateTime::Format::Strptime;
- use DateTime::Format::Natural;
- use DateTime::Format::DateParse;
- use DateTime::Format::Builder;
- use DateTime::Format::Oracle;
- use DateTime::Format::Pg;
- use DateTime::Format::ISO8601;
- use DateTime::Format::Flexible;
- use Benchmark qw(cmpthese);
- my $value = '2014-01-29 15:23:22.721485';
- sub _create_builder {
- my $parser = DateTime::Format::Builder->new();
- $parser->parser(
- length => 26,
- params => [ qw( year month day hour minute second nanosecond ) ],
- regex => qr/^(\d\d\d\d)-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)\.(\d{6})$/,
- postprocess => sub {
- my %args = @_;
- $args{parsed}{nanosecond} *= 1000;
- return 1;
- },
- );
- return $parser;
- };
- sub _create_builder_alt {
- my $parser = DateTime::Format::Builder->new();
- $parser->parser(
- params => [ qw( year month day hour minute second nanosecond ) ],
- regex => qr/^(\d{4})-(\d\d?)-(\d\d?)(?: (\d\d?):(\d\d?):(\d\d?)(?:\.(\d+))?)?$/,
- postprocess => sub {
- my %args = @_;
- my $nano = $args{parsed}{nanosecond};
- $args{parsed}{nanosecond} = $nano . '0' x (9 - length($nano));
- return 1;
- },
- );
- return $parser;
- };
- our %parsers = (
- 'strptime' => sub {
- state $parser = DateTime::Format::Strptime->new(
- pattern => '%F %T.%N',
- locale => 'C',
- time_zone => 'Europe/Warsaw',
- on_error => 'croak',
- );
- return $parser->parse_datetime(@_);
- },
- 'natural' => sub {
- state $parser = DateTime::Format::Natural->new(
- format => 'yyyy-mm-dd',
- prefer_future => 0,
- time_zone => 'floating',
- );
- return $parser->parse_datetime(@_);
- },
- 'dateparse' => sub {
- return DateTime::Format::DateParse->parse_datetime(@_);
- },
- 'oracle' => sub {
- BEGIN{ $ENV{'NLS_DATE_FORMAT'} = 'YYYY-MM-DD'; };
- BEGIN{ $ENV{'NLS_TIMESTAMP_FORMAT'} = 'YYYY-MM-DD HH24:MI:SS.FF'; };
- return DateTime::Format::Oracle->parse_timestamp(@_); # parse_datetime
- },
- 'pg' => sub {
- return DateTime::Format::Pg->parse_datetime(@_);
- },
- 'iso8601' => sub {
- #return DateTime::Format::ISO8601->parse_datetime(@_);
- my $item = shift;
- $item =~ s/ /T/;
- return DateTime::Format::ISO8601->parse_datetime($item);
- },
- 'flexible' => sub {
- DateTime::Format::Flexible->parse_datetime(@_);
- },
- 'builder_f' => sub {
- state $parser = _create_builder();
- return $parser->parse_datetime(@_);
- },
- 'builder_l' => sub {
- state $parser = _create_builder_alt();
- return $parser->parse_datetime(@_);
- },
- );
- ###########################################################################
- # Rozbiegówka
- ###########################################################################
- our %valid;
- my $printer = DateTime::Format::Strptime->new(pattern => '%F %T.%N', locale => 'C');
- foreach my $name (sort keys %parsers) {
- my $parser = $parsers{$name};
- my $obj;
- eval {
- $obj = $parser->($value);
- }; if($@) {
- $@ =~ s/at datetime_parsing_benchmark\.pl line \d+.*//s;
- printf "%10s: [invalid] %s\n", $name, "failed to parse: $@";
- next;
- }
- my $is_valid = $obj->year == 2014
- && $obj->month == 1
- && $obj->day == 29
- && $obj->hour == 15
- && $obj->minute == 23
- && $obj->second == 22
- && $obj->nanosecond == 721485000;
- printf "%10s: [%7s] %s\n", $name, $is_valid ? "ok" : "wrong", $printer->format_datetime($obj);
- if($is_valid) {
- $valid{$name} = 1;
- }
- }
- ###########################################################################
- # Właściwy benchmark
- ###########################################################################
- print "Spawning benchmark\n";
- my %compared;
- #foreach my $name (keys %valid) {
- foreach my $name (keys %parsers) {
- my $parser = $parsers{$name};
- my @values = (
- '2014-01-29 15:23:22.721485',
- '2013-11-09 05:23:22.121385',
- '2013-03-01 15:02:44.000000',
- '2013-12-06 18:18:35.317669',
- );
- unless($valid{$name}) {
- $name .= "[bad]";
- }
- $compared{$name} = sub {
- my @parsed = map { $parser->($_) } @values;
- @parsed = ();
- };
- }
- cmpthese(1000, \%compared);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement