首页 > 应用开发 > > 将 Python 运行速度提升 30 倍的神技巧

import random
import time
# 点
class Point():
def __init__(self, x, y):
self.x = x
self.y = y
class Test():
def __init__(self, string, nb):
self.string = string
self.points = []
# 初始化点集合
for i in range(nb):
self.points.append(Point(random.random(), random.random()))
self.distances = []
# 增量字符串
def increment_string(self, n):
tmp = ""
# 每个字符做一次偏移
for c in self.string:
tmp += chr(ord(c) + n)
self.string = tmp
# 这个函数计算列表中每个点之间的距离
def distance_between_points(self):
for i, a in enumerate(self.points):
for b in self.points:
# 距离公式
self.distances.append(((b.x - a.x) ** 2 + (b.y - b.x) ** 2) ** 0.5)
if __name__ == '__main__':
start_time = time.time()
test = Test("A nice sentence to test.", 10000)
test.increment_string(-5) # 偏移字符串中的每个字符
test.distance_between_points() # 计算集合中点与点之间的距离
print('pure python run time:%s'%str(time.time()-start_time))
python 1.py
pure python run time:39.431304931640625
#include <stdlib.h>
#include <math.h>
// 点结构
typedef struct s_point
{
double x;
double y;
} t_point;
typedef struct s_test
{
char *sentence; // 句子
int nb_points;
t_point *points; // 点
double *distances; // 两点距离,指针
} t_test;
// 增量字符串
char *increment_string(char *str, int n)
{
for (int i = ; str[i]; i++)
// 每个字符做一次偏移
str[i] = str[i] + n;
return (str);
}
// 随机生成点集合
void generate_points(t_test *test, int nb)
{
// calloc () 函数用来动态地分配内存空间并初始化为 0
// 其实就是初始化变量,为其分配内存空间
t_point *points = calloc(nb + 1, sizeof(t_point));
for (int i = ; i < nb; i++)
{
points[i].x = rand();
points[i].y = rand();
}
// 将结构地址赋值给指针
test->points = points;
test->nb_points = nb;
}
// 计算集合中点的距离
void distance_between_points(t_test *test)
{
int nb = test->nb_points;
// 创建变量空间
double *distances = calloc(nb * nb + 1, sizeof(double));
for (int i = ; i < nb; i++)
for (int j = ; j < nb; j++)
// sqrt 计算平方根
distances[i * nb + j] = sqrt((test->points[j].x - test->points[i].x) * (test->points[j].x - test->points[i].x) + (test->points[j].y - test->points[i].y) * (test->points[j].y - test->points[i].y));
test->distances = distances;
}
// 生成 .o 文件
gcc -c fastc.c
// 利用 .o 文件生成so文件
gcc -shared -fPIC -o fastc.so fastc.o
import ctypes
from ctypes import *
from ctypes.util import find_library
import time
# 定义结构,继承自ctypes.Structure,与C语言中定义的结构对应
class Point(ctypes.Structure):
_fields_ = [('x', ctypes.c_double), ('y', ctypes.c_double)]
class Test(ctypes.Structure):
_fields_ = [
('sentence', ctypes.c_char_p),
('nb_points', ctypes.c_int),
('points', ctypes.POINTER(Point)),
('distances', ctypes.POINTER(c_double)),
]
# Lib C functions
_libc = ctypes.CDLL(find_library('c'))
_libc.free.argtypes = [ctypes.c_void_p]
_libc.free.restype = ctypes.c_void_p
# Lib shared functions
_libblog = ctypes.CDLL("./fastc.so")
_libblog.increment_string.argtypes = [ctypes.c_char_p, ctypes.c_int]
_libblog.increment_string.restype = ctypes.c_char_p
_libblog.generate_points.argtypes = [ctypes.POINTER(Test), ctypes.c_int]
_libblog.distance_between_points.argtypes = [ctypes.POINTER(Test)]
if __name__ == '__main__':
start_time = time.time()
# 创建
test = {}
test['sentence'] = "A nice sentence to test.".encode('utf-8')
test['nb_points'] =
test['points'] = None
test['distances'] = None
c_test = Test(**test)
ptr_test = ctypes.pointer(c_test)
# 调用so文件中的c语言方法
_libblog.generate_points(ptr_test, 10000)
ptr_test.contents.sentence = _libblog.increment_string(ptr_test.contents.sentence, -5)
_libblog.distance_between_points(ptr_test)
_libc.free(ptr_test.contents.points)
_libc.free(ptr_test.contents.distances)
print('ctypes run time: %s'%str(time.time() - start_time))
python 2.py
ctypes run time: 1.2614238262176514
以下文章来源于懒编程 ,作者ayuliao
技术交流微信群,技术探讨 信息分享 学习互助,还有直播等福利活动等着你~

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/31535056/viewspace-3145784/ ,如需转载,请注明出处,否则将追究法律责任。