Cet article explique comment utiliser les ctypes pour améliorer la vitesse d'exécution de Python et a une certaine valeur de référence pour que tout le monde puisse apprendre à utiliser Python. Des amis dans le besoin viennent jeter un œil.
">
Préface
ctypes est une bibliothèque de fonctions externe pour Python. Elle fournit des types de données compatibles C et permet d'appeler des bibliothèques de liens dynamiques/bibliothèques partagées. Fonction. Il peut envelopper ces bibliothèques pour une utilisation en Python. Cette interface introduite dans le langage C peut nous aider à faire beaucoup de choses, comme certains petits problèmes qui nécessitent d'appeler du code C pour améliorer les performances. Grâce à elle, vous pouvez accéder au système Windows32. dll et msvcrt.dll et la bibliothèque libc.so.6 sur les systèmes Linux. Bien sûr, vous pouvez également utiliser vos propres bibliothèques partagées compilées
Regardons d'abord un exemple simple pour utiliser Python. trouvez les nombres premiers inférieurs à 1 000 000, répétez ce processus 10 fois et calculez le temps d'exécution
import math
from timeit import timeit
def check_prime(x):
values = xrange. (2 , int(math.sqrt(x)) + 1)
pour i en valeurs :
si 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',
number =10)
Sortie
42.8259568214
Écrivez une fonction check_prime en langage C ci-dessous, puis importez-la en tant que bibliothèque partagée (bibliothèque de liens dynamiques)
#include
#include
int check_prime(int a)
{
int c;
for ( c = 2 ; c <= sqrt(a) ; c++ ) {
if ( a%c == 0 )
renvoie 0;
}
renvoie 1;
}
utiliser La commande suivante génère un fichier .so (objet partagé)
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):
values = xrange(2, int(math.sqrt(x)) + 1)
pour i en valeurs :
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',
numéro =10)
imprimer "Version Python : {} secondes".format(py_time)
imprimer "Version C : {} secondes".format(c_time)
Sortie
Version Python : 43,4539749622 secondes
Version C : 8,56250786781 secondes
Nous pouvons voir l'écart de performances évident. Voici d'autres façons de déterminer si un nombre est premier
Regardons un problème plus complexe. exemple trier rapidement
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;
pendant que (gauche < droite) {
pendant que (arr[gauche] < milieu && gauche < droite)
gauche++;
pendant (arr[right] >= milieu && gauche < droite)
droite--;
swap(&arr[gauche], &arr[droite]);
}
si (arr[gauche ] >= 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
Les ctypes sont des exemples de Python. Il s'agit d'un tableau de type Python.所以我们需要进行转换
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()
pour i in range(100):
quick_sort(nums[i][0], nums[i][1])
print "%s" % (time.clock() - init)
输出
1.874907
与Python list 的 sort 方法进行对比
import ctypes
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)导入系统提供的库文件,比如linux下c标准库的实现 glibc
import random
from ctypes import cdlllibc = cdll.LoadLibrary('libc.so.6') # Linux系统
# libc = cdll.msvcrt # Windows系统
init = time.clock()
randoms = [random.randrange(1, 100) for x in xrange(1000000)]
print "Version Python : %s secondes" % (time.clock() - init)
init = time.clock()
randoms = [(libc.rand() % 100) pour x dans xrange(1000000)]
imprimer "Version C : %s secondes" % (time.clock() - init)
输出
Version C : 0,27645 secondes
总结
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!