Heim  >  Artikel  >  Backend-Entwicklung  >  Einführung in die Verwendung von Ctypes zur Verbesserung der Ausführungsgeschwindigkeit von Python

Einführung in die Verwendung von Ctypes zur Verbesserung der Ausführungsgeschwindigkeit von Python

高洛峰
高洛峰Original
2017-03-28 14:59:281339Durchsuche

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!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn