此處以"費氏數列"進行耗時訊算,以此測試調用底層函數時能提昇多少效能.
foo.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
#include <iostream> #include <stdlib.h> int f(int n){ int *f =(int *) malloc(sizeof(int)*n); if(n > 2){ f[0] = 0; f[1] = 1; }else return n; for(int i=2;i<n;i++){ f[i] = f[i-1] + f[i-2]; } return f[n-1]; } class Foo{ public: void bar(int num){ std::cout << "fibonacci :: " << f(num) << std::endl; } }; extern "C" { Foo* Foo_new(){ return new Foo(); } void Foo_bar(Foo* foo,int num){ foo->bar(num); } } |
執行以下語法編譯產生 .so 檔.紅色粗體為檔案名稱,依照實際狀況進行異動.
$ g++ -c -fPIC foo.cpp -o foo.o
$ g++ -shared -Wl,-soname,libfoo.so -o libfoo.so foo.o
*Wl 將後面參數傳送鍊結器
*soname設定動態函式庫soname(short for shared object name)
soname提供相容性標準,當升級系統中函式庫時新的soname與舊的soname相同,用舊連結產生的程式仍能正常運作.
(在Linux中,應用程式透過使用soname來指定所希望的函式庫版本,作者也可以通過保留或改變soname來聲明,哪些版本是相容的)
load_c_sample.py
1 2 3 4 5 6 7 8 9 10 11 |
from ctypes import cdll lib = cdll.LoadLibrary('./libfoo.so') class Foo(object): def __init__(self): self.obj = lib.Foo_new() def bar(self): lib.Foo_bar(self.obj,20) f = Foo() f.bar() |
以下進行效能比較:
1 2 3 4 5 6 7 |
def fibonacci(n, fib = [0, 1]): if n >= len(fib): for i in range(len(fib), n): fib.append(fib[i - 1] + fib[i - 2]) return fib[n-1] print (fibonacci(20)) |
實驗結果如下圖所示.
1. python運算
2. python載入 .so 進行運算
3. 純C++ 編譯後執行
4.最後一次執行為沒有進行運算,單純測試載入.so檔之耗費時間.
可以看出實際運算時間非常短暫,因此當運算效能差異大於載入模組時間時方能有效提昇效能.
文章標籤
全站熱搜