Psyco は 任意の Python コードを高速化する。
The Ultimate Psyco Guide の読書メモです。
2006年9月の時点で、Psyco は以下を要求する。
Psyco は OS が何であるかに依存しない。
Debian 的には python-psyco/python-psyco-doc パッケージをインスコするだけ
俺には関係ないからトバす
import psyco psyco.full()
アプリケーションの初期化(モジュールのインポートとか、大域定数の初期化)が重いプログラムでは、初期化終了に上のコードを置くのがよい。こういった初期化作業を通常 Psyco は高速化しない。
psyco モジュールをロードするコードを置くのによい場所は __main__
パートで次のようにするのを推奨。
if __name__ == '__main__': # Import Psyco if available try: import psyco psyco.full() except ImportError: pass # ...your code here...
大きなプログラムではプロファイラを使うのがよい。
import psyco psyco.profile()
次のようにすれば、プロファイラのログを script_name.log-psyco に出力する。
import psyco psyco.log() psyco.profile()
さらに、psyco.profile() に 0.0 - 1.0 の数値を引数(watermark という) として与えればれば、 計算機時間を 20% 喰う関数をコンパイルする。ここの所が
import psyco psyco.log() psyco.profile(0.2)
次の例は、以下のように指定している
import psyco psyco.log() psyco.full(memory=100) psyco.profile(0.05, memory=100) psyco.profile(0.2)
特定の関数をコンパイル指定する時は次のようにする
import psyco psyco.bind(myfunction1) psyco.bind(myfunction2)
次のように、指定した関数の元の関数と、コンパイルされた奴(proxy) を共存させることができる
import psyco g = psyco.proxy(f) g(args) # Psyco-accelerated call f(args) # regular slow call
Psyco による高速化を zope のテンプレートランゲージである、TAL で検証する。
tal は、HTML の拡張で、動的に HTML を生成するものである。
実験は Zope 2 の TAL.markbench.py を買って、On a Dual Pentium Linux running Python 2.2.2, using the Zope 2.6.1 で行なった。
テストケース #09 に注目して欲しい
数値が小さい程、高速である。
psyco を使わない完全にインタプリタによる実行。
##: ZPT TAL DTML 01: 0 0 0 02: 0 0 0 03: 2 1 0 04: 9 6 3 05: 16 12 4 06: 19 13 10 07: 15 10 1 08: 10 7 1 09: ------ 123 ------- 90 ------- 32 10: 14 6 3 11: 28 18 10 12: 20 15 6
以下のコードを追加して、全部コンパイルした例
import psyco; psyco.log(); psyco.full()
TALの性能は三倍になっているが、 DTML の性能には変化がない。
##: ZPT TAL DTML 01: 0 0 0 02: 0 0 0 03: 1 0 0 04: 5 2 2 05: 8 4 4 06: 11 5 10 07: 7 4 1 08: 6 2 1 09: ------- 61 ------- 34 ------- 32 10: 10 3 2 11: 17 7 10 12: 11 6 6
プロファイラのデフォールトのコンパイル条件を使ってみる
import psyco; psyco.log(); psyco.profile()
これでも、全部コンパイルした時に匹敵する性能が出ている。
##: ZPT TAL DTML 01: 0 0 0 02: 0 0 0 03: 4 3 0 04: 15 11 3 05: 20 13 5 06: 16 5 12 07: 7 5 1 08: 5 2 1 09: ------- 65 ------- 35 ------- 40 10: 11 3 2 11: 18 8 10 12: 12 6 6
という訳で、TALInterpreter() だけをコンパイルしてみる TAL の性能は
from TALInterpreter import TALInterpreter import psyco; psyco.bind(TALInterpreter)TAL の性能を改善するには、TALInterpreter() だけをコンパイルするだけで十分だ、ということが判る。
Results: ##: ZPT TAL DTML 01: 0 0 0 02: 0 0 0 03: 2 0 0 04: 9 2 2 05: 16 4 4 06: 19 5 10 07: 14 4 1 08: 10 3 1 09: ------ 122 ------- 33 ------- 32 10: 13 3 3 11: 28 8 10 12: 20 6 6
Python Ver 2.2 で導入されたニュースタイルクラスを使うと psyco は高速に動作する。
psyco 1.4 は コンパクトな、ニュースタイルクラスの代替物 psyco.compact ルートクラスを用意しており、これを明に、スーパークラスに指定すると一層のコンパクト化、高速化が可能となる。 クラス定義の前に、以下のように書くと、自動的にクラスは psyco.compact を継承し、そのメソッドは、自動的にコンパイルされる。
from psyco.classes import *
しかし、psyco.compact を継承したクラスの動作は少しだけ違うので注意が必要である。
例えば、通常の、type(x) は、types.InstanceType ではなく x.__class__
になる。
任意のc拡張モジュールを使っているものも含め、殆どの Python コードは psyco で動作する
Psyco がサポートしていないコードは、通常は Python インタプリタで実行される。
にもかかわらず、実行が失敗するものは付録の A.1 にリストがある。
これらとは別に Psyco によって、性能がかえって低下するケースもある。
map(lambda x: x*x, lst)
[x*x for x in lst]
psyco.cannotcompile(re.compile)
すべてをコンパイルするのは、中規模以上のソフトウエアではやりすぎになってしまう。
コンパイルに時間が掛る上に、余分にメモリを消費する。