【DLL檔是甚麼?讓DLL把Python加速75倍!】

李耕銘
Nov 5, 2020

--

在安裝程式時,常會看到 dll 這種副檔名的出現,但 dll 是甚麼?它是幹嘛用的?

DLL 的全名是動態連結函式庫 Dynamic-link library ,Microsoft給的解釋是:

DLL 是一種包含可供多個程式同時使用的程式碼和資料的文件庫,當多個程式使用相同的函式程式庫時,DLL 可以減少磁片上和實體記憶體中載入的程式碼的重複。

(引文自:https://bit.ly/36ae3v5 原本內文感謝網友范姜士武指正)

因為 Python 目前是使用者最多的語言,因此接下來用 Python 引入用 C 寫的 dll 為例,看 dll 檔是怎麼幫助我們擷取各種程式語言的長處。

測試時用的程式碼是利用遞迴算斐波那契數列,我們也可以同時測試 Python 與 C 在執行速度上的差異。

首先先在 C 底下寫出斐波那契數列的函式與標頭檔,這裡我是用 Codeblocks ,但任何開發環境都可以。

編譯後,就可以用 Dll Export Viewer 看一下所產生的 dll 檔裏頭是否有Fibo_C這個函式。
( https://www.nirsoft.net/utils/dll_export_viewer.html )

然後就可以在 Python 裡引用進剛剛做好的 dll 檔啦!引用與使用方式如下:

from ctypes import cdll
dll = cdll.LoadLibrary(‘test_DLL.dll’)
dll.Fibo_C(40)

如果沒意外的話,實際執行後你有可能看到下面這個錯誤:

“OSError: [WinError 193] %1 不是有效的 Win32 應用程式。”

這是因為通常我們編譯 C 時用的是 32 bit,但在執行 Python 時用的卻是 64 bit,導致兩者不相容,這時候你可以用 exe 64bit detector 這個軟體檢查編譯出來的 dll 究竟是 32 還 64 bit。
( https://securityxploded.com/exe-64bit-detector.php )

如果發現是 32 bit,就回到原本的 C 開發環境 ,下載支援 64 bit 的編譯器後,改用 64 bit 編譯。

重新執行過後就可以使用了!這時候我們利用遞迴算第 40 個斐波那契數,藉此比較兩者需要的時間差異。

測試時用的程式碼如下:

結果如下:

Python:40.956 秒
用C寫的DLL:0.547 秒

可以發現同樣的演算法下,兩者的速度差了近 75 倍!

與 C 相比 Python 容易上手、開發快、函式庫也多,但執行速度普遍不如 C 語言,所以很常見的做法就是在開發快的 Python 中遇到複雜、重複度高的運算就導入 C 語言製成的 DLL 檔,將這部分的運算改成用 C 完成,讓這兩種語言彼此互補、合作。

最後補充幾點:

  1. 這個測試比較特殊,實際上會加速幾倍還要看實際狀況而定。
  2. 製作 dll 檔時也會同時編譯產生 .a、.def ,之後有空再說明各自代表甚麼意思。
  3. 在 C 裏頭有不同的關鍵字可以在製作 dll 檔時使用,像是 __declspec、__cdecl、__stdcall,同樣日後再來比較彼此間的差異與用法。

覺得這篇文有幫助到你的話,可以幫我的粉專點個讚,之後有空會出續集
https://bit.ly/3evM7pk

另外工商一下我下一期在台大資工訓練班的課

↓C/C++資結演算法↓
https://bit.ly/3251sIk
↓C/C++基礎↓
https://bit.ly/3jWmjDW

有其他開課需求的單位也可以找我,在這個大家都學Python的時代教C/C++的我都快被時代淘汰掉惹。

--

--

李耕銘
李耕銘

No responses yet