Created
May 9, 2012 09:55
-
-
Save gypark/2643462 to your computer and use it in GitHub Desktop.
substr과 재귀호출 vs 정규표현식 벤치마크
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/env perl | |
use strict; | |
use warnings; | |
use Benchmark qw/:all/; | |
# 입력 (A,(B,(D,(d,_,_),_),(E,_,_)),(C,(F,_,(f,_,_)),(G,(g,_,_),_))) | |
# 위 입력을 받아 A를 root로 하는 트리 구조를 구성 | |
# | |
# G | |
# g | |
# C | |
# f | |
# F | |
# A | |
# E | |
# B | |
# D | |
# d | |
# | |
# construct_node_recursive | |
# substr()과 재귀호출을 써서 스트링을 앞에서부터 읽어나가며 구성 | |
# | |
# construct_node_regexp | |
# 정규표현식으로 (A,_,_) 형태를 읽고 노드를 만들고 배열에 저장한 후 | |
# 스트링의 그 자리를 배열 인덱스로 치환하는 과정을 반복 | |
# 트리 출력용 | |
sub print_tree { #{{{ | |
my ($p, $c) = @_; | |
if ( not defined $p ) { | |
return; | |
} | |
print_tree( $p->{right}, $c + 3 ); | |
print " "x$c, $p->{data}, "\n"; | |
print_tree( $p->{left}, $c + 3 ); | |
return; | |
} #}}} | |
sub construct_node_recursive { #{{{ | |
my $s = shift; | |
my $i = 0; | |
if ( substr($s, $i, 1) ne "(" ) { | |
die "error 1: [" . substr($s, $i, 1). "]"; | |
} | |
$i += 1; | |
my $node = { | |
data => substr($s, $i, 1), | |
left => undef, | |
right => undef, | |
}; | |
$i += 2; | |
if ( substr($s, $i, 1) ne "_" ) { | |
( $node->{left}, my $i_inc ) = construct_node_recursive( substr($s, $i) ); | |
$i += $i_inc; | |
} | |
$i += 2; | |
if ( substr($s, $i, 1) ne "_" ) { | |
( $node->{right}, my $i_inc ) = construct_node_recursive( substr($s, $i) ); | |
$i += $i_inc; | |
} | |
$i += 1; | |
if ( substr($s, $i, 1) ne ")" ) { | |
die "error 2: [" . substr($s, $i, 1). "]"; | |
} | |
return ( $node, $i ); | |
} #}}} | |
sub construct_node_regexp { #{{{ | |
my $str = shift; | |
my @nodes = (); | |
my $make_node = sub { | |
my ( $data, $left, $right ) = @_; | |
my $node = { data => $data }; | |
$node->{left} = $left eq "_" ? undef : $nodes[$left]; | |
$node->{right} = $right eq "_" ? undef : $nodes[$right]; | |
push @nodes, $node; | |
return $#nodes; | |
}; | |
while ( $str =~ s/\( | |
(\w) | |
, | |
(_|\d+) | |
, | |
(_|\d+) | |
\)/$make_node->($1, $2, $3)/xge ) { } | |
return $nodes[$str]; | |
} #}}} | |
sub main { | |
my $str = "(A,_,_)"; | |
$str = "(A,(B,_,_),_)"; | |
$str = "(A,_,(C,_,_))"; | |
$str = "(A,(B,_,_),(C,_,_))"; | |
$str = "(A,(B,(D,(d,_,_),_),(E,_,_)),(C,(F,_,(f,_,_)),(G,(g,_,_),_)))"; | |
my $root = undef; | |
($root) = construct_node_recursive( $str ); | |
print_tree($root, 0); | |
print "-"x30, "\n"; | |
($root) = construct_node_regexp( $str ); | |
print_tree($root, 0); | |
} | |
main(); | |
# 벤치마크 | |
my $str = "(A,(B,(D,(d,_,_),_),(E,_,_)),(C,(F,_,(f,_,_)),(G,(g,_,_),_)))"; | |
cmpthese( | |
timethese( -5, { | |
recursive => sub { construct_node_recursive( $str ) }, | |
regexp => sub { construct_node_regexp( $str ) }, | |
} | |
) | |
); |
Author
gypark
commented
May 9, 2012
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment