<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          提速72倍!?在Python里面調(diào)用Golang函數(shù)

          共 1863字,需瀏覽 4分鐘

           ·

          2021-04-24 02:22


          大家好,歡迎來到 Crossin的編程教室 !

          我們知道,在涉及到大量 CPU 計(jì)算的時候,Python 的運(yùn)行效率可能不如其他語言。在之前的一篇文章:一個小操作把你的Python代碼提速6倍多 中,我們講到了如何通過把 Python 代碼編譯成 C 語言代碼來提高代碼的運(yùn)行速度。今天,我們分享一個可以讓速度進(jìn)一步提升的方案:不用 C 語言,而用 Go 語言。并且,我們這次不是做轉(zhuǎn)換,而是直接用 Python 調(diào)用 Go 語言寫的代碼。

          注意:文本內(nèi)容需要使用 Linux 和 macOS 系統(tǒng)實(shí)現(xiàn)?;蛘吣阋部梢允褂?Windows 10自帶的 WSL2 Linux子系統(tǒng)。

          這次我們的測試代碼還是遞歸版本的斐波那契數(shù)列計(jì)算函數(shù),由于遞歸版本涉及到大量重復(fù)計(jì)算,所以運(yùn)行速度極慢。用 Python 計(jì)算第40項(xiàng),耗時36.6秒,如下圖所示:

          如果直接使用 Golang 來寫相同的算法,速度會遠(yuǎn)遠(yuǎn)快于 Python——同樣是計(jì)算第40項(xiàng),只需要0.5秒,如下圖所示:

          那么,我們能不能使用 Golang 寫一個計(jì)算斐波那契數(shù)列的遞歸函數(shù),但是使用 Python 來調(diào)用這個函數(shù)呢?

          實(shí)際上是可以的,我們只需要把 Golang 寫的程序編譯為.so文件就可以在 Python 里面調(diào)用了。

          首先修改一下我們的 Golang 代碼,把計(jì)算斐波拉契數(shù)列的函數(shù)fib的首字母改成大寫。在 Golang 中,只有首字母大寫的函數(shù),才能被package外面的代碼調(diào)用。

          修改以后的代碼如下:

          package main
          import ( "C")
          //export Fibfunc Fib(n int) int { if n == 1 || n == 2{ return 1 } else { return Fib(n - 1) + Fib(n - 2) }}
          func main() {}

          需要注意的是,這里的注釋//export Fib不能省略,因?yàn)樵诰幾g成.so文件的時候,編譯器會尋找這個注釋。同時,為了能正常編譯,我們也必須導(dǎo)入C這個包。

          把代碼保存為fib.go,然后我們使用如下命令進(jìn)行編譯:

          go build -buildmode=c-shared -o _fib.so fib.go

          這條命令指定了編譯模式為c-shared,編譯完成以后,當(dāng)前文件夾下面會生成一個_fib.so文件。這就是我們需要用 Python 載入的文件了。

          下面,我們創(chuàng)建一個 Python 文件load.py,代碼如下:

          import ctypesimport time

          so = ctypes.cdll.LoadLibrary('./_fib.so')fib = so.Fib
          start = time.time()result = fib(40)end = time.time()print(f'斐波那契數(shù)列第40項(xiàng):{result},耗時:{end - start}')

          在這段代碼里面,通過 Python 自帶的ctypes模塊,加載_fib.so文件,然后提取出里面的Fib函數(shù)。這個函數(shù)就是用遞歸方式計(jì)算斐波那契數(shù)列的函數(shù)了。同樣是計(jì)算第40項(xiàng),我們來看看耗時:

          只需要0.5秒。耗時只有純 Python 版本的 三十六分之一,也就是說,通過 Python 調(diào)用 Golang 的函數(shù),速度是純 Python 版本的72倍。

          但需要注意的是,由于Golang 是靜態(tài)強(qiáng)類型語言,定義函數(shù)的時候需要聲明變量類型。如果你要導(dǎo)出的函數(shù)是字符串,那么變量類型需要改為*C.char而不是簡單的string。這里涉及到 C 語言中的變量類型與 Golang 中變量類型的映射關(guān)系,可以參閱:cgo[1]。本文的例子中,由于整型比較特殊,直接使用int就可以了。但其他的類型可能并沒有這么簡單。

          如果文章對你有幫助,歡迎轉(zhuǎn)發(fā)/點(diǎn)贊/收藏~

          參考資料

          [1]

          cgo: https://golang.org/cmd/cgo/

          作者:kingname
          來源:未聞Code


          _往期文章推薦_

          一行代碼讓pandas運(yùn)行得更快




          如需了解付費(fèi)精品課程教學(xué)答疑服務(wù)
          請?jiān)?strong style="max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box !important;">Crossin的編程教室內(nèi)回復(fù): 666

          瀏覽 80
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产做受 高潮游戏视频 | 国产婷婷999 | 欧美日韩在线视频免费播放 | 男人天堂网在线视频 | 成人黄色电影在线观看 |