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

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

python 原始方法:

 # File: StdDev.py

 import math

 def pyStdDev(a):
mean = sum(a) / len(a)
return math.sqrt((sum(((x - mean)**2 for x in a)) / len(a)))

引入numpy对象:

 # File: StdDev.py

 import numpy as np

 def npStdDev(a):
return np.std(a)

简单cython代码:

# File: cyStdDev.pyx

import math

def cyStdDev(a):
m = a.mean()
w = a - m
wSq = w**2
return math.sqrt(wSq.mean())

numpy优化后的cython:

# File: cyStdDev.pyx

cdef extern from "math.h":
double sqrt(double m) from numpy cimport ndarray
cimport numpy as np
cimport cython @cython.boundscheck(False)
def cyOptStdDev(ndarray[np.float64_t, ndim=1] a not None):
cdef Py_ssize_t i
cdef Py_ssize_t n = a.shape[0]
cdef double m = 0.0
for i in range(n):
m += a[i]
m /= n
cdef double v = 0.0
for i in range(n):
v += (a[i] - m)**2
return sqrt(v / n)

最后cython调用”c”代码:

# File: cyStdDev.pyx

cdef extern from "std_dev.h":
double std_dev(double *arr, size_t siz) def cStdDev(ndarray[np.float64_t, ndim=1] a not None):
return std_dev(<double*> a.data, a.size)

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

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

在“std_dev.c”实现:

#include <math.h>

#include "std_dev.h"

double std_dev(double *arr, size_t siz) {
double mean = 0.0;
double sum_sq;
double *pVal;
double diff;
double ret; pVal = arr;
for (size_t i = ; i < siz; ++i, ++pVal) {
mean += *pVal;
}
mean /= siz; pVal = arr;
sum_sq = 0.0;
for (size_t i = ; i < siz; ++i, ++pVal) {
diff = *pVal - mean;
sum_sq += diff * diff;
}
return sqrt(sum_sq / siz);
}

分别测量其运行时间:

# Pure Python
python3 -m timeit -s "import StdDev; import numpy as np; a = [float(v) for v in range(1000000)]" "StdDev.pyStdDev(a)"
# Numpy
python3 -m timeit -s "import StdDev; import numpy as np; a = np.arange(1e6)" "StdDev.npStdDev(a)"
# Cython - naive
python3 -m timeit -s "import cyStdDev; import numpy as np; a = np.arange(1e6)" "cyStdDev.cyStdDev(a)"
# Optimised Cython
python3 -m timeit -s "import cyStdDev; import numpy as np; a = np.arange(1e6)" "cyStdDev.cyOptStdDev(a)"
# Cython calling C
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. NetCoreApi框架搭建三、JWT授权验证)

    1.首先还是粘贴大神的链接 虽然说大神的博客已经讲得很详细了,但是此处还是自己动手好点. 首先配置Startup Swagger的验证 2.新建一个项目存放tokenmodel和生成token并且存入 ...

  2. python高级编程——网络编程(二)

    UDP 概念和介绍 UDP --- 用户数据报协议,是一个无连接的简单的面向数据报的运输层协议. UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并 不能保证它们能到达目的地. U ...

  3. Windows RDP的RCE漏洞分析和复现(CVE-2019-0708)

    0x00 漏洞描述 Windows系列服务器于2019年5月15号,被爆出高危漏洞,该漏洞影响范围较广如:windows2003.windows2008.windows2008 R2.windows ...

  4. QTableWidget右键菜单

    #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> namespace Ui { class MainWind ...

  5. 景点API支持查询携程旅游门票景点详情

    门票景点详情,景点api支持查询携程旅游门票景点详情. 接口名称:景点api 接口平台:开放api 接口地址:http://api2.juheapi.com/xiecheng/senicspot/ti ...

  6. MySQL数据库(二)--库相关操作、表相关操作(1)、存储引擎、数据类型

    一.库相关操作 1.创建数据库 (1)语法 create database 数据库 charset utf8; (2)数据库命名规范 可以由字母.数字.下划线.@.#.$ 区分大小写 唯一性 不能使用 ...

  7. nmap指令

    -sP  主机发现    -p  端口扫描(可区域)  -sV  端口(服务版本信息)-O  操作系统-iL  使用列表里的IP.(快捷方便)-iR  对公网上的随机n个IP.--excludeile ...

  8. MySQL小测试(2)

    2.创建一个stu表,字段有:自增主键id,不为空姓名,默认值性别(枚举类型),无限制身高 create table stu( id int primary key auto_increment, n ...

  9. scapy 中sniff指定的数据包并打印指定信息

    在理解这篇文章前可以先看看这两篇文章: https://www.cnblogs.com/liyuanhong/p/10925582.html https://www.cnblogs.com/liyua ...

  10. chromedriver对应chrome版本

    chromedriver版本 支持的Chrome版本 v2.41 v67-69 v2.40 v66-68 v2.39 v66-68 v2.38 v65-67 v2.37 v64-66 v2.36 v6 ...