ホームページ  >  記事  >  バックエンド開発  >  ctypes を使用して Python の実行速度を向上させる方法の紹介

ctypes を使用して Python の実行速度を向上させる方法の紹介

高洛峰
高洛峰オリジナル
2017-03-28 14:59:281321ブラウズ

この記事は、Python の実行速度を向上させるための ctypes の使用方法を紹介しており、誰もが Python の使い方を学ぶ上で一定の参考値になります。困っている友達が見に来ます。

">

はじめに

ctypes は、Python 用の外部関数ライブラリです。C 互換のデータ型を提供し、ダイナミック リンク ライブラリ/共有ライブラリ内の関数を呼び出すことができます。これらのライブラリを Python で使用するためにラップできます。このインターフェイスC 言語を導入すると、パフォーマンスを向上させるために C コードを呼び出す必要がある小さな問題など、さまざまな作業に役立ちます。これにより、Windows システム上の kernel32.dll および msvcrt.dll ダイナミック リンク ライブラリ、および libc.so にアクセスできるようになります。 Linux システム上の .6 ライブラリ. もちろん、独自にコンパイルされた共有ライブラリを使用することもできます

まず、Python を使用して 1000000 内の素数を見つけ、このプロセスを 10 回繰り返し、Time を計算して実行します。

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

Output

42.8259568214

以下のC言語でcheck_prime関数を記述し、共有ライブラリ(ダイナミックリンクライブラリ)としてインポートします

#include
#include
int check_prime(int a)
{
int c;
for ( c = 2 ; c if ( a%c = = 0 )
timeit import timeit から 0 を返します
check_prime_in_c = ctypes.CDLL('./prime.so').check_prime
def check_prime_ in_py(x):
値 = xrange(2, int(math.sqrt( x)) + 1)

for i invalues:

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 バージョン: {} 秒".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 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] 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 では明確な相対関係を示すことができません。配列モジュール内の 1 つの数グループです。そのため、変換を実行する必要があります

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.lock() - init)

出力

1.874907

とPythonリストの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

構造体まで、定義が必要対応するフィールドと型を含む 1 つのクラス

class Point(ctypes.Structure):
_fields_ = [('x', ctypes.c_double),
('y', ctypes.c_double)]

除了导入我们自己写された C 言語解説文ファイル、私はまた、システムが提供するファイル ファイルを直接入力することができます。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 を使用して Python の実行速度を向上させる方法の紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。