<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ù)

          共 1787字,需瀏覽 4分鐘

           ·

          2020-07-27 17:27

          閱讀本文大概需要 3 分鐘。


          我們知道,在涉及到大量 CPU 計算的時候,Python 的運行效率可能不如其他語言。今天我們講一下如何直接用 Python 調(diào)用 Go 語言寫的代碼。

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

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

          如果直接使用 Golang 來寫相同的算法,速度會遠遠快于 Python——同樣是計算第40項,只需要0.5秒,如下圖所示:

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

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

          首先修改一下我們的 Golang 代碼,把計算斐波拉契數(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不能省略,因為在編譯成.so文件的時候,編譯器會尋找這個注釋。同時,為了能正常編譯,我們也必須導入C這個包。

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

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

          這條命令指定了編譯模式為c-shared,編譯完成以后,當前文件夾下面會生成一個_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項:{result},耗時:{end - start}')

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

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

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

          參考資料

          [1]

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


          推薦閱讀

          1

          如何判斷一個網(wǎng)頁是列表頁還是詳情頁

          2

          最全總結(jié):Python 發(fā)送郵件的幾種方式

          3

          Docker 中運行 Pyppeteer 的那些坑

          4??

          Python 為什么用 # 號作注釋符?




          崔慶才

          靜覓博客博主,《Python3網(wǎng)絡(luò)爬蟲開發(fā)實戰(zhàn)》作者

          隱形字

          個人公眾號:進擊的Coder

          長按識別二維碼關(guān)注





          好文和朋友一起看~
          瀏覽 38
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <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>
                  午夜淫色 | 五月色激情 | www.4438久久 www.豆花视频在线 | 亚州在现免费视 | 777777亚洲成人 |