IF文を制する者はBASICを制す
PART 4 IF文の簡略化(応用編)
PART2の方法では条件式が1つの場合でしか高速化できないですが、IF文において複数の条件式を使って判定することはよくあります。そのためANDやORを使い複数の条件式で判定する場合の方法も書いておきます。
まずはANDを使用時から考えます。
IF A=1 AND B=2 THEN 30
IF文においてIF(条件式1)AND(条件式2)THEN(実行文)はIF(条件式1)IF(条件式2)THEN(実行文)のように2つのIF文に分けて判断が可能であるため上記のIF文は次のように変形できます。
IF A=1 IF B=2 THEN 30
このようにIF文1つあたり条件式を1つの状態にすればPART2の高速化テクニックを使うことが可能になります。しかし、ここで問題となるのがELSEの扱いです。次のように条件式が不成立の時には50行にジャンプする場合はどうなるでしょうか。
IF A=1 AND B=2 THEN 30 ELSE 50
A=1、B=2のどちらか一方もしくは両方が不成立の場合に50行にジャンプするのでIF文が2つに増えた分だけELSEも2つに増やさなくてはいけません。
IF A=1 IF B=2 THEN 30 ELSE 50 ELSE 50
1つめのELSEがIF B=2〜に対応しており、2つ目のELSE(行末の方)が最初のIF A=1〜に対応しています。このようにELSEはIF文と1対1で対応しておりこれはIF文が何個に増えても変わりません。
では、このIF文においてPART2の高速化を行ってみます。
IF A-1 THEN 50 ELSE IF B-2 THEN 50 ELSE 30
THEN以下とELSE以下が入れ替わるためどちらのELSEがどちらのIFに対応していないとこの変形は難しいですが、慣れればそんなに難しいことではありません。IFを2つに分けるメリットはANDでは両方が成立しているかを判断しなくてはならないのに対して最初のIF文が不成立であれば2つ目は成立しているかどうかの判断が要らないため高速化が期待できるということです。そのため、1つ目の条件式は成立する確率の低いものを持ってくることでより高速化ができます。
この条件式が成立する確率を変えた場合にかかる処理時間を計測したら下記のようになりました。
| 両方成立 | 両方不成立 | A=1が10% (※) B=2が50%で成立 | A=1が50% (※) B=2が10%で成立 |
ANDを使用 | 7.5m秒 | 7.4m秒 | 7.4m秒 | 7.4m秒 |
IF文を2つ使用 | 6.0m秒 | 3.4m秒 | 3.6m秒 | 4.6m秒 |
IF文2つ+高速化使用 | 6.1m秒 | 2.7m秒 | 3.0m秒 | 4.4m秒 |
(※)確率から計算した期待値ではなく指定確率の乱数を発生させてそれを元に実際に判定しそれにかかった時間を計測した
この計測結果を見ればIF文を2つに分割することによる高速化の効果は分かると思います。
次にORを使用時について考えます。
IF A=1 OR B=2 THEN 30 ELSE 50
こちらもANDと同じように2つのIF文に分けてみます。
IF A=1 THEN 30 ELSE IF B=2 THEN 30 ELSE 50
これからさらにPART2の高速化を使用してみます。
IF A-1 IF B-2 THEN 50 ELSE 30 ELSE 30
こちらも条件式が成立する確率を変えて処理時間を計測してみました。
| 両方成立 | 両方不成立 | A=1が10% B=2が50%で成立 | A=1が50% B=2が10%で成立 |
ORを使用 | 7.5m秒 | 7.4m秒 | 7.4m秒 | 7.4m秒 |
IF文を2つ使用 | 3.3m秒 | 6.6m秒 | 5.9m秒 | 4.6m秒 |
IF文2つ+高速化使用 | 3.0m秒 | 5.2m秒 | 5.3m秒 | 4.5m秒 |
ORの方はANDとは異なり片方だけ成立した時点でTHEN以下を実行できるためにIF文2つに分ける場合には1つ目のIF文に成立する確率が高いものを持ってきた方が高速化できます。
ANDやORを用いて複数の条件式をIF文で判断する場合には条件式を分割しIF文を2つ使用することで一見処理が遅くなるようなイメージを受けますが、IF自体の処理がANDやORよりも速い上に条件式が複数ある場合は片方だけを判断した時点で2つ目の条件式を判断する必要が無いことが多々あるため高速化が期待できるわけです。
とはいえ、ANDは両方の条件式が成立する場合、ORは両方の条件式が不成立の場合にIFを2回実行することになり高速化の効果は低くなってしまいます。そういう確率が低ければ上記の計測結果を見ても平均的には高速化が期待できます。あくまで上記の計測結果はあらかじめ設定された確率を元に考えているのでさらに速くなる場合もあります。
要は高速化を行おうとするならば条件式が成立する確率をあらかじめ把握しておくことが重要になるということです。PART3では論理式との比較でIF文が速くなる確率を考えましたが、ANDやORを使用した条件式を複数のIF文に分割する場合でもそれは非常に重要になってきます。全く同じ条件であっても1m秒以上処理時間が変わってくる場合があるというのが上記計測結果からもいえるからです。2つの条件式を判定する場合、上記のようにANDの場合は成立する確率が低い方、ORの場合は成立する確率が高い方を1つめに持ってくることで速度面で有利となります。
今回の方法を用いれば条件式の数はいくつになっても変形は可能になるのですが、条件式の数の分だけTHEN以下が複数に分かれてしまいリストが長くなるというデメリットがあるためににメインルーチン内の本当に高速処理が求められる部分のみで使うことを薦めます。ただ、このような条件式が成立する確率を考慮した高速化は応用の範囲が広いのでデメリットがない場合は積極的に使用していくべきだと思います。
PART5に続く
PART 1 IF〜THEN〜の動作の基本について
PART 2 条件式の簡略化(基本編)
PART 3 IF文は論理式よりも速い!?
PART 4 IF文の簡略化(応用編)
PART 5 IF文の簡略化(実戦編)
PART 6 IF文を制するには・・・
RETURN