The Ultimate Psyco Guide

Psyco は 任意の Python コードを高速化する。

The Ultimate Psyco Guide の読書メモです。

1. Installation
1.1 Requirements
1.2 Installing
1.3 Installing from the sources
1.4 Compiling Psyco in Debug mode
2. Tutorial
2.1 Quick examples
2.2 Zope's TAL: a real example with benchmarks
2.3 Old-style classes vs. Built-in types
2.4 Known bugs
3. User Reference Guide
3.2 Profile-based compilation
3.3 Exceptions and warnings
3.4 The psyco.classes module
3.5 The psyco.compact type
3.6 Logging
3.7 Machine code inspection
A. Caveats
A.1 Known bugs
A.2 Patched functions
A.3 Unsupported Python constructs
B. Performance expectations
Index
About this document ...

1. Installation

1.1 Requirements

2006年9月の時点で、Psyco は以下を要求する。

Psyco は OS が何であるかに依存しない。

1.2 Installing

Debian 的には python-psyco/python-psyco-doc パッケージをインスコするだけ

1.3 Installing from the sources

俺には関係ないからトバす

1.4 Compiling Psyco in Debug mode

※ Psyco をデバックする時の話、トバス

2. Tutorial

Psyco の目標は、とっても簡単に使えることであり、この目標が達成されたら、このユーザーガイドは、無内容でいい筈ということになる。 とはいえ、まだ実験段階であるので、使用メモリ量など子細な点を制御できるようにしてある。

2.1 Quick examples

このドキュメントには、トップレベルの先頭に下のように書けば、psyco を使える、と書いてあるが
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

2.2 Zope's TAL: a real example with benchmarks

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
obfuscated
わかりにくくする
ceveat
注意

2.3 Old-style classes vs. Built-in types

Python Ver 2.2 で導入されたニュースタイルクラスを使うと psyco は高速に動作する。

psyco 1.4 は コンパクトな、ニュースタイルクラスの代替物 psyco.compact ルートクラスを用意しており、これを明に、スーパークラスに指定すると一層のコンパクト化、高速化が可能となる。 クラス定義の前に、以下のように書くと、自動的にクラスは psyco.compact を継承し、そのメソッドは、自動的にコンパイルされる。

from psyco.classes import *

しかし、psyco.compact を継承したクラスの動作は少しだけ違うので注意が必要である。

例えば、通常の、type(x) は、types.InstanceType ではなく x.__class__ になる。

2.4 Known bugs

任意のc拡張モジュールを使っているものも含め、殆どの Python コードは psyco で動作する

Psyco がサポートしていないコードは、通常は Python インタプリタで実行される。

にもかかわらず、実行が失敗するものは付録の A.1 にリストがある。

これらとは別に Psyco によって、性能がかえって低下するケースもある。

3. User Reference Guide

ここで説明する関数はすべて、どこまでコンパイルして、何をインタプリタに残すかを指示するものである。

すべてをコンパイルするのは、中規模以上のソフトウエアではやりすぎになってしまう。

コンパイルに時間が掛る上に、余分にメモリを消費する。

3.1 Selecting the functions to compile

3.2 Profile-based compilation

3.2.1 Charge profilers

3.2.2 Limiting memory usage

3.2.3 The profilers queue

3.3 Exceptions and warnings

3.4 The psyco.classes module

3.4.1 Examples

3.5 The psyco.compact type

3.5.1 Examples

3.6 Logging

3.7 Machine code inspection

A. Caveats

A.1 Known bugs

A.2 Patched functions

A.3 Unsupported Python constructs

B. Performance expectations

Index

About this document ...


連絡先:webadmin.itsumi@gmail.com このページは muse.el で作成しています。 Emacs