纯 Python 实现
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
使用 c* 提速度代码
#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 c*
from c* import *
from c*.util import find_library
import time
# 定义结构,继承自c*.Structure,与C语言中定义的结构对应
class Point(c*.Structure):
_fields_ = [('x', c*.c_double), ('y', c*.c_double)]
class Test(c*.Structure):
_fields_ = [
('sentence', c*.c_char_p),
('nb_points', c*.c_int),
('points', c*.POINTER(Point)),
('distances', c*.POINTER(c_double)),
]
# Lib C functions
_libc = c*.CDLL(find_library('c'))
_libc.free.arg* = [c*.c_void_p]
_libc.free.restype = c*.c_void_p
# Lib shared functions
_libblog = c*.CDLL("./fastc.so")
_libblog.increment_string.arg* = [c*.c_char_p, c*.c_int]
_libblog.increment_string.restype = c*.c_char_p
_libblog.generate_points.arg* = [c*.POINTER(Test), c*.c_int]
_libblog.distance_between_points.arg* = [c*.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 = c*.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('c* run time: %s'%str(time.time() - start_time))
python 2.py
c* run time: 1.2614238262176514
结尾
以下文章来源于懒编程 ,作者ayuliao
技术交流微信群,技术探讨 信息分享 学习互助,还有直播等福利活动等着你~