別ファイルに分けるべきか、分けざるべきか
2007年12月27日
手元の環境で調べたところ、PHPコードのパース(JITによるコンパイル)には、平均して一行あたり約2.5μ秒かかっている。一方で、一つのクラスをファイルから呼び出すのに、最低500μ秒が必要。例えば、100行からなるファイルだと、2.5×100+500=750μ秒。現在までに8つほどクラスを作成したが、コードのパースにかかる時間は、ほぼこの計算値と一致している。
どの機能を別のクラスに分けて、どの機能は分けずに同じPHPファイル内に置くかの決断が難しい。別のクラスに分けることで500μ秒のロスがあるわけだから、クラスを分ける場合、このロスを解消できるだけの見返りが必要である。あまり細かくファイルを分けてしまうと、かえってスピードが遅くなってしまう。
L行からなるコードの利用頻度が、P%だと仮定する。このコードを別クラスに分けなかった場合の平均パース時間が、別クラスに分けた場合の平均パース時間より長くなるケースは、
L × 2.5 > ( 500 + L × 2.5 ) × P ÷ 100
を満たす場合である。展開して、
L > 500P ÷ ( 250 - 2.5P )
となる。P値と、クラスを分けた方が良くなる閾値の長さ(L)の関係は、次のテーブルのようになった。
ほとんど使わないケース、例えば使用頻度が0-10%の場合(例えば、管理領域)など、ちょっとしたコードでも別クラスにしたほうが良いことになる。他方で、必ず使用する機能は当然ながら別クラスにするべきではない。その中間、つまり使ったり使わなかったりする場合はこの表をもとに別クラスにするかどうかを決めることにする。例えば、使用頻度が50%の機能については、200行を超える場合に別クラスにするのが良い。
どの機能を別のクラスに分けて、どの機能は分けずに同じPHPファイル内に置くかの決断が難しい。別のクラスに分けることで500μ秒のロスがあるわけだから、クラスを分ける場合、このロスを解消できるだけの見返りが必要である。あまり細かくファイルを分けてしまうと、かえってスピードが遅くなってしまう。
L行からなるコードの利用頻度が、P%だと仮定する。このコードを別クラスに分けなかった場合の平均パース時間が、別クラスに分けた場合の平均パース時間より長くなるケースは、
L × 2.5 > ( 500 + L × 2.5 ) × P ÷ 100
を満たす場合である。展開して、
L > 500P ÷ ( 250 - 2.5P )
となる。P値と、クラスを分けた方が良くなる閾値の長さ(L)の関係は、次のテーブルのようになった。
P(%) | L(行) |
---|---|
0 | 0 |
10 | 22 |
20 | 50 |
30 | 86 |
40 | 133 |
50 | 200 |
60 | 300 |
70 | 467 |
80 | 800 |
90 | 1800 |
100 | ∞ |
ほとんど使わないケース、例えば使用頻度が0-10%の場合(例えば、管理領域)など、ちょっとしたコードでも別クラスにしたほうが良いことになる。他方で、必ず使用する機能は当然ながら別クラスにするべきではない。その中間、つまり使ったり使わなかったりする場合はこの表をもとに別クラスにするかどうかを決めることにする。例えば、使用頻度が50%の機能については、200行を超える場合に別クラスにするのが良い。
コメント
Kat (2007年12月27日 13:50:38)
各クラスのコードをSQLiteのテーブルに挿入し、ここからコードを呼び出してevalする方法でパースしてみたが、結果はほとんど同じであった。