sub sms_WxH_Perl_4loops( $m, $w, $h ) { my ( $W, $H ) = ( scalar $m-> [0]-> @*, scalar @$m ); my @ret; for my $i ( 0 .. $H - $h ) { for my $j ( 0 .. $W - $w ) { for my $k ( 0 .. $w - 1 ) { for my $l ( 0 .. $h - 1 ) { $ret[ $i ][ $j ] += $m-> [ $i + $l ][ $j + $k ]; } } } } return \@ret } sub sms_WxH_Perl_3loops( $m, $w, $h ) { my ( $W, $H ) = ( scalar $m-> [0]-> @*, scalar @$m ); my ( @tmp, @ret ); for my $i ( 0 .. $H - 1 ) { for my $j ( 0 .. $W - $w ) { for my $k ( 0 .. $w - 1 ) { $tmp[ $i ][ $j ] += $m-> [ $i ][ $j + $k ]; } next if $i < $h - 1; for my $k ( 0 .. $h - 1 ) { $ret[ $i - $h + 1 ][ $j ] += $tmp[ $i - $k ][ $j ]; } } } return \@ret } $m = [ map [ map rand, 0 .. 149 ], 0 .. 149 ]; __END__ + Time (s) vs. N (NxN submatrix, 150x150 matrix) +----------------------------------------------------------+ |+ + + + + + + + | 10 |-+ +-| |+ +| |+ +| |+ A A A A +| |+ A A +| |+ A A +| | A A | | | 1 |-+ A +-| |+ A +| |+ +| |+ +| |+ A +| | A | |+ +| | B B B B B B | 0.1 |-+ B B B +-| |+ B +| |+ B B +| |+ B +| |+ +| | | |+ B +| | | 0.01 |-+ +-| |+ + + + + + + + +| +----------------------------------------------------------+ 0 20 40 60 80 100 120 140 sms_WxH_Perl_4loops A sms_WxH_Perl_3loops B +-----+-------+-------+ | N | A | B | +-----+-------+-------+ | 10 | 0.250 | 0.053 | | 20 | 0.809 | 0.091 | | 30 | 1.528 | 0.116 | | 40 | 2.288 | 0.134 | | 50 | 2.988 | 0.144 | | 60 | 3.512 | 0.147 | | 70 | 3.828 | 0.144 | | 80 | 3.862 | 0.134 | | 90 | 3.628 | 0.122 | | 100 | 3.122 | 0.103 | | 110 | 2.453 | 0.088 | | 120 | 1.675 | 0.066 | | 130 | 0.900 | 0.044 | | 140 | 0.284 | 0.022 | +-----+-------+-------+