綾小路龍之介の素人思考

[perl] 2つの式を評価する場合、andとorとどちらが速い

気になったので調べてみた。結局あまり気にせず人間に優しいコードを書こうと思った。

以下のようなベンチマークを書いてみた。$aと$bは1or0とするとき、$aと$bが両方1であることを評価する。test0, test2, test3 は本質的に同じだと思うけど、test1だけは、$a == 1の評価の結果にかかわらずと$b == 1を評価するので、どんな入力があっても2回評価を行うため遅くなると思われる。

$ cat benchmark_andor.pl
#!/usr/bin/perl -w
use strict;
use warnings;
use Benchmark qw/cmpthese timethese/;

my $count = 10000000;

cmpthese(
                timethese($count,
                        {
                        '0-0-1' => 'test0(0,0);',
                        '0-1-1' => 'test0(0,1);',
                        '0-2-2' => 'test0(1,0);',
                        '0-3-2' => 'test0(1,1);',
                        '1-0-2' => 'test1(0,0);',
                        '1-1-2' => 'test1(0,1);',
                        '1-2-2' => 'test1(1,0);',
                        '1-3-2' => 'test1(1,1);',
                        '2-0-1' => 'test2(0,0);',
                        '2-1-1' => 'test2(0,1);',
                        '2-2-2' => 'test2(1,0);',
                        '2-3-2' => 'test2(1,1);',
                        '3-0-1' => 'test3(0,0);',
                        '3-1-1' => 'test3(0,1);',
                        '3-2-2' => 'test3(1,0);',
                        '3-3-2' => 'test3(1,1);',
                        }
                        )
        );

exit;

sub test0
{
        my $a = shift;
        my $b = shift;
        if ($a != 1 || $b != 1) {
                return 0;
        } else {
                return 1;
        }
}

sub test1
{
        my $a = shift;
        my $b = shift;
        if ($a == 1 && $b == 1) {
                return 1;
        } else {
                return 0;
        }
}

sub test2
{
        my $a = shift;
        my $b = shift;
        if ($a == 1) {
                if ($b == 1) {
                        return 1;
                } else {
                        return 0;
                }
        } else {
                return 0;
        }
}

sub test3
{
        my $a = shift;
        my $b = shift;
        if ($a != 1) {
                return 0;
        } else {
                if ($b != 1) {
                        return 0;
                } else {
                        return 1;
                }
        }
}
__END__
    a a
    0 1
b 0 0 0
b 1 0 1

で結果が以下。X-Y-ZのZは評価する回数、Yは引数のタイプ、Xは評価方法に付けられたラベル。期待される結果はZ=2はZ=1に比べて遅くなるはずだが、そうではない結果が得られている。perlでプロファイラ使うのはどうすりゃいいんだ。

$ perl benchmark_andor.pl
Benchmark: timing 10000000 iterations of 0-0-1, 0-1-1, 0-2-2, 0-3-2, 1-0-2, 1-1-2, 1-2-2, 1-3-2, 2-0-1, 2-1-1, 2-2-2, 2-3-2, 3-0-1, 3-1-1, 3-2-2, 3-3-2...
     0-0-1: 12 wallclock secs ( 6.24 usr +  0.00 sys =  6.24 CPU) @ 1602564.10/s (n=10000000)
     0-1-1: 13 wallclock secs ( 7.07 usr +  0.00 sys =  7.07 CPU) @ 1414427.16/s (n=10000000)
     0-2-2: 13 wallclock secs ( 6.86 usr +  0.00 sys =  6.86 CPU) @ 1457725.95/s (n=10000000)
     0-3-2: 16 wallclock secs ( 8.02 usr +  0.01 sys =  8.03 CPU) @ 1245330.01/s (n=10000000)
     1-0-2: 16 wallclock secs ( 8.48 usr +  0.00 sys =  8.48 CPU) @ 1179245.28/s (n=10000000)
     1-1-2: 16 wallclock secs ( 7.93 usr +  0.00 sys =  7.93 CPU) @ 1261034.05/s (n=10000000)
     1-2-2: 17 wallclock secs ( 7.96 usr +  0.01 sys =  7.97 CPU) @ 1254705.14/s (n=10000000)
     1-3-2: 13 wallclock secs ( 7.00 usr +  0.00 sys =  7.00 CPU) @ 1428571.43/s (n=10000000)
     2-0-1: 15 wallclock secs ( 7.71 usr +  0.01 sys =  7.72 CPU) @ 1295336.79/s (n=10000000)
     2-1-1: 15 wallclock secs ( 7.56 usr +  0.01 sys =  7.57 CPU) @ 1321003.96/s (n=10000000)
     2-2-2: 17 wallclock secs ( 8.14 usr +  0.00 sys =  8.14 CPU) @ 1228501.23/s (n=10000000)
     2-3-2: 17 wallclock secs ( 7.70 usr +  0.00 sys =  7.70 CPU) @ 1298701.30/s (n=10000000)
     3-0-1: 15 wallclock secs ( 6.85 usr +  0.00 sys =  6.85 CPU) @ 1459854.01/s (n=10000000)
     3-1-1: 13 wallclock secs ( 6.48 usr +  0.02 sys =  6.50 CPU) @ 1538461.54/s (n=10000000)
     3-2-2: 18 wallclock secs ( 8.32 usr +  0.00 sys =  8.32 CPU) @ 1201923.08/s (n=10000000)
     3-3-2: 16 wallclock secs ( 8.41 usr +  0.00 sys =  8.41 CPU) @ 1189060.64/s (n=10000000)
           Rate 1-0-2 3-3-2 3-2-2 2-2-2 0-3-2 1-2-2 1-1-2 2-0-1 2-3-2 2-1-1 0-1-1 1-3-2 0-2-2 3-0-1 3-1-1 0-0-1
