Dieser Artikel stellt vor, wie man ctypes verwendet, um die Ausführungsgeschwindigkeit von Python zu verbessern, und bietet einen bestimmten Referenzwert für jeden, der den Umgang mit Python erlernen möchte. Freunde in Not kommen und schauen vorbei.
">
Vorwort
ctypes ist eine externe Funktionsbibliothek für Python. Sie stellt C-kompatible Datentypen bereit und ermöglicht den Aufruf dynamischer Linkbibliotheken/gemeinsam genutzter Bibliotheken. Funktion. Diese in die C-Sprache eingeführte Schnittstelle kann uns dabei helfen, viele kleine Probleme zu lösen, die beim Aufrufen von C-Code zur Verbesserung der Leistung erforderlich sind .dll und msvcrt.dll dynamische Linkbibliotheken und die libc.so.6-Bibliothek auf Linux-Systemen Natürlich können Sie auch Ihre eigenen kompilierten gemeinsam genutzten Bibliotheken verwenden
Schauen wir uns zunächst ein einfaches Beispiel an Um Primzahlen innerhalb von 1000000 zu finden, wiederholen Sie diesen Vorgang 10 Mal und berechnen Sie die Laufzeit
import math
from timeit import timeit
def check_prime(x):
Values = xrange(2 , int(math.sqrt(x)) + 1)
für i in Werten:
if x % i == 0:
return False
return True
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',
Zahl =10)
Ausgabe
42.8259568214
Schreiben Sie unten eine check_prime-Funktion in der C-Sprache und importieren Sie sie dann als gemeinsam genutzte Bibliothek (Dynamic Link Library)
#include
#include
int check_prime(int a)
{
int c;
for ( c = 2 ; c <= sqrt(a) ; c++ ) {
if ( a%c == 0 )
return 0;
}
return 1;
}
verwenden Der folgende Befehl generiert eine .so-Datei (Shared Object)
gcc -shared -o prime.so -fPIC prime.c
import ctypes
import math
from timeit import timeit
check_prime_in_c = ctypes.CDLL('./prime.so').check_prime
def check_prime_in_py(x):
Werte = xrange(2, int(math.sqrt(x)) + 1 )
für i in Werten:
if x % i == 0:
return False
return True
def get_prime_in_c(n):
return [x for x in xrange( 2, n) if check_prime_in_c (x)]
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)
c_time = timeit(stmt='get_prime_in_c(1000000)', setup='from __main__ import. get_prime_in_c',
number=10)
print „Python version: {} seconds“.format(py_time)
print „C version: {} seconds“.format(c_time)
Output
Python-Version: 43,4539749622 Sekunden
C-Version: 8,56250786781 Sekunden
Wir können die offensichtliche Leistungslücke erkennen, um festzustellen, ob eine Zahl eine Primzahl ist
Sehen wir uns eine weitere an komplexes Beispiel schnell sortieren
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 quick_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 range = r[--p];
if (range.start >= range.end)
continue;
int mid = arr[range.end];
int left = range.start, right = range.end - 1;
while (left < right) {
while (arr[left] < mid && left < right)
left++;
while (arr[right] >= mid && left < right)
right--;
swap(&arr[left], &arr[right]);
}
if (arr[left ] >= arr[range.end])
swap(&arr[left], &arr[range.end]);
else
left++;
r[p++] = new_Range(range. start, left - 1);
r[p++] = new_Range(left + 1, range.end);
}
}
gcc -shared -o mylib.so -fPIC mylib.c
使用ctypes有一个麻烦点的地方是原生的C代码使用的类型可能跟Python不能明确的对应上来。比如这里什么是Python中的数组?列表?还是 array 模块中的一个数组。所以我们需要进行转换
test.py
import 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):
quick_sort(nums[i][0], nums[i][1])
print "%s" % (time.clock() - init)
输出
1.874907
与Python list 的 sort 方法进行对比
ctypes importieren
import time
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 random
from ctypes import cdll
libc = cdll.LoadLibrary('libc.so.6') # Linux系统
# libc = cdll.msvcrt # Windows-Betriebssystem
init = time.clock()
randoms = [random.randrange(1, 100) for x in xrange(1000000)]
print „Python-Version : %s Sekunden" % (time.clock() - init)
init = time.clock()
randoms = [(libc.rand() % 100) for x in xrange(1000000)]
print „C-Version: %s Sekunden“ % (time.clock() - init)
输出
Python-Version: 0,850172 Sekunden
C-Version: 0,27645 Sekunden
总结
以上就是这篇文章的全部内容, 希望对大家学习或使用Python能有一定的帮助,如果有疑问大家可以留言交流.
Das obige ist der detaillierte Inhalt vonEinführung in die Verwendung von Ctypes zur Verbesserung der Ausführungsgeschwindigkeit von Python. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!