Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The problem is Perl can't make some optimization which is common in many compiled programming languages. As <a href="https://stackoverflow.com/users/589924/ikegami">ikegami</a> pointed out, each while cycle you copy data out from hash and you also do many unnecessary hash look-ups. There is some benchmark code you can play around.</p> <pre><code>#!/usr/bin/env perl use 5.10.0; use strict; use warnings; use Benchmark qw(:hireswallclock :all); use Clone qw(clone); my $data = { map +( $_ =&gt; { students =&gt; { map +( $_ =&gt; undef ), 103991 .. 104010 } } ), 1 .. 70000 }; my $college_data_hr; sub sum_time { my $t = shift; $t = timesum( $t, $_ ) for @_; return $t; } sub my_cmp_these { my %bench = @_; my %times; for ( 1 .. 10 ) { push @{ $times{$_} }, do { $college_data_hr = clone($data); timeit( 1, $bench{$_} ); } for keys %bench; } $_ = sum_time(@$_) for values %times; cmpthese( \%times ); } my_cmp_these( orig_while =&gt; sub { while ( my ( $college_code, $college_info_hr ) = each( %{$college_data_hr} ) ) { while ( my ( $student_num, $student_info_hr ) = each( %{ $college_info_hr-&gt;{'students'} } ) ) { if ( $student_num &lt; 104000 ) { ## Delete the info of students before 2004. delete $college_info_hr-&gt;{'students'}{$student_num}; } } } }, new_while =&gt; sub { while ( my ( undef, $college_info_hr ) = each( %{$college_data_hr} ) ) { my $s = $college_info_hr-&gt;{'students'}; while ( my ( $student_num, undef ) = each(%$s) ) { if ( $student_num &lt; 104000 ) { ## Delete the info of students before 2004. delete $s-&gt;{$student_num}; } } } }, orig_foreach =&gt; sub { foreach my $college_code ( keys %$college_data_hr ) { foreach my $student_num ( keys %{ $college_data_hr-&gt;{$college_code}{'students'} } ) { if ( $student_num &lt; 104000 ) { ## Delete the info of students before 2004. delete $college_data_hr-&gt;{$college_code}{'students'} {$student_num}; } } } }, new_foreach =&gt; sub { foreach my $college_info ( values %$college_data_hr ) { my $students = $college_info-&gt;{'students'}; delete @$students{ grep $_ &lt; 104000, keys %$students }; } }, ikegami_foreach =&gt; sub { for my $college_code ( keys %$college_data_hr ) { my $students = $college_data_hr-&gt;{$college_code}{students}; delete @$students{ grep $_ &lt; 104000, keys %$students }; } }, ); </code></pre> <p>Results on mine notebook:</p> <pre><code> s/iter orig_while new_while orig_foreach ikegami_foreach new_foreach orig_while 1.56 -- -25% -31% -35% -40% new_while 1.17 33% -- -8% -14% -21% orig_foreach 1.08 44% 8% -- -6% -14% ikegami_foreach 1.01 54% 16% 7% -- -8% new_foreach 0.927 68% 26% 16% 9% -- </code></pre> <p>Result for <code>248,000</code></p> <pre><code> s/iter orig_while new_while orig_foreach ikegami_foreach new_foreach orig_while 6.19 -- -27% -30% -33% -38% new_while 4.54 36% -- -5% -8% -16% orig_foreach 4.31 44% 5% -- -4% -11% ikegami_foreach 4.16 49% 9% 4% -- -8% new_foreach 3.83 62% 19% 13% 9% -- </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload