我们用以下方法计算百万以上float型数据的标准偏差,以估计各个方法的计算性能:

  • 原始python
  • numpy
  • cython
  • c(由cython调用)

python 原始方法:

  1. # File: StdDev.py
  2.  
  3. import math
  4.  
  5. def pyStdDev(a):
  6. mean = sum(a) / len(a)
  7. return math.sqrt((sum(((x - mean)**2 for x in a)) / len(a)))

引入numpy对象:

  1. # File: StdDev.py
  2.  
  3. import numpy as np
  4.  
  5. def npStdDev(a):
  6. return np.std(a)

简单cython代码:

  1. # File: cyStdDev.pyx
  2.  
  3. import math
  4.  
  5. def cyStdDev(a):
  6. m = a.mean()
  7. w = a - m
  8. wSq = w**2
  9. return math.sqrt(wSq.mean())

numpy优化后的cython:

  1. # File: cyStdDev.pyx
  2.  
  3. cdef extern from "math.h":
  4. double sqrt(double m)
  5.  
  6. from numpy cimport ndarray
  7. cimport numpy as np
  8. cimport cython
  9.  
  10. @cython.boundscheck(False)
  11. def cyOptStdDev(ndarray[np.float64_t, ndim=1] a not None):
  12. cdef Py_ssize_t i
  13. cdef Py_ssize_t n = a.shape[0]
  14. cdef double m = 0.0
  15. for i in range(n):
  16. m += a[i]
  17. m /= n
  18. cdef double v = 0.0
  19. for i in range(n):
  20. v += (a[i] - m)**2
  21. return sqrt(v / n)

最后cython调用”c”代码:

  1. # File: cyStdDev.pyx
  2.  
  3. cdef extern from "std_dev.h":
  4. double std_dev(double *arr, size_t siz)
  5.  
  6. def cStdDev(ndarray[np.float64_t, ndim=1] a not None):
  7. return std_dev(<double*> a.data, a.size)

“c”代码定义在“std_dev.h”:

  1. #include <stdlib.h>
  2. double std_dev(double *arr, size_t siz);

在“std_dev.c”实现:

  1. #include <math.h>
  2.  
  3. #include "std_dev.h"
  4.  
  5. double std_dev(double *arr, size_t siz) {
  6. double mean = 0.0;
  7. double sum_sq;
  8. double *pVal;
  9. double diff;
  10. double ret;
  11.  
  12. pVal = arr;
  13. for (size_t i = ; i < siz; ++i, ++pVal) {
  14. mean += *pVal;
  15. }
  16. mean /= siz;
  17.  
  18. pVal = arr;
  19. sum_sq = 0.0;
  20. for (size_t i = ; i < siz; ++i, ++pVal) {
  21. diff = *pVal - mean;
  22. sum_sq += diff * diff;
  23. }
  24. return sqrt(sum_sq / siz);
  25. }

分别测量其运行时间:

  1. # Pure Python
  2. python3 -m timeit -s "import StdDev; import numpy as np; a = [float(v) for v in range(1000000)]" "StdDev.pyStdDev(a)"
  3. # Numpy
  4. python3 -m timeit -s "import StdDev; import numpy as np; a = np.arange(1e6)" "StdDev.npStdDev(a)"
  5. # Cython - naive
  6. python3 -m timeit -s "import cyStdDev; import numpy as np; a = np.arange(1e6)" "cyStdDev.cyStdDev(a)"
  7. # Optimised Cython
  8. python3 -m timeit -s "import cyStdDev; import numpy as np; a = np.arange(1e6)" "cyStdDev.cyOptStdDev(a)"
  9. # Cython calling C
  10. python3 -m timeit -s "import cyStdDev; import numpy as np; a = np.arange(1e6)" "cyStdDev.cStdDev(a)"

结果:

方法 运行时间(ms) python做基准 numpy做基准
python 183 1倍  0.03倍
numpy 5.97 31 1
cython 7.76 24 0.8
cython + numpy 2.18 84 2.7
调用c 2.22 82 2.7

总结:

  1. numpy优化速度很高,相比于python
  2. cython 在非优化状态下居然跟numpy性能差不多,优秀
  3. 直接手写c语言是性能很高的,但还是不如cython+numpy,大爷还是厉害

=============================================

qsy 23 may 2019

