for(;;)とforeach()とLoop unrollingと
YappoLogs: CPUの気持ちは大事だけど、VMの気持ちも考えようよ
http://d.hatena.ne.jp/yappo/20090330/1238360153
会議中なので-MO=Consiseしてないし特に言いたいことはない。
use strict; use warnings; use Benchmark qw(:all); cmpthese( timethese( 0, { loop_for => sub { my $sum = 0; for (my $i = 0; $i < 100; $i++) { $sum = $sum + $i; } }, loop_foreach => sub { my $sum = 0; for my $i (0 .. 99) { $sum = $sum + $i; } }, loop_unrolling_5 => sub { my $sum = 0; for (my $i = 0; $i < 100; $i += 5) { $sum = $sum + $i + 0; $sum = $sum + $i + 1; $sum = $sum + $i + 2; $sum = $sum + $i + 3; $sum = $sum + $i + 4; } }, loop_unrolling_10 => sub { my $sum = 0; for (my $i = 0; $i < 100; $i += 10) { $sum = $sum + $i + 0; $sum = $sum + $i + 1; $sum = $sum + $i + 2; $sum = $sum + $i + 3; $sum = $sum + $i + 4; $sum = $sum + $i + 5; $sum = $sum + $i + 6; $sum = $sum + $i + 7; $sum = $sum + $i + 8; $sum = $sum + $i + 9; } }, loop_unrolling_50 => sub { my $sum = 0; for (my $i = 0; $i < 100; $i += 50) { $sum = $sum + $i + 0; $sum = $sum + $i + 1; $sum = $sum + $i + 2; $sum = $sum + $i + 3; $sum = $sum + $i + 4; $sum = $sum + $i + 5; $sum = $sum + $i + 6; $sum = $sum + $i + 7; $sum = $sum + $i + 8; $sum = $sum + $i + 9; $sum = $sum + $i + 10; $sum = $sum + $i + 11; $sum = $sum + $i + 12; $sum = $sum + $i + 13; $sum = $sum + $i + 14; $sum = $sum + $i + 15; $sum = $sum + $i + 16; $sum = $sum + $i + 17; $sum = $sum + $i + 18; $sum = $sum + $i + 19; $sum = $sum + $i + 20; $sum = $sum + $i + 21; $sum = $sum + $i + 22; $sum = $sum + $i + 23; $sum = $sum + $i + 24; $sum = $sum + $i + 25; $sum = $sum + $i + 26; $sum = $sum + $i + 27; $sum = $sum + $i + 28; $sum = $sum + $i + 29; $sum = $sum + $i + 30; $sum = $sum + $i + 31; $sum = $sum + $i + 32; $sum = $sum + $i + 33; $sum = $sum + $i + 34; $sum = $sum + $i + 35; $sum = $sum + $i + 36; $sum = $sum + $i + 37; $sum = $sum + $i + 38; $sum = $sum + $i + 39; $sum = $sum + $i + 40; $sum = $sum + $i + 41; $sum = $sum + $i + 42; $sum = $sum + $i + 43; $sum = $sum + $i + 44; $sum = $sum + $i + 45; $sum = $sum + $i + 46; $sum = $sum + $i + 47; $sum = $sum + $i + 48; $sum = $sum + $i + 49; } }, loop_unrolling_100 => sub { my $sum = 0; for (my $i = 0; $i < 100; $i += 100) { $sum = $sum + $i + 0; $sum = $sum + $i + 1; $sum = $sum + $i + 2; $sum = $sum + $i + 3; $sum = $sum + $i + 4; $sum = $sum + $i + 5; $sum = $sum + $i + 6; $sum = $sum + $i + 7; $sum = $sum + $i + 8; $sum = $sum + $i + 9; $sum = $sum + $i + 10; $sum = $sum + $i + 11; $sum = $sum + $i + 12; $sum = $sum + $i + 13; $sum = $sum + $i + 14; $sum = $sum + $i + 15; $sum = $sum + $i + 16; $sum = $sum + $i + 17; $sum = $sum + $i + 18; $sum = $sum + $i + 19; $sum = $sum + $i + 20; $sum = $sum + $i + 21; $sum = $sum + $i + 22; $sum = $sum + $i + 23; $sum = $sum + $i + 24; $sum = $sum + $i + 25; $sum = $sum + $i + 26; $sum = $sum + $i + 27; $sum = $sum + $i + 28; $sum = $sum + $i + 29; $sum = $sum + $i + 30; $sum = $sum + $i + 31; $sum = $sum + $i + 32; $sum = $sum + $i + 33; $sum = $sum + $i + 34; $sum = $sum + $i + 35; $sum = $sum + $i + 36; $sum = $sum + $i + 37; $sum = $sum + $i + 38; $sum = $sum + $i + 39; $sum = $sum + $i + 40; $sum = $sum + $i + 41; $sum = $sum + $i + 42; $sum = $sum + $i + 43; $sum = $sum + $i + 44; $sum = $sum + $i + 45; $sum = $sum + $i + 46; $sum = $sum + $i + 47; $sum = $sum + $i + 48; $sum = $sum + $i + 49; $sum = $sum + $i + 50; $sum = $sum + $i + 51; $sum = $sum + $i + 52; $sum = $sum + $i + 53; $sum = $sum + $i + 54; $sum = $sum + $i + 55; $sum = $sum + $i + 56; $sum = $sum + $i + 57; $sum = $sum + $i + 58; $sum = $sum + $i + 59; $sum = $sum + $i + 60; $sum = $sum + $i + 61; $sum = $sum + $i + 62; $sum = $sum + $i + 63; $sum = $sum + $i + 64; $sum = $sum + $i + 65; $sum = $sum + $i + 66; $sum = $sum + $i + 67; $sum = $sum + $i + 68; $sum = $sum + $i + 69; $sum = $sum + $i + 70; $sum = $sum + $i + 71; $sum = $sum + $i + 72; $sum = $sum + $i + 73; $sum = $sum + $i + 74; $sum = $sum + $i + 75; $sum = $sum + $i + 76; $sum = $sum + $i + 77; $sum = $sum + $i + 78; $sum = $sum + $i + 79; $sum = $sum + $i + 80; $sum = $sum + $i + 81; $sum = $sum + $i + 82; $sum = $sum + $i + 83; $sum = $sum + $i + 84; $sum = $sum + $i + 85; $sum = $sum + $i + 86; $sum = $sum + $i + 87; $sum = $sum + $i + 88; $sum = $sum + $i + 89; $sum = $sum + $i + 90; $sum = $sum + $i + 91; $sum = $sum + $i + 92; $sum = $sum + $i + 93; $sum = $sum + $i + 94; $sum = $sum + $i + 95; $sum = $sum + $i + 96; $sum = $sum + $i + 97; $sum = $sum + $i + 98; $sum = $sum + $i + 99; } }, noloop => sub { my $sum = 0; $sum = $sum + 0; $sum = $sum + 1; $sum = $sum + 2; $sum = $sum + 3; $sum = $sum + 4; $sum = $sum + 5; $sum = $sum + 6; $sum = $sum + 7; $sum = $sum + 8; $sum = $sum + 9; $sum = $sum + 10; $sum = $sum + 11; $sum = $sum + 12; $sum = $sum + 13; $sum = $sum + 14; $sum = $sum + 15; $sum = $sum + 16; $sum = $sum + 17; $sum = $sum + 18; $sum = $sum + 19; $sum = $sum + 20; $sum = $sum + 21; $sum = $sum + 22; $sum = $sum + 23; $sum = $sum + 24; $sum = $sum + 25; $sum = $sum + 26; $sum = $sum + 27; $sum = $sum + 28; $sum = $sum + 29; $sum = $sum + 30; $sum = $sum + 31; $sum = $sum + 32; $sum = $sum + 33; $sum = $sum + 34; $sum = $sum + 35; $sum = $sum + 36; $sum = $sum + 37; $sum = $sum + 38; $sum = $sum + 39; $sum = $sum + 40; $sum = $sum + 41; $sum = $sum + 42; $sum = $sum + 43; $sum = $sum + 44; $sum = $sum + 45; $sum = $sum + 46; $sum = $sum + 47; $sum = $sum + 48; $sum = $sum + 49; $sum = $sum + 50; $sum = $sum + 51; $sum = $sum + 52; $sum = $sum + 53; $sum = $sum + 54; $sum = $sum + 55; $sum = $sum + 56; $sum = $sum + 57; $sum = $sum + 58; $sum = $sum + 59; $sum = $sum + 60; $sum = $sum + 61; $sum = $sum + 62; $sum = $sum + 63; $sum = $sum + 64; $sum = $sum + 65; $sum = $sum + 66; $sum = $sum + 67; $sum = $sum + 68; $sum = $sum + 69; $sum = $sum + 70; $sum = $sum + 71; $sum = $sum + 72; $sum = $sum + 73; $sum = $sum + 74; $sum = $sum + 75; $sum = $sum + 76; $sum = $sum + 77; $sum = $sum + 78; $sum = $sum + 79; $sum = $sum + 80; $sum = $sum + 81; $sum = $sum + 82; $sum = $sum + 83; $sum = $sum + 84; $sum = $sum + 85; $sum = $sum + 86; $sum = $sum + 87; $sum = $sum + 88; $sum = $sum + 89; $sum = $sum + 90; $sum = $sum + 91; $sum = $sum + 92; $sum = $sum + 93; $sum = $sum + 94; $sum = $sum + 95; $sum = $sum + 96; $sum = $sum + 97; $sum = $sum + 98; $sum = $sum + 99; } } ) );
Benchmark: running loop_for, loop_foreach, loop_unrolling_10, loop_unrolling_100, loop_unrolling_5, loop_unrolling_50, noloop for at least 3 CPU seconds... loop_for: 3 wallclock secs ( 3.16 usr + 0.00 sys = 3.16 CPU) @ 41487.34/s (n=131100) loop_foreach: 3 wallclock secs ( 3.17 usr + 0.00 sys = 3.17 CPU) @ 53420.19/s (n=169342) loop_unrolling_10: 3 wallclock secs ( 3.14 usr + 0.00 sys = 3.14 CPU) @ 42575.48/s (n=133687) loop_unrolling_100: 4 wallclock secs ( 3.14 usr + 0.00 sys = 3.14 CPU) @ 43949.04/s (n=138000) loop_unrolling_5: 3 wallclock secs ( 3.09 usr + 0.00 sys = 3.09 CPU) @ 37364.72/s (n=115457) loop_unrolling_50: 3 wallclock secs ( 3.13 usr + 0.00 sys = 3.13 CPU) @ 44089.46/s (n=138000) noloop: 4 wallclock secs ( 3.21 usr + 0.00 sys = 3.21 CPU) @ 96098.44/s (n=308476) Rate loop_unrolling_5 loop_for loop_unrolling_10 loop_unrolling_100 loop_unrolling_50 loop_foreach noloop loop_unrolling_5 37365/s -- -10% -12% -15% -15% -30% -61% loop_for 41487/s 11% -- -3% -6% -6% -22% -57% loop_unrolling_10 42575/s 14% 3% -- -3% -3% -20% -56% loop_unrolling_100 43949/s 18% 6% 3% -- -0% -18% -54% loop_unrolling_50 44089/s 18% 6% 4% 0% -- -17% -54% loop_foreach 53420/s 43% 29% 25% 22% 21% -- -44% noloop 96098/s 157% 132% 126% 119% 118% 80% --