-
-
Save martinpopel/bea01d8037d6baee01b8825e84e40c41 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
use warnings; | |
use strict; | |
use Carp qw{ confess }; | |
use List::Util qw{ shuffle }; | |
use Test::More tests => 5; | |
use Benchmark qw{ cmpthese }; | |
my @ATTRS; | |
my ( | |
$ORD, $ROOT, $PARENT, $FIRSTCHILD, $NEXTSIBLING, $MISC, # both root and node | |
$FORM, $LEMMA, $UPOS, $XPOS, $FEATS, $DEPREL, $DEPS, # node only | |
); | |
BEGIN { | |
@ATTRS = qw(ord root parent firstchild nextsibling misc | |
form lemma upos xpos feats deprel deps); | |
($ORD, $ROOT, $PARENT, $FIRSTCHILD, $NEXTSIBLING, $MISC) = (0..5); | |
($FORM, $LEMMA, $UPOS, $XPOS, $FEATS, $DEPREL, $DEPS) = (6..12); | |
} | |
my $self = [ 'a'..'z' ]; | |
sub ternary { | |
map { | |
$_ eq 'ord' ? $self->[$ORD] | |
: $_ eq 'form' ? $self->[$FORM] | |
: $_ eq 'lemma' ? $self->[$LEMMA] | |
: $_ eq 'upos' ? $self->[$UPOS] | |
: $_ eq 'xpos' ? $self->[$XPOS] | |
: $_ eq 'feats' ? $self->[$FEATS] | |
: $_ eq 'deprel' ? $self->[$DEPREL] | |
: $_ eq 'deps' ? $self->[$DEPS] | |
: $_ eq 'misc' ? $self->[$MISC] | |
: confess "Unknown attribute '$_'"; | |
} @_; | |
} | |
{ my %h = ( ord => $ORD, | |
form => $FORM, | |
lemma => $LEMMA, | |
upos => $UPOS, | |
xpos => $XPOS, | |
feats => $FEATS, | |
deprel => $DEPREL, | |
deps => $DEPS, | |
misc => $MISC, | |
); | |
sub hash { | |
map {$self->[$h{$_} // confess("Unknown attribute '$_'")]} @_ | |
} | |
} | |
my @values = shuffle qw( ord form lemma upos xpos feats deprel deps misc ); | |
is_deeply [ ternary(@values) ], [ hash(@values) ], 'same values'; | |
my $exception_regex = qr/^Unknown attribute 'x' at/; | |
isnt eval { ternary('x'); 1 }, 1, 'ternary dies'; | |
like $@, $exception_regex, 'ternary exception'; | |
isnt eval { hash('x'); 1 }, 1, 'hash dies'; | |
like $@, $exception_regex, 'hash exception'; | |
cmpthese( -5, | |
{ ternary => sub { ternary(@values) }, | |
hash => sub { hash(@values) }, | |
} | |
); | |
# Rate ternary hash | |
# ternary 142172/s -- -41% | |
# hash 241986/s 70% -- |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The original comparison showed
hash
is 191% faster thanternary
, but it was wrong:ternary
did an extra copy to@values
(it makes the original subroutineget_attrs
more readable when checking undefs; it should be either in bothternary
andhash
or in none).hash
did not access$self
, but unfortunately this bug remained unnoticed because of the special values 0..12 assigned as values (so the values were the same as indices of the attributes).Now,
ternary
is "just" 70% faster. So thanks @choroba for the suggestion, I will update the code.