python、cython与python调用c库运行时间对比

一、简介

  1. 本文主要对比纯python代码、cython代码以及python调用c库运行效率对比。
  2. 文件结构:
    在这里插入图片描述

二、代码

1. python代码

get_angle_python.py

import math
def get_angle(x,y):
    angle = 123
    if y == 0 : 
        if x < 0:
            angle = 180
        else:
            angle =  0
    if x == 0 :
        if y > 0:
            angle = 90
        else:
            angle =  270   
    else: 
        tan_yx = abs(y)/abs(x)
        if y > 0 and x < 0:
            angle = 180 - math.atan(tan_yx)*180/math.pi #90-180
        elif y > 0 and x > 0:
            angle =  math.atan(tan_yx)*180/math.pi #0-90
        elif y < 0 and x < 0:
            angle = 180 + math.atan(tan_yx)*180/math.pi #180-270
        elif y < 0 and x > 0:
            angle = 360- math.atan(tan_yx)*180/math.pi #270-360
    return angle

2. cython代码

get_angle_cython.pyx

cimport cython
import math

@cython.boundscheck(False)
@cython.wraparound(False)



cdef float _get_angle(float x, float y):
    cdef float angle
    cdef float tan_yx

    angle = 123
    if y == 0 :
        if x < 0:
            angle = 180
        else:
            angle =  0
    if x == 0 :
        if y > 0:
            angle = 90
        else:
            angle =  270   
    else: 
        tan_yx = abs(y)/abs(x)
        if y > 0 and x < 0:
            angle = 180 - math.atan(tan_yx)*180/math.pi #90-180
        elif y > 0 and x > 0:
            angle =  math.atan(tan_yx)*180/math.pi #0-90
        elif y < 0 and x < 0:
            angle = 180 + math.atan(tan_yx)*180/math.pi #180-270
        elif y < 0 and x > 0:
            angle = 360- math.atan(tan_yx)*180/math.pi #270-360
    return angle

def get_angle(float x, float y):
    return _get_angle(x, y)




setup_cython.py

from distutils.core import setup, Extension
from Cython.Build import cythonize

extension = Extension(
 	"get_angle_cython",
    ["get_angle_cython.pyx"],
    # libraries=["method"]
)

setup(
    ext_modules=cythonize([extension]),
)

命令行

python setup_cython.py build_ext --inplace

编译产生get_angle_cython.cget_angle_cython.pyd(windows)或get_angle_cython.so(linux)文件。
引用时import get_angle_cython即可。

3. python调用c库代码

get_angle.h

float _get_angle(float x, float y);

get_angle.c

#include "get_angle.h"
#include <math.h>

#define pi (2*acos(0.0))

// 方向向量转化为角度
float _get_angle(float x, float y){
	float angle = 123;
	if(y == 0){
		if(x < 0) 
			angle = 180;
		else 
			angle = 0;
	}
	if(x == 0){
		if(y > 0) 
			angle = 90;
		else 
			angle = 270;
	}
	else{
		float tan_yx = fabs(y)/fabs(x);
		if (y > 0 && x < 0){
			angle = 180 - atan(tan_yx)*180/pi; //90-180
		}else if(y > 0 && x > 0){
            angle =  atan(tan_yx)*180 / pi; //0-90
		}else if (y < 0 && x < 0){
            angle = 180 + atan(tan_yx)*180/pi; //180-270
		}else if (y < 0 && x > 0){
            angle = 360- atan(tan_yx)*180/pi; //270-360
		}
	}
	return angle;		
}

get_angle_c.pyx


cdef extern from "get_angle.h":
    float _get_angle(float x, float y)

def get_angle(float x, float y):
    return _get_angle(x, y)

setup_c.py

from distutils.core import setup, Extension
from Cython.Build import cythonize

import numpy
setup(ext_modules = cythonize(Extension(
    'get_angle_c',
    sources=['get_angle_c.pyx', 'get_angle.c'],
    language='c',
    # include_dirs=[numpy.get_include()],
    library_dirs=[],
    # libraries=["method"],
    extra_compile_args=[],
    extra_link_args=[]
)))

命令行

python setup_c.py build_ext --inplace

编译产生get_angle_c.cget_angle_c.pyd(windows)或get_angle_c.so(linux)文件。
引用时import get_angle_c即可。

3. 结果测试

test.py

# test.py
import get_angle_python
import get_angle_cython
import get_angle_c

a = get_angle_python.get_angle(48, 10)
b = get_angle_cython.get_angle(48, 10)
c = get_angle_c.get_angle(48, 10)
print("a = ", a)
print("b = ", b)
print("c = ", c)

运行结果:
精度损失跟float接收double有关。
在这里插入图片描述

4. 效率测试

使用jupyter运行如下代码:

  1. 导入模块:

    import get_angle_python
    import get_angle_cython
    import get_angle_c
    
  2. 运行测试函数:

    %timeit -n 100 -r 3 get_angle_python.get_angle(48, 10)
    %timeit -n 100 -r 3 get_angle_cython.get_angle(48, 10)
    %timeit -n 100 -r 3 get_angle_c.get_angle(48, 10)
    
  3. 运行结果:
    Windows:
    在这里插入图片描述

    Ubuntu:
    在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值