2017-01-23 42 views
2

我需要加快NumPy陣列上的一些算法。他們將使用std::vector和一些更高級的STL數據結構。在Cython和Boost.Python中擴展NumPy的相對優點是什麼?

我將我的選擇縮小到Cython(現在包裝大多數STL容器)和Boost.Python(它現在已經內置了對NumPy的支持)。

我從我的,有時它需要個月提供了一個框架合作,以發現其隱藏的問題(因爲它們很少使用由其弟子談話要點)的編程經驗知道,所以你的幫助可能會救了我很多時間。

在Cython和Boost.Python中擴展NumPy的相對優點和缺點是什麼?

+0

如果你想要更多的答案,然後不接受我的!當它顯然只是部分答案時,接受它會說「這個問題已經解決了」。 – DavidW

+0

考慮到問題的性質,我無法知道它是否是部分的。道歉,如果這是不好的禮儀。 – MaxB

+0

這不是真正的禮節(你可以選擇接受任何你喜歡的問題) - 我只是覺得你有最好的機會在沒有被接受的答案的情況下得到更多的答案。 – DavidW

回答

3

這是一個非常不完整的答案,只有真正覆蓋一對夫婦的它一小部分(如果我想的更多的東西,我會編輯):


升壓doesn't look to implement operator[] specifically for numpy arrays。這意味着operator[]將來自基類object類(即ndarray繼承),這將意味着調用將通過Python機制到達__getitem__,因此索引將變慢(接近Python速度)。如果你想在速度做索引,你必須自己做指針運算:

// rough gist - untested: 

// i,j,k are your indices 

double* data = reinterpret_cast<double*>(array.get_data()); 
// in reality you'd check the dtype - the data may not be a double... 

double data_element = array.strides(0)*i + array.strides(1)*j +array.strides(2)*k; 

相比之下用Cython有內置的自動numpy的陣列的高效的索引。


用Cython是不一樣的東西大std::vector(雖然不是絕對可怕的 - 你可以它通常誘使做你想要什麼)。一個明顯的限制是所有的cdef都必須在函數的開頭,所以C++類在默認情況下在那裏構造,然後在之後分配給/操作(這可能有點低效)。對於超出簡單用途的任何事情,您不希望在Cython中操作C++類型(相反,最好使用C++編寫代碼,然後從Cython調用它)。

第二個限制是它與非類模板發生衝突。一個常見的例子是std::array,它以模板編號。根據您計劃的代碼,這可能會也可能不是問題。

+0

非常感謝! Boost.Python在這裏的選擇對我來說非常令人驚訝。 '[]'在C++ 03中是一元的,但它們可以定義'operator()'。 – MaxB

+0

支持Operataor [](ndarray類繼承自定義它的對象) - 它不會很快。雖然我不知道他們是如何做多個論點的,但我懷疑你可以。 – DavidW

2

對於小問題,我傾向於選擇使用cython,與C++代碼庫進行更大程度的整合,更喜歡使用Python。

部分取決於您的代碼的受衆。如果你正在與一個在python方面有豐富經驗的團隊合作,但是使用C++的經驗很少,那麼Cython是有意義的。如果你有一個固定的代碼庫和複雜的類型進行交互操作,那麼boost python最終可能會便宜些。

Cython鼓勵您逐步編寫,逐步添加所需的類型以獲得額外的性能並解決許多硬包裝問題。提升Python需要花費大量精力來獲取構建設置,並且很難生成對PyPI有意義的包。但是從我所看到的,Cython具有良好的內置錯誤消息/診斷,從boost中解脫出來可能很難解釋 - 善待你自己,並使用新的ish C++編譯器,最好是用於生成可讀的錯誤消息的編譯器。

不打折的替代工具,如numba和pybind11(Python的提升不提升和更好的錯誤消息)(類似性能的代碼是Python的,不只是一些類似於用Cython)

+0

非常感謝!我有一段可怕的時間試圖「安裝numba」:未聲明的依賴關係,即使你修復它們,破壞的構建,對於它們的子依賴也是如此,等等遞歸。即使他們沒有故意這樣做,爲了讓人們購買康達,它將我轉移到他們的項目上。 – MaxB

相關問題