python shape函数_Perlin噪声和Python的ctypes
最近在知乎上看了一篇關于用C++加速Python的短文,受益匪淺。同時也受到啟發,撰寫此文作為以后的參考。
作為Python的用戶經常碰到的一個問題就是速度太慢,一般來說速度下降的一個主要原因是來自多重的for循環。如何給現有的Python代碼加速其實是Python用戶的一門必修課。比較熟悉numpy的用戶,可以熟練地寫成矩陣化操作,這樣可以大大加速運行的效率。這和MATLAB里多用矩陣操作而少用for循環是一個道理。但往往我們中的大多數并沒有高超的numpy技巧。即便是有,Python代碼的閱讀性可能反而會下降。就算退一步講,寫成了比較好的numpy的代碼也未必會比C/C++的代碼快。在不放棄Python語言的前提下,怎么用C語言來提速呢?方法有很多,前面的所指的短文已經給出了一個答案。這里我再用一個例子做一個簡單的說明,希望對大家有所幫助。首先代碼都可以取到,
https://github.com/yanfeit/PerlinNoise?github.com關于Perlin噪聲,我就不詳細介紹。簡單地說來,Perlin噪聲具有光滑性,自然性和隨機性的特點。感興趣的讀者可以找到很多相關資料,在這里我推薦兩個,pvigier的GitHub site和Adrian's 的博客。Pvigier的Perlin噪聲是用numpy來實現的,讀者如果對自己numpy的技巧深感自信,可以去閱讀一下他寫的代碼。閱讀他的代碼之后,我們可以給自己兩個問題:
我想讀者心中可能也會犯嘀咕,確實,高度矩陣化的操作需要程序員有高超的numpy技巧。反正我自愧不如,認為我很難寫出那樣漂亮的代碼。我們再來看看Adrian的博客,這是篇博客文中的上乘之作, 是關于Perlin噪聲的一個詳細介紹,配合C#來實現。我想大多數讀者可能和我一樣,對寫成for循環的形式感到極度舒適。而閱讀這樣的代碼我想讀者們也是駕輕就熟吧。所以我首先制作了一個Perlin噪聲的C++代碼(其實只用到了C的成分),之后我們會使用ctypes來調用動態鏈接庫的代碼。
創建動態鏈接庫
cd build $ cmake .. $ make $ mv ./lib/libperlinNoise.dylib ../python為了快速測試一下效果,讀者可以嘗試執行以上的代碼。
用了make之后我們會在/build/lib目錄下得到一個libperlinNoise.dylib的動態鏈接庫文件,在這個庫里面我們可以調用兩個函數。它們的接口如下所示,
// 你可以在./lib/PerlinNoise.h的文件中找到相應代碼。兩個函數返回的是指向Float的指針,我選用了單精度的浮點數也就是float。這里面有個需要注意的地方,函數切記不要返回指向一個超過二維數組的指針,其實根本就沒有這樣的定義,具體請看這個帖子。有了libperlinNoise.dylib這個動態鏈接庫之后,剩下的任務就交給Python了。以下是我的代碼的一部分(借鑒了Pvigier的代碼,在./python/cppnoise.py中可以找到相應的代碼),
# 我們所采用加速的方法,ctypes是build-in package相比于木盞的函數,我這里相對來說復雜一點點。我們需要注意的是,我們得告訴函數傳入的參數的類型和返回的類型和大小,這點至關重要。
# 讀取動態鏈接庫,在Python中調用動態鏈接庫后得到的加速效果(當然我在C++用了單精度的float),讀者可以自行修改成雙精度去測試一下。
$ python caltime.py 2D noise, numpy time consuming: 0.08261830806732177 3D noise, numpy time consuming: 4.525643992424011 2D noise, cpp time consuming: 0.007184123992919922 3D noise, cpp time consuming: 0.1645211935043335我們可以發現C語言的代碼可以說快了將近10倍以上。
最后上個圖,以饗讀者。
總結
以上是生活随笔為你收集整理的python shape函数_Perlin噪声和Python的ctypes的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python requests_小白学
- 下一篇: android 筛选控件_Flutter