use strict; use warnings; use Benchmark qw(cmpthese); srand (1); my @testPaths = map { join '\\', ${['c:', 'd:', 'e:']}[rand 2], map {int rand 100} 0 .. rand 6 } 1 .. 100; cmpthese ( -3, { JDP_c => sub {paths2treeJDP_c (@testPaths)}, JDP => sub {paths2treeJDP (@testPaths)}, GF => sub {paths2TreeGF (@testPaths)}, } ); sub paths2TreeGF { my %pTree; for my $path (@_) { my @parts = split /\\/, $path; my $scan = \%pTree; $scan = $scan->{shift @parts} ||= {} while @parts; } return \%pTree; } sub paths2treeJDP { my $hr = {}; @{$hr}{@_} = map {{}} @_; my $n_repls; do { $n_repls = 0; for (sort {length ($b) <=> length ($a)} keys %$hr) { if (/(.*)\\(.*)/) { $hr->{$1}{$2} = delete $hr->{$_}; $n_repls++; } } } while ($n_repls); $hr } sub paths2treeJDP_c { my $hr = {map {$_ => {}} @_}; my $n_repls; do { $n_repls = 0; for (keys %$hr) { if (/(.*)\\(.*)/) { $hr->{$1}{$2} = delete $hr->{$_}; $n_repls++; } } } while ($n_repls); $hr } #### Rate JDP JDP_c GF JDP 625/s -- -19% -47% JDP_c 773/s 24% -- -34% GF 1175/s 88% 52% --