deploy django to pypy
15692 ワード
tips:このドキュメントはsphinxで書かれていて、直接copyからブログに来ました.
4.PyPy配置
4.1 PyPy取付
PyPyはpython言語で実装されたjit付きpython解釈器で、X 86,X 86をサポートしています.64,ARMなどのプラットフォームでは,最新バージョンは2.0 beta 1であるが,サーバに64ビットバージョンをインストールする際にインストールに問題があるため,1.9を選択した.
公式サイトからPyPyの相応のバージョンをダウンロードして、解凍した後cd pypy/bin;pypyはpypyコマンド解釈器に入ります.
sample:
wget https://bitbucket.org/pypy/pypy/downloads/pypy-1.9-linux64.tar.bz2
tar xvf pypy-1.9-linux64.tar.bz2 -C/opt
cd/usr/local/bin
ln -s/opt/pypy-1.9/bin/pypy pypy
curl -O http://python-distribute.org/distribute_setup.py
curl -O https://raw.github.com/pypa/pip/master/contrib/get-pip.py
pypy distribute_setup.py
pypy get-pip.py
/opt/pypy-1.9/bin/pip install pygments # for example
しかし、より良い方法はvirtualenvでPyPy実行環境を構築し、他のpython環境に干渉せず、pipも自動的にインストールされます.
PyPyをダウンロードして解凍すると、
virtualenv -p/path/to/bin/pypy my-pypy-env
source my-pypy-env/bin/active
pip install django #for example
4.2 Packageインストール
現在、PyPy互換性はまあまあですが、PyPyのパフォーマンスについてもいくつかの説明があり、サードパーティのライブラリ互換性についてはwikiページがあります.
現在直接インストールできる(必ずしも互換性がない)ライブラリは次のとおりです.
pip install django flask tornado gunicorn sqlalchemy
pip pillow #PIL
pip BeautifulSoup south pytidylib simplejson
pillow :PIL fork
MySQL-Python(MySQLdb)は小さなpatchを打つ必要があります.彼のpatchはmysqldb 1.2.3 c 1に基づいて修正されていますが、1.2.4 b 4に適用してもいいです.
patchに従ってMySQLdbコードを変更する
python setup.py build
python setup.py install
今すぐpy runserverは実行できるはずです
4.3 PyPy Bugs(継続更新)
Issue1116 : AttributeError: ‘GzipFile’ object has no attribute ‘fileobj’ with Django
fixメソッド(未確定):add the following line at the end of manage.py the error goes away:
import gc; gc.collect(); gc.collect()
後記:九牛二虎の力を費やして私の元のプログラムdeployをpypyに行きましたが、pypyはまだ成熟していません.結果は少しがっかりしました.60 msのページしか必要ありませんでしたが、今は300 msが必要です.実は私はベンチマークテストをしたことがあります.pypyは完勝しましたが、Benchmarks are just lies damn lies
profileで見ると、deepcopyとpickleの2つの性能に影響を与える場所が見つかりました.
CPython2.7実行結果:
PyPy 2.0.0-beta 1運転結果:
deepcopyの性能の差は2倍ぐらいで、pickleの差は何倍になるか分かりません
4.PyPy配置
4.1 PyPy取付
PyPyはpython言語で実装されたjit付きpython解釈器で、X 86,X 86をサポートしています.64,ARMなどのプラットフォームでは,最新バージョンは2.0 beta 1であるが,サーバに64ビットバージョンをインストールする際にインストールに問題があるため,1.9を選択した.
公式サイトからPyPyの相応のバージョンをダウンロードして、解凍した後cd pypy/bin;pypyはpypyコマンド解釈器に入ります.
sample:
wget https://bitbucket.org/pypy/pypy/downloads/pypy-1.9-linux64.tar.bz2
tar xvf pypy-1.9-linux64.tar.bz2 -C/opt
cd/usr/local/bin
ln -s/opt/pypy-1.9/bin/pypy pypy
curl -O http://python-distribute.org/distribute_setup.py
curl -O https://raw.github.com/pypa/pip/master/contrib/get-pip.py
pypy distribute_setup.py
pypy get-pip.py
/opt/pypy-1.9/bin/pip install pygments # for example
しかし、より良い方法はvirtualenvでPyPy実行環境を構築し、他のpython環境に干渉せず、pipも自動的にインストールされます.
PyPyをダウンロードして解凍すると、
virtualenv -p/path/to/bin/pypy my-pypy-env
source my-pypy-env/bin/active
pip install django #for example
4.2 Packageインストール
現在、PyPy互換性はまあまあですが、PyPyのパフォーマンスについてもいくつかの説明があり、サードパーティのライブラリ互換性についてはwikiページがあります.
現在直接インストールできる(必ずしも互換性がない)ライブラリは次のとおりです.
pip install django flask tornado gunicorn sqlalchemy
pip pillow #PIL
pip BeautifulSoup south pytidylib simplejson
pillow :PIL fork
MySQL-Python(MySQLdb)は小さなpatchを打つ必要があります.彼のpatchはmysqldb 1.2.3 c 1に基づいて修正されていますが、1.2.4 b 4に適用してもいいです.
patchに従ってMySQLdbコードを変更する
python setup.py build
python setup.py install
今すぐpy runserverは実行できるはずです
4.3 PyPy Bugs(継続更新)
Issue1116 : AttributeError: ‘GzipFile’ object has no attribute ‘fileobj’ with Django
fixメソッド(未確定):add the following line at the end of manage.py the error goes away:
import gc; gc.collect(); gc.collect()
後記:九牛二虎の力を費やして私の元のプログラムdeployをpypyに行きましたが、pypyはまだ成熟していません.結果は少しがっかりしました.60 msのページしか必要ありませんでしたが、今は300 msが必要です.実は私はベンチマークテストをしたことがあります.pypyは完勝しましたが、Benchmarks are just lies damn lies
profileで見ると、deepcopyとpickleの2つの性能に影響を与える場所が見つかりました.
import cProfile as profile
from pstats import Stats
from timeit import timeit
from copy import copy, deepcopy
import cPickle as pickle
lst = [[str(x)] for x in range(100)]
def f():
def inner():
x = copy(lst)
y = deepcopy(lst)
timeit(inner, number=100)
def p():
def inner():
s = pickle.dumps(lst)
pickle.loads(s)
timeit(inner, number=100)
st = Stats(profile.Profile().runctx('f()', globals(), locals()))
st.sort_stats('time').print_stats()
st = Stats(profile.Profile().runctx('p()', globals(), locals()))
st.sort_stats('time').print_stats()
CPython2.7実行結果:
$ python tcopy.py
191318 function calls (161318 primitive calls) in 0.559 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
20100/100 0.191 0.000 0.556 0.006 /usr/lib/python2.7/copy.py:145(deepcopy)
10100/100 0.095 0.000 0.554 0.006 /usr/lib/python2.7/copy.py:226(_deepcopy_list)
20100 0.088 0.000 0.140 0.000 /usr/lib/python2.7/copy.py:267(_keep_alive)
50400 0.066 0.000 0.066 0.000 {id}
40300 0.052 0.000 0.052 0.000 {method 'get' of 'dict' objects}
40000 0.052 0.000 0.052 0.000 {method 'append' of 'list' objects}
10000 0.012 0.000 0.012 0.000 /usr/lib/python2.7/copy.py:198(_deepcopy_atomic)
100 0.001 0.000 0.558 0.006 tcopy.py:19(inner)
1 0.001 0.001 0.559 0.559 /usr/lib/python2.7/timeit.py:96(inner)
100 0.000 0.000 0.001 0.000 /usr/lib/python2.7/copy.py:66(copy)
100 0.000 0.000 0.000 0.000 /usr/lib/python2.7/copy.py:113(_copy_with_constructor)
1 0.000 0.000 0.000 0.000 /usr/lib/python2.7/timeit.py:143(setup)
1 0.000 0.000 0.559 0.559 /usr/lib/python2.7/timeit.py:178(timeit)
1 0.000 0.000 0.000 0.000 /usr/lib/python2.7/timeit.py:121(__init__)
1 0.000 0.000 0.559 0.559 /usr/lib/python2.7/timeit.py:227(timeit)
2 0.000 0.000 0.000 0.000 {time.time}
2 0.000 0.000 0.000 0.000 {isinstance}
1 0.000 0.000 0.559 0.559 tcopy.py:18(f)
1 0.000 0.000 0.000 0.000 {hasattr}
1 0.000 0.000 0.000 0.000 /usr/lib/python2.7/timeit.py:94(_template_func)
1 0.000 0.000 0.000 0.000 {gc.disable}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.000 0.000 0.000 0.000 <string>:1(<module>)
1 0.000 0.000 0.000 0.000 {gc.enable}
1 0.000 0.000 0.000 0.000 {gc.isenabled}
1 0.000 0.000 0.000 0.000 {globals}
318 function calls in 0.031 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
100 0.019 0.000 0.019 0.000 {cPickle.dumps}
100 0.011 0.000 0.011 0.000 {cPickle.loads}
100 0.001 0.000 0.031 0.000 tcopy.py:25(inner)
1 0.000 0.000 0.031 0.031 /usr/lib/python2.7/timeit.py:96(inner)
1 0.000 0.000 0.000 0.000 /usr/lib/python2.7/timeit.py:143(setup)
1 0.000 0.000 0.031 0.031 /usr/lib/python2.7/timeit.py:178(timeit)
1 0.000 0.000 0.000 0.000 /usr/lib/python2.7/timeit.py:121(__init__)
1 0.000 0.000 0.031 0.031 /usr/lib/python2.7/timeit.py:227(timeit)
2 0.000 0.000 0.000 0.000 {time.time}
1 0.000 0.000 0.031 0.031 tcopy.py:24(p)
2 0.000 0.000 0.000 0.000 {isinstance}
1 0.000 0.000 0.000 0.000 {globals}
1 0.000 0.000 0.000 0.000 {hasattr}
1 0.000 0.000 0.000 0.000 /usr/lib/python2.7/timeit.py:94(_template_func)
1 0.000 0.000 0.000 0.000 <string>:1(<module>)
1 0.000 0.000 0.000 0.000 {gc.isenabled}
1 0.000 0.000 0.000 0.000 {gc.disable}
1 0.000 0.000 0.000 0.000 {gc.enable}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
PyPy 2.0.0-beta 1運転結果:
$ python tcopy.py
191318 function calls (161318 primitive calls) in 1.015 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
20100/100 0.457 0.000 1.013 0.010 /opt/pypy-2.0-beta1/lib-python/2.7/copy.py:145(deepcopy)
10100/100 0.211 0.000 1.010 0.010 /opt/pypy-2.0-beta1/lib-python/2.7/copy.py:226(_deepcopy_list)
20100 0.173 0.000 0.224 0.000 /opt/pypy-2.0-beta1/lib-python/2.7/copy.py:267(_keep_alive)
40300 0.083 0.000 0.083 0.000 {method 'get' of 'dict' objects}
40000 0.067 0.000 0.067 0.000 {method 'append' of 'list' objects}
50400 0.015 0.000 0.015 0.000 {id}
10000 0.007 0.000 0.007 0.000 /opt/pypy-2.0-beta1/lib-python/2.7/copy.py:198(_deepcopy_atomic)
100 0.001 0.000 0.001 0.000 /opt/pypy-2.0-beta1/lib-python/2.7/copy.py:66(copy)
1 0.000 0.000 1.015 1.015 /opt/pypy-2.0-beta1/lib-python/2.7/timeit.py:96(inner)
100 0.000 0.000 0.000 0.000 /opt/pypy-2.0-beta1/lib-python/2.7/copy.py:113(_copy_with_constructor)
100 0.000 0.000 1.014 0.010 tcopy.py:19(inner)
1 0.000 0.000 0.000 0.000 /opt/pypy-2.0-beta1/lib-python/2.7/timeit.py:143(setup)
1 0.000 0.000 1.015 1.015 /opt/pypy-2.0-beta1/lib-python/2.7/timeit.py:178(timeit)
1 0.000 0.000 0.000 0.000 {gc.disable}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.000 0.000 0.000 0.000 /opt/pypy-2.0-beta1/lib-python/2.7/timeit.py:121(__init__)
1 0.000 0.000 1.015 1.015 /opt/pypy-2.0-beta1/lib-python/2.7/timeit.py:227(timeit)
2 0.000 0.000 0.000 0.000 {time.time}
1 0.000 0.000 1.015 1.015 tcopy.py:18(f)
1 0.000 0.000 0.000 0.000 {gc.isenabled}
2 0.000 0.000 0.000 0.000 {isinstance}
1 0.000 0.000 0.000 0.000 {gc.enable}
1 0.000 0.000 0.000 0.000 {hasattr}
1 0.000 0.000 0.000 0.000 /opt/pypy-2.0-beta1/lib-python/2.7/timeit.py:94(_template_func)
1 0.000 0.000 0.000 0.000 {globals}
1 0.000 0.000 0.000 0.000 <string>:1(<module>)
714740 function calls (674740 primitive calls) in 4.780 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
100 1.295 0.013 2.787 0.028 /opt/pypy-2.0-beta1/lib_pypy/cPickle.py:152(load)
20100 0.826 0.000 0.919 0.000 /opt/pypy-2.0-beta1/lib-python/2.7/pickle.py:227(memoize)
20100/100 0.451 0.000 1.982 0.020 /opt/pypy-2.0-beta1/lib-python/2.7/pickle.py:269(save)
20100 0.388 0.000 0.434 0.000 /opt/pypy-2.0-beta1/lib_pypy/cPickle.py:466(load_put)
20000 0.361 0.000 0.449 0.000 /opt/pypy-2.0-beta1/lib_pypy/cPickle.py:480(load_append)
10000 0.208 0.000 0.291 0.000 /opt/pypy-2.0-beta1/lib_pypy/cPickle.py:264(load_string)
10100/100 0.133 0.000 1.974 0.020 /opt/pypy-2.0-beta1/lib-python/2.7/pickle.py:608(_batch_appends)
10100 0.132 0.000 0.143 0.000 /opt/pypy-2.0-beta1/lib_pypy/cPickle.py:550(load_mark)
70400 0.121 0.000 0.121 0.000 {method 'read' of 'cStringIO.StringI' objects}
10100/100 0.115 0.000 1.979 0.020 /opt/pypy-2.0-beta1/lib-python/2.7/pickle.py:591(save_list)
10000 0.113 0.000 0.848 0.000 /opt/pypy-2.0-beta1/lib-python/2.7/pickle.py:480(save_string)
20100 0.094 0.000 1.018 0.000 /opt/pypy-2.0-beta1/lib_pypy/cPickle.py:110(memoize)
60300 0.085 0.000 0.085 0.000 {method 'write' of 'cStringIO.StringO' objects}
40203 0.082 0.000 0.082 0.000 {method 'get' of 'dict' objects}
30100 0.064 0.000 0.064 0.000 {method 'readline' of 'cStringIO.StringI' objects}
40100 0.062 0.000 0.062 0.000 {method 'append' of 'list' objects}
10000 0.050 0.000 0.050 0.000 {method 'decode' of 'str' objects}
20100 0.047 0.000 0.047 0.000 {method 'pop' of 'list' objects}
70400 0.043 0.000 0.043 0.000 {ord}
80400 0.034 0.000 0.034 0.000 {id}
20100 0.022 0.000 0.029 0.000 /opt/pypy-2.0-beta1/lib-python/2.7/pickle.py:250(put)
30100 0.016 0.000 0.016 0.000 {repr}
40300 0.012 0.000 0.012 0.000 {len}
10100 0.006 0.000 0.006 0.000 {iter}
10100 0.005 0.000 0.007 0.000 /opt/pypy-2.0-beta1/lib_pypy/cPickle.py:179(marker)
10100 0.005 0.000 0.012 0.000 /opt/pypy-2.0-beta1/lib_pypy/cPickle.py:325(load_list)
100 0.002 0.000 1.989 0.020 /opt/pypy-2.0-beta1/lib_pypy/cPickle.py:121(dumps)
20100 0.002 0.000 0.002 0.000 /opt/pypy-2.0-beta1/lib-python/2.7/pickle.py:333(persistent_id)
100 0.001 0.000 0.003 0.000 /opt/pypy-2.0-beta1/lib_pypy/cPickle.py:102(__init__)
100 0.001 0.000 2.789 0.028 /opt/pypy-2.0-beta1/lib_pypy/cPickle.py:594(loads)
100 0.001 0.000 0.001 0.000 /opt/pypy-2.0-beta1/lib-python/2.7/pickle.py:173(__init__)
100 0.001 0.000 4.779 0.048 tcopy.py:25(inner)
100 0.001 0.000 0.001 0.000 /opt/pypy-2.0-beta1/lib_pypy/cPickle.py:136(__init__)
100 0.001 0.000 1.983 0.020 /opt/pypy-2.0-beta1/lib-python/2.7/pickle.py:220(dump)
100 0.001 0.000 0.001 0.000 {method 'getvalue' of 'cStringIO.StringO' objects}
1 0.001 0.001 4.780 4.780 /opt/pypy-2.0-beta1/lib-python/2.7/timeit.py:96(inner)
200 0.000 0.000 0.000 0.000 {cStringIO.StringIO}
1 0.000 0.000 0.000 0.000 {__import__}
1 0.000 0.000 0.000 0.000 /home/largetalk/venv/pypy-env/lib-python/2.7/encodings/string_escape.py:2(<module>)
1 0.000 0.000 0.000 0.000 /home/largetalk/venv/pypy-env/lib-python/2.7/encodings/__init__.py:71(search_function)
1 0.000 0.000 0.000 0.000 /opt/pypy-2.0-beta1/lib-python/2.7/timeit.py:143(setup)
1 0.000 0.000 4.780 4.780 /opt/pypy-2.0-beta1/lib-python/2.7/timeit.py:178(timeit)
1 0.000 0.000 0.000 0.000 /opt/pypy-2.0-beta1/lib-python/2.7/timeit.py:121(__init__)
1 0.000 0.000 0.000 0.000 /home/largetalk/venv/pypy-env/lib-python/2.7/encodings/__init__.py:49(normalize_encoding)
1 0.000 0.000 0.000 0.000 /home/largetalk/venv/pypy-env/lib-python/2.7/codecs.py:77(__new__)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.000 0.000 4.780 4.780 /opt/pypy-2.0-beta1/lib-python/2.7/timeit.py:227(timeit)
1 0.000 0.000 0.000 0.000 /home/largetalk/venv/pypy-env/lib-python/2.7/encodings/string_escape.py:29(getregentry)
4 0.000 0.000 0.000 0.000 {isinstance}
2 0.000 0.000 0.000 0.000 {time.time}
1 0.000 0.000 4.780 4.780 tcopy.py:24(p)
1 0.000 0.000 0.000 0.000 {method 'replace' of 'str' objects}
2 0.000 0.000 0.000 0.000 {hasattr}
1 0.000 0.000 0.000 0.000 {method 'translate' of 'str' objects}
1 0.000 0.000 0.000 0.000 {method 'split' of 'str' objects}
1 0.000 0.000 0.000 0.000 /home/largetalk/venv/pypy-env/lib-python/2.7/encodings/string_escape.py:10(Codec)
1 0.000 0.000 0.000 0.000 {method 'join' of 'str' objects}
1 0.000 0.000 0.000 0.000 {method '__new__' of 'type' objects}
1 0.000 0.000 0.000 0.000 {gc.enable}
1 0.000 0.000 0.000 0.000 /home/largetalk/venv/pypy-env/lib-python/2.7/encodings/string_escape.py:15(IncrementalEncoder)
1 0.000 0.000 0.000 0.000 /opt/pypy-2.0-beta1/lib-python/2.7/timeit.py:94(_template_func)
1 0.000 0.000 0.000 0.000 /home/largetalk/venv/pypy-env/lib-python/2.7/encodings/string_escape.py:19(IncrementalDecoder)
1 0.000 0.000 0.000 0.000 {gc.isenabled}
1 0.000 0.000 0.000 0.000 /home/largetalk/venv/pypy-env/lib-python/2.7/encodings/string_escape.py:23(StreamWriter)
1 0.000 0.000 0.000 0.000 {gc.disable}
1 0.000 0.000 0.000 0.000 /home/largetalk/venv/pypy-env/lib-python/2.7/encodings/string_escape.py:26(StreamReader)
1 0.000 0.000 0.000 0.000 <string>:1(<module>)
1 0.000 0.000 0.000 0.000 {globals}
deepcopyの性能の差は2倍ぐらいで、pickleの差は何倍になるか分かりません