這篇文章跟大家介紹如何利用ctypes提高Python的執行速度,對大家學習使用python具有一定的參考借鏡價值。有需要的朋友們一起來看看吧。
">
前言
ctypes是Python的外部函數庫。它提供了C相容的資料類型,並且允許呼叫動態連結庫/共享庫中的函數。 kernel32.dll 和msvcrt.dll 動態連結函式庫,以及Linux系統上的libc.so.6 函式庫。使用Python 求1000000 以內質數,重複這個過程10次,計算運行時間。 , int(math.sqrt(x)) + 1)
for i in values:if x % i == 0:
return False return
def get_prime(n) :
return [x for x in xrange(2, n) if check_prime(x)]
print timeit(stmt='get_prime(1000000)', setup='from __main__ import get_prime',
主義者=10)
輸出
42.8259568214
下面用C語言寫一個的 check_prime 函數,然後把它當作共享庫(動態連結庫)導入
#include
#include
{
int c; for ( c = 2 ; c <= sqrt(a) ; c++ ) {
if ( a%c == 0 )
return 0;
# }
return 1;
#}
##使用使用使用以下命令產生.so (shared object)檔案
gcc -shared -o prime.so -fPIC prime.c
import ctypes
import math
from timeit import timeit
check_prime_in_c =##from timeit import timeit##check_prime_in_c = ctypes.CDLL('./prime.so').check_prime
def check_prime_in_py(x):
values = xrange(2, int(math.sqrt(x)) + 1)
for i in values:
if x % i == 0:
return False
return True
def get_prime_in_c(n):
def get_prime_in_py(n):
return [x for x in xrange(2, n) if check_prime_in_py(x)]py_time = timeit(stmt='get_prime_in_py(1000000)', setup ='from __main__ import get_prime_in_py',
number=10)
print "Python version: {} seconds".format(py_time)
print "C version: {} seconds".format(c_time)#輸出##Python version: 43.4539749622 seconds
輸出#####Python version: 43.4539749622 seconds# ##C version: 8.56250786781 seconds######我們可以看到很明顯的效能差距這裡有更多的方法去判斷一個數是否是質數#######再來看一個複雜點的例子快速排序######mylib.c####include
typedef struct _Range {
int start, end;
} Range;
Range new_Range(int s, int e) {
Range r ;
r.start = s;
r.end = e;
return r;
}
void swap(int *x, int *y) {
int t = * x;
*x = *y;
*y = t;
}
void fast_sort(int arr[], const int len) {
if (len <= 0 )
return;
Range r[len];
int p = 0;
r[p++] = new_Range(0, len - 1);
while (p) {
範圍range = r[--p];
if (range.start >= range.end)
繼續;
int mid = arr[range.end];
int left = range.start , right = range.end - 1;
while (左< 右) {
while (arr[左] < 中間&& 左< 右)
left ; = 中&& 左< 右)
右--;
交換(&arr[左], &arr[右]);
}
if (arr[左] ] >= arrrange [ .end])
swap(&arr[left], &arr[range.end]);
else
left++;
r[p++] = new_Range(range.開始,左-##1);
r[p++] = new_Range(left + 1, range.end);
}
}
gcc -shared -o mylib.so -fPIC mylib.c
使用ctypes
使用ctypes.有一個麻煩點的地方是臨時的C程式碼使用的類型可能與Python不能明確的對應起來。 ##test.pyimport ctypes#import time
#import random
quick_sort = ctypes.CDLL('./mylib.so').quick_sort
nums = [ ]
for _ in range(100):
r = [random.randrange(1, 100000000) for x in xrange(100000)]
arr = (ctypes.c_int * len(r))( *r)
nums.append((arr, len(r)))
#init = time.clock()
for i in range(100):
快速排序(nums[i ][0], nums[i][1])
print "%s" % (time.clock() - init)
##與Python list的排序方法進行比較
import ctypes
#導入時間#import random
#quick_sort = ctypes.CDLL('./mylib.so').quick_sort
nums = []
#for _ in range(100):
nums.append([random.randrange(1, 100000000) for x in xrange(100000)])
init = time. Clock ()
for i in range(100):
nums[i].sort()
print "%s" % (time.clock() - init)
# 輸出
2.501257
至於結構體,需要定義一個類,包含對應的欄位和型別
class Point(ctypes.Structure):
_fields_ = [(' x ', ctypes.c_double), ('y', ctypes.c_double)]
除了匯入我們自己寫的C語言擴充文件,我們也直接匯入系統提供的函式庫檔案可以,例如linux下c標準函式庫的實作glibc
import time
#import randomfrom ctypes import cdll
libc = cdll.LoadLibrary('libc.so.6') # Linux系統
# libc = cdll.msvcrt # Windows系統
#init = time.clock()
randoms = [random.randrange(1, 100) for x in xrange(1000000)]
print "Python版本: %s 秒" % (time.clock() - init)
init = time.clock()
randoms = [(libc.rand() % 100) for x in xrange(1000000)]
print "C 版本: %s 秒" % (time.clock() - init)
#輸出
Python 版本: 0.850172 秒
C 版本: 0.27645 秒
總結
以上就是這篇文章的全部內容,希望對大家學習或使用Python能有一定的幫助,如果有疑問大家可以留言交流。
以上是利用ctypes提高Python的執行速度方法介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!