1-0-2 1179245/s    --   -1%   -2%   -4%   -5%   -6%   -6%   -9%   -9%  -11%  -17%  -17%  -19%  -19%  -23%  -26%
3-3-2 1189061/s    1%    --   -1%   -3%   -5%   -5%   -6%   -8%   -8%  -10%  -16%  -17%  -18%  -19%  -23%  -26%
3-2-2 1201923/s    2%    1%    --   -2%   -3%   -4%   -5%   -7%   -7%   -9%  -15%  -16%  -18%  -18%  -22%  -25%
2-2-2 1228501/s    4%    3%    2%    --   -1%   -2%   -3%   -5%   -5%   -7%  -13%  -14%  -16%  -16%  -20%  -23%
0-3-2 1245330/s    6%    5%    4%    1%    --   -1%   -1%   -4%   -4%   -6%  -12%  -13%  -15%  -15%  -19%  -22%
1-2-2 1254705/s    6%    6%    4%    2%    1%    --   -1%   -3%   -3%   -5%  -11%  -12%  -14%  -14%  -18%  -22%
1-1-2 1261034/s    7%    6%    5%    3%    1%    1%    --   -3%   -3%   -5%  -11%  -12%  -13%  -14%  -18%  -21%
2-0-1 1295337/s   10%    9%    8%    5%    4%    3%    3%    --   -0%   -2%   -8%   -9%  -11%  -11%  -16%  -19%
2-3-2 1298701/s   10%    9%    8%    6%    4%    4%    3%    0%    --   -2%   -8%   -9%  -11%  -11%  -16%  -19%
2-1-1 1321004/s   12%   11%   10%    8%    6%    5%    5%    2%    2%    --   -7%   -8%   -9%  -10%  -14%  -18%
0-1-1 1414427/s   20%   19%   18%   15%   14%   13%   12%    9%    9%    7%    --   -1%   -3%   -3%   -8%  -12%
1-3-2 1428571/s   21%   20%   19%   16%   15%   14%   13%   10%   10%    8%    1%    --   -2%   -2%   -7%  -11%
0-2-2 1457726/s   24%   23%   21%   19%   17%   16%   16%   13%   12%   10%    3%    2%    --   -0%   -5%   -9%
3-0-1 1459854/s   24%   23%   21%   19%   17%   16%   16%   13%   12%   11%    3%    2%    0%    --   -5%   -9%
3-1-1 1538462/s   30%   29%   28%   25%   24%   23%   22%   19%   18%   16%    9%    8%    6%    5%    --   -4%
0-0-1 1602564/s   36%   35%   33%   30%   29%   28%   27%   24%   23%   21%   13%   12%   10%   10%    4%    --

リファレンス

  1. perl 入れ子|ネスト if - Google 検索
  2. 入れ子|ネスト if 速度|スピード - Google 検索
  3. 制御文の条件の書き方と処理速度の関係は?
  4. 4-1 ~分岐処理(1) 基本的な if 文~

ソーシャルブックマーク

  1. はてなブックマーク
  2. Google Bookmarks
  3. del.icio.us

ChangeLog

  1. Posted: 2009-12-13T10:06:06+09:00
  2. Modified: 2009-12-13T10:06:06+09:00
  3. Generated: 2017-01-04T23:09:16+09:00