2012-04-27 28 views
0

由於python有很多種編寫二進制模塊的方法,所以如果我希望改進某些段的性能,代碼儘可能多。擴展python/numpy性能的最佳方法

據我所知,可以使用python/numpy C-api編寫擴展,或者包裝一些已經編寫的純C/C++/Fortran函數,以從python代碼中調用。

當然,像Cython這樣的工具是最簡單的方法,但我認爲用手寫代碼可以提供更好的控制並提供更好的性能。

這個問題,它可能是一般的,是使用哪種方法。編寫一個C或C++擴展?包裝外部C/C++函數或使用回調python函數?

我寫這個問題在Langtangen的「Python腳本爲計算科學」裏有幾種方法進行了比較,以Python和C.

+2

寫得很好的Cython應該可以提供近乎C的性能,而且比使用手寫C擴展更少的代碼。 – 2012-04-27 14:21:09

回答

3

我會說這取決於你的技能/經驗之間的接口讀取章10後和你的項目。 如果這是非常實際的,並且您在C/C++中精通並且您已經編寫了python包裝器,那麼編寫您自己的擴展並進行接口。

如果你打算在其他項目上使用Numpy,那麼去Numpy的C-API,它是廣泛的,而且有很好的文檔記錄,但它也是相當多的文檔要處理。 至少我處理它有很多困難,但後來我再次吮吸C.如果你不確定去Cython,耗時少得多,而且在大多數情況下性能都非常不錯。 (我的選擇) 從我的角度來看,您需要成爲一個優秀的C編碼器,比之前的2版本的Cython做得更好,而且會更加複雜和耗時。 那麼你是一個偉大的C編碼器?

此外,如果您正在尋找性能,可能需要一段時間才能查看pycuda或其他GPGPU內容,具體取決於您的硬件。

1

幾種不同方法的比較可以找到here。我已經嘗試了兩個cython,並使用f2py封裝了我自己的fortran代碼。我發現f2py是更好的方式去達到我的目的。這部分受我瞭解fortran這個事實的影響,但老實說,像fortran 90這樣的現代方言看起來與使用numpy的python代碼非常相似,並且不應該那麼難。

隨着cython開始慢,純python代碼,那麼你必須經歷一個繁瑣的過程,儀器化你的代碼,找出所有對python API的調用,並在相應的cython關鍵字處輸入把它變成更快的C代碼。使用Fortran,您只需編寫普通代碼,並且您已經獲得了完整的編譯速度,而不會出現繁瑣的迭代過程。

此外,cython中的某些數組操作仍會導致對Python API的調用緩慢,特別是涉及切片操作的那些操作。相反,Fortran中的數組是編譯器理解並可以優化的本地類型。話雖如此,cython正在快速發展,所以未來這可能會發生變化。

我在f2py中發現的最大缺點是它不支持派生類型的數組(類似於numpy的recarray)。有一些希望fwrap將是f2py的替代品,它可以解決這個問題,但目前似乎是在後退。順便說一下,它基於cython。