>  기사  >  백엔드 개발  >  Python의 실행 속도를 향상시키기 위해 ctypes를 사용하는 방법 소개

Python의 실행 속도를 향상시키기 위해 ctypes를 사용하는 방법 소개

高洛峰
高洛峰원래의
2017-03-28 14:59:281335검색

이 글에서는 ctypes를 사용하여 Python의 실행 속도를 향상시키는 방법을 소개하고, 모든 사람이 Python 사용법을 배우는 데 도움이 되는 특정 참조 값을 제공합니다. 도움이 필요한 친구들이 와서 살펴보세요.

">

서문

ctypes는 Python용 외부 함수 라이브러리입니다. C 호환 데이터 유형을 제공하고 동적 링크 라이브러리/공유 라이브러리 호출을 허용합니다. 함수. Python에서 사용하기 위해 이러한 라이브러리를 래핑할 수 있습니다. C 언어에 도입된 이 인터페이스는 성능 향상을 위해 C 코드를 호출해야 하는 몇 가지 작은 문제와 같은 많은 작업을 수행하는 데 도움이 되며 이를 통해 Windows 시스템에 액세스할 수 있습니다. .dll 및 msvcrt.dll 동적 링크 라이브러리와 Linux 시스템의 libc.so.6 라이브러리는 물론 자체 컴파일된 공유 라이브러리를 사용할 수도 있습니다.

먼저 Python을 사용하여 간단한 예를 살펴보겠습니다. 1000000 내의 소수를 찾으려면 이 과정을 10번 반복하고 실행 시간을 계산하세요.

import math
from timeit import timeit
def check_prime(x):
values ​​​​= xrange(2 , int(math.sqrt(x)) + 1)
for i in 값:
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',
숫자 =10)

출력

42.8259568214

아래 C 언어로 check_prime 함수를 작성한 후 공유 라이브러리(동적 링크 라이브러리)로 가져옵니다

#include
#include
int check_prime(int a)
{
int c;
for ( c = 2 ; c if ( a%c == 0 )
return 0;
}
return 1;
}

use 다음 명령은 .so(공유 객체) 파일을 생성합니다

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):
값 ​​= xrange(2, int(math.sqrt(x)) + 1 )
값의 i에 대해:
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 (100000) ', setup ='from __main__ import get_prime_in_py ', c_time = timeit (stmt ='get_prime_in_c (1000000) ', __main__ import get_prime_in_c',
number=10)
print "Python 버전: {}초".format(py_time)
print "C 버전: {}초".format(c_time)

출력

Python 버전: 43.4539749622초

C 버전: 8.56250786781초


숫자가 소수인지 확인하는 더 많은 방법이 있습니다.

좀 더 살펴보겠습니다. 복잡한 예제를 빠르게 정렬

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) {
   범위 범위 = r[--p];
   if (range.start >= range.end)
     continue;
   int mid = arr[range.end];
   int left = range.start, right = range.end - 1;
   while (왼쪽 < 오른쪽) {
     while (arr[왼쪽] < mid && 왼쪽 < 오른쪽)
       left++;
     while (arr[right] >= mid && left
   if (arr[left) ] >= arr[range.end])
     swap(&arr[left], &arr[range.end]);
   else
     left++;
   r[p++] = new_Range(range. 시작, 왼쪽 - 1);
   r[p++] = new_Range(왼쪽 + 1, range.end);
 }
}
gcc -shared -o mylib.so -fPIC mylib.c
使用 CTypes 有 有 一 个 个 麻烦点 麻烦点 的 地方 是 是 原生 的 的 的 的 代码 使用 的 类型 可能 跟 跟 跟 跟 跟 不 不 不 能 明确 明确 的 对应 上 来。。 比如 这里 什么 是 是 中 中 的 数 组 组??? 还 是 是 是。。 一 的 个 一 一 一 的 个 中 中 模块 模块 模块 模块 模块 模块 模块 模块 模块 模块 模块 模块 模块 模块 模块 模块 模块 模块 模块 模块 模块 模块 模块 模块 模块 模块 模块 模块 模块 模块 模块 模块 模块 模块 模块 模块 模块.所以我们需要进行转换

test.py

ctypes 가져오기

가져오기 시간

임의로 가져오기

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 목록 적 정렬 方法进行对比

ctype 가져오기

가져오기 시간

임의로 가져오기

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()
"%s" % 인쇄(time.clock() - init)

输出

2.501257

至于结构体,需要定义一个类,包含상应的字段和类型

클래스 Point(ctypes.Structure):

 _필드_ = [( 'x', ctypes.c_double),

       ('y', ctypes.c_double)]

统提供的库文件,比如linux下c标准库적实现 glibc

가져오기 시간

임의로 가져오기

from 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를 사용하는 방법 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.