python cython c 性能对比的更多相关文章

  1. 2017年的golang、python、php、c++、c、java、Nodejs性能对比(golang python php c++ java Nodejs Performance)

    2017年的golang.python.php.c++.c.java.Nodejs性能对比 本人在PHP/C++/Go/Py时,突发奇想,想把最近主流的编程语言性能作个简单的比较, 至于怎么比,还是不 ...

  2. 2017年的golang、python、php、c++、c、java、Nodejs性能对比[续]

    2017年的golang.python.php.c++.c.java.Nodejs性能对比[续] 最近忙,这个话题放了几天,今天来个续集.   上篇传送门: 2017年的golang.python.p ...

  3. Python开发【笔记】:从海量文件的目录中获取文件名--方法性能对比

    Python获取文件名的方法性能对比 前言:平常在python中从文件夹中获取文件名的简单方法   os.system('ll /data/')   但是当文件夹中含有巨量文件时,这种方式完全是行不通 ...

  4. python性能对比

    python性能对比之items #1 #-*- coding:utf8-*- import datetime road_nodes = {} for i in range(5000000): roa ...

  5. Python 读取图像文件的性能对比

    Python 读取图像文件的性能对比 使用 Python 读取一个保存在本地硬盘上的视频文件,视频文件的编码方式是使用的原始的 RGBA 格式写入的,即无压缩的原始视频文件.最开始直接使用 Pytho ...

  6. 开发语言性能对比,C++、Java、Python、LUA、TCC

    一直想做开发语言性能对比,刚好有时间都做了给大家参考一下, 编译类:C++和Java表现还不错 脚本类:TCC脚本动态运行C语言,性能比其他脚本快好多... 想玩TCC的同学下载测试包,TCC目录下修 ...

  7. python各种web框架对比

    0 引言        python在web开发方面有着广泛的应用.鉴于各种各样的框架,对于开发者来说如何选择将成为一个问题.为此,我特此对比较常见的几种框架从性能.使用感受以及应用情况进行一个粗略的 ...

  8. 常用排序算法的python实现和性能分析

    常用排序算法的python实现和性能分析 一年一度的换工作高峰又到了,HR大概每天都塞几份简历过来,基本上一天安排两个面试的话,当天就只能加班干活了.趁着面试别人的机会,自己也把一些基础算法和一些面试 ...

  9. 【Python】常用排序算法的python实现和性能分析

    作者:waterxi 原文链接 背景 一年一度的换工作高峰又到了,HR大概每天都塞几份简历过来,基本上一天安排两个面试的话,当天就只能加班干活了.趁着面试别人的机会,自己也把一些基础算法和一些面试题整 ...

随机推荐

  1. Windows Server - Tomcat服务器下载、安装、配置环境变量教程

      版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/qq_40881680/articl ...

  2. 字节输出流FileOutputStream

    #字节流 字节输出流FileOutputStream 创建输出流对象 OutputStream 流对象是一个抽象类,不能实例化.所以,我们要找一个具体的子类 :FileOutputStream. 查看 ...

  3. Linux下getopt()函数

    from https://www.cnblogs.com/qingergege/p/5914218.html 最近在弄Linux C编程,本科的时候没好好学啊,希望学弟学妹们引以为鉴. 好了,虽然啰嗦 ...

  4. C++ http服务

    1.需要使用c++提供http服务,本来想使用libevent,但是经过一番搜索后,发现了只需要引用2个文件的mongoose库. 官方文档:https://cesanta.com/docs/over ...

  5. PS图片转CSS+HTML页面的正确步骤

    转载来源:https://www.cnblogs.com/gg_lihui/p/3396409.html 制作网页标准的流程是:拿到网站美工制作的psd效果图后,网页设计师再把PS制作的图片转html ...

  6. 红黑树实现(c/c++)

    红黑树 简介 一直想写的一种数据结构,非常厉害的思想,插入,删除,查找,修改,都是\(log_2 n\)的时间复杂度. 比AVL更强大的是,插入删除综合效率比AVL要优秀一点. 性质 一颗红黑树是满足 ...

  7. MySQL Install--CentOS 7配置MySQL服务和开启启动

    创建MySQL服务 编辑文件: vim /usr/lib/systemd/system/mysql.service 录入下面内容: PS: 注意修改ExecStart脚本 [Unit]Descript ...

  8. 国内不fq安装K8S三: 使用helm安装kubernet-dashboard

    目录 3 使用helm安装kubernet-dashboard 3.1 Helm的安装 3.2 使用Helm部署Nginx Ingress 3.3 使用Helm部署dashboard 3.4 使用He ...

  9. Linux操作系统安全-OpenSSL工具常用命令介绍

    Linux操作系统安全-OpenSSL工具常用命令介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.OpenSSL开源项目有三个组件 openssl: 多用途的命令行工具,包 ...

  10. centos7下搭建JDK和Hadoop

    涉及基础操作命令 这里只是将涉及到的提了下一下具体的使用还需要读者自己查阅资料 tar 解压命令 su 进入root用户模式 rm -rf 删除 cd /文件名/.../ 进入某个文件夹下 注意要逐层 ...