聊聊Python中的pypy,聊聊Pythonpypy
PyPy是一個虛擬機器項目,主要分為兩部分:一個Python的實現和 一個編譯器
PyPy的第一部分: 用Python實現的Python
其實這麼說並不準確,準確得說應該是用rPython實現的Python,rPython是Python的一個子集,雖然rPython不是完整的Python,但用rPython寫的這個Python實現卻是可以解釋完整的Python語言。
PyPy的第二部分:編譯器
這是一個編譯rPython的編譯器,或者說這個編譯器有一個rPython的前端,目前也只有這麼一個前端,不過它的後端卻是不少,也就是說這個編譯器支援許多的目標語言,比較重要的有:C,CIL,JavaScript...
第一部分看成pypy(1)第二部分看成pypy(2)
為什麼你在同一層面下同時需要這兩者?你可以這樣想一下:PyPy(1)是一個用RPython寫的解譯器,因此它能載入使用者的Python代碼並將它編譯成位元組碼。但是這個用RPython寫的解譯器本身要能運行,就必須要被另外一個Python實現去解釋。我們可以直接用CPython去.運行這個解譯器。但是這個還不夠快取而代之,我們使用了PyPy(2)去編譯這個PyPy的解譯器,產生其他平台(比如C,JVM或CLI)代碼在我們的機器上運行,並且還加入了JIT特性。JIT能夠把位元組碼轉換成機器語言,pypy之所以快,是因為它整合了JIT跟蹤技術的最佳化編譯器。
pypy效能測試
Cpython2.7.6,pyston0.2,pypy2.2.1的效能對比,使用的是pyston原始碼目錄下的minibenchmarks和microbenchmarks中
的python代碼來跑,對比結果如下表所示
| |
Cpython2.7.6 |
pyston0.2 |
| microbenchmarks |
|
|
|
| attribute_lookup.py |
258.544s |
200.387s |
2.667s |
| attrs.py |
0.622s |
1.658s |
0.086s |
| closures.py |
0.485s |
6.658s |
0.058s |
| empty_loop.py |
3.532s |
19.248s |
0.248s |
| fib2.py |
3.375s |
0.669s |
0.804s |
| fib.py |
3.696s |
0.636s |
0.864s |
| function_calls.py |
5.283s |
0.878s |
0.303s |
| gcj_2014_2_b.py |
1.527s |
45.803s |
0.276s |
| gcj_2014_3_b.py |
0.022s |
0.174s |
0.069s |
| iteration.py |
0.185s |
1.242s |
0.062s |
| lcg.py |
2.910s |
9.097s |
0.235s |
| listcomp_bench.py |
10.132s |
56.170s |
1.379s |
| nested.py |
0.368s |
6.828s |
0.057s |
| polymorphism.py |
4.358s |
4.390s |
14.260s |
| prime_summing.py |
20.197s |
43.779s |
1.250s |
| pydigits.py |
0.034s |
Failed |
0.039s |
| repatching.py |
0.475s |
0.384s |
0.061s |
| simple_sum.py |
0.075s |
0.578s |
0.040s |
| sort.py |
2.216s |
4.587s |
0.135s |
| thread_contention.py |
6.486s |
8.133s |
0.240s |
| thread_uncontended.py |
1.324s |
5.823s |
0.238s |
| unwinding.py |
1.082s |
93.180s |
4.481s |
| vecf_add.py |
9.890s |
Failed |
0.059s |
| vecf_dot.py |
4.944s |
8.434s |
0.062s |
| |
|
|
|
| minibenchmarks |
|
|
|
| allgroup.py |
0.836s |
Failed |
18.804s |
| chaos.py |
26.268s |
Failed |
1.392s |
| fannkuch_med.py |
0.990s |
1.898s |
0.325s |
| fannkuch.py |
10.952s |
20.834s |
2.057s |
| Go.py |
53.787s |
Failed |
33.638s |
| interp2.py |
5.521s |
10.124s |
0.701s |
| interp.py |
10.863s |
5.035s |
0.563s |
| nbody_med.py |
3.132s |
6.642s |
0.601s |
| nbody.py |
12.677s |
25.540s |
1.470s |
| nq.py |
29.879s |
Failed |
44.418s |
| raytrace.py |
11.608s |
Failed |
1.228s |
| spectral_norm.py: |
14.388s |
118.309s |
1.333s |
pypy編譯除了有顏色背景的資料,其它測試結果基本都是最快的,其中15個程式碼測試結果所花時間不到Cpython的十分之一
pypy的缺陷
可以看出pypy實現python有很大的優勢,但是目前來說很多公司的python項目仍然沒有採用pypy來實現,原因是
pypy有一個缺陷:C擴充性弱,簡單理解就是python程式中如果混合了C/C++代碼,調用了C/C++的庫,就會導pypy
不支援或者pypy運行速度變慢很多。而現在很多項目都是採用C/C++/Python混合編程。
但是pypy也有自己的相容C/C++的方法(但是沒有完全解決擴充性弱的問題),pypy有ctypes和cffi兩種方式來
進行C擴充,以下是一些簡單程式實驗:
用ctypes的方式實現C++,python混合編程,先寫一個.cpp然後在python檔案中調用它,最後用Cpython,和pypy分別編譯執行都可以跑,說明ctypes是支援C++擴充的
這次用pypy跑的速度就要Cpython不少了
總結
以上就是本文關於聊聊Python中的pypy的全部內容,希望對大家有所協助。感興趣的朋友可以繼續參閱本站其他相關專題,如有不足之處,歡迎留言指出。感謝朋友們對本站的支援!