此處以"費氏數列"進行耗時訊算,以此測試調用底層函數時能提昇多少效能.

 

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檔之耗費時間.

可以看出實際運算時間非常短暫,因此當運算效能差異大於載入模組時間時方能有效提昇效能.

 

arrow
arrow
    文章標籤
    python c c++
    全站熱搜

    Lung-Yu,Tsai 發表在 痞客邦 留言(0) 人氣()