cython并行性能-计算滚动求和 rolling function
cython通过编译为C程序提高性能有很多例子,通过OpenMP并行的性能没那么多。
今天尝试了一下似乎gcc对parallelism reduction优化的很厉害,加上OpenMP并行可以提高20倍性能(相对于pandas rolling),这不是简单的2 core带来的性能提高。
滚动求和 rolling sum的例子
最简单的实现pandas.rolling,通过操作numpy array,速度也还算能接受。
# test_para.py
import numpy as np
#import pyximport; pyximport.install(reload_support=True, setup_args={"include_dirs":np.get_include()})
import timeit
import pandas as pd
import para.cpara as cpara
X = -1 + 2*np.random.rand(100000)
ss = pd.Series(X)
ss.rolling(100).apply(np.sum,raw=True)
print('==============')
print('multi thread')
start_time = timeit.default_timer()
sum_cython=pd.Series(cpara.window_sum(X, 100))
print(timeit.default_timer() - start_time)
print('single thread')
start_time = timeit.default_timer()
sum_pandas=ss.rolling(100).apply(np.sum,raw=True)
print(timeit.default_timer() - start_time)
print(np.max(np.abs(sum_cython - sum_pandas)))
cython源文件
# cpara.pyx
cimport cython
import numpy as np
from cython.parallel import prange,parallel
cimport numpy as cnp
from libc.stdlib cimport malloc
@cython.boundscheck(False)
def window_sum(cnp.ndarray[double, ndim=1] arr, int window):
    cdef h = np.zeros_like(arr)
    cdef int imax = arr.shape[0]
    cdef double *buffer = <double *>malloc(imax * sizeof(double))
    cdef double result = 0.0
    cdef int i, j
    with nogil, parallel():
        for i in prange(imax, schedule='dynamic'):
            buffer[i] = 0.0
            if i >= window-1:
                for j in range(window):
                    buffer[i] += arr[i-j]
    for i in range(imax):
        if i < window -1:
            h[i] = np.nan
        else:
            h[i] = buffer[i]
    return h
setup.py中要加入openmp的编译链接参数
EXT = Extension("*",
                ["para/*.pyx"],
                define_macros=[('CYTHON_TRACE', CYTHON_DEBUG),
                               ('CYTHON_TRACE_NOGIL', CYTHON_DEBUG),
                               ('CYTHON_BINDING', CYTHON_DEBUG),
                               ("NPY_NO_DEPRECATED_API", "NPY_1_7_API_VERSION"),
                               ('CYTHON_FAST_PYCCALL', '1')],
                extra_compile_args = ["-fopenmp" ],
                extra_link_args=['-fopenmp'],
                include_dirs=[".", np.get_include()])
性能比较
%timeit pd.Series(cpara.window_sum(X, 100))
23.4 ms ± 325 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit ss.rolling(100).apply(np.sum,raw=True)
536 ms ± 3.96 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
536/23.4=22.9
测试环境:i3-7100U 2core 2T CPU, ubuntu 18.04 LTS
cython并行性能-计算滚动求和 rolling function的更多相关文章
- easyui生成合并行,合计计算价格
		
easyui生成合并行,合计计算价格 注:本文来源: 原创 一:图样你效果图 二:代码实现 1:datagrid 列展示: window.dataGrid = $("#dataGrid&qu ...
 - python cython c 性能对比
		
我们用以下方法计算百万以上float型数据的标准偏差,以估计各个方法的计算性能: 原始python numpy cython c(由cython调用) python 原始方法: # File: Std ...
 - ForkJoin、并行流计算、串行流计算对比
		
ForkJoin 什么是 ForkJoin ForkJoin 是一个把大任务拆分为多个小任务来分别计算的并行计算框架 ForkJoin 特点:工作窃取 这里面维护的都是双端队列,因此但其中一个线程完成 ...
 - 横向tab计算滚动位置
		
React横向滚动计算 class Footer extends React.Component { handleClick(e) { const offset = 150; // 指定偏移量 thi ...
 - .NET使用Task动态创建多任务多线程并行程序计算Redis集群keys计算
		
Task是一个很好用的多任务处理类,并且通过Task可以对任务进行很好的控制. 下面将通过代码实现Redis集群在使用IServer.keys时通过多任务对多个服务器示例进行并行计算,并对返回key做 ...
 - js滚动
		
有选择性的重复造一些轮子,未必是件坏事.Aaron的博客上加了一个悬浮菜单,貌似显得很高大上了.虽然这类小把戏也不是头一次见了,但是从未自己写过.今天就选择性的拿这个功能写一写.下面是这个轮子的开发过 ...
 - js的下拉刷新和上拉加载,基于iScroll v4.2.5
		
html部分 <div id="wrapper" style="height: 100%"> <div id="scroller&q ...
 - 一个用于每一天JavaScript示例-使用缓存计算(memoization)为了提高应用程序性能
		
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
 - [转] Performance_js中计算网站性能监控利器
		
1.Performance方法 Performance提供的方法可以灵活使用,获取到页面加载等标记的耗时情况. performance.now() //返回当前到页面打开时刻的耗时,精确到千分之一毫秒 ...
 - 开源图计算框架GraphLab介绍
		
GraphLab介绍 GraphLab 是由CMU(卡内基梅隆大学)的Select 实验室在2010 年提出的一个基于图像处理模型的开源图计算框架.框架使用C++语言开发实现. 该框架是面向机器学习( ...
 
随机推荐
- 容器镜像仓库-Harbor的安装及踩坑
			
之前实验室的师兄让我帮忙给服务器上装一个Harbor,花了不少时间,遂记录之,以避坑. 在学习使用Harbor之前,需要了解Docker的使用,可以看看我之前的博客:应用容器引擎-Docker.Doc ...
 - vue+.net入门级书签项目
			
vu3+.net6 webApi 书签管理项目 前言 Gitee项目地址:https://gitee.com/zyplj/book-marks Github项目地址:https://github.co ...
 - javaweb画图
			
最近都在忙期中考试,写博客的频率有点低了,以下是一些基本代码,是王建民老师说的要建立自己的资料库,我直接建的资料库. 画图html <!--定义表格宽度 行距 宽度<tr>行< ...
 - shell:判断某个变量是否包含字符串/变量的方法
			
尝试了有3种方法: 1.使用"=~"符号,注意前后必须要有空格! ** 可以输出正确结果,被匹配的字符串必须要有引号括起来!** [clouder@ana53 bin]$ a1=' ...
 - 最大K段和
			
题目大意 有一个长度为 \(N\) 的序列 \(A\) .他希望从中选出不超过 \(K\) 个连续子段,满足它们两两不相交,求总和的最大值(可以一段也不选,答案为 \(0\)). 分析 很容易想到 \ ...
 - IP地址后面/24/26/27/28/29/30网关数量分别是多少?如何计算?
			
转载csdn: https://blog.csdn.net/jinfengyunIDC/article/details/112575286
 - 读论文SRCNN:Learning a Deep Convolutional Network for Image Super-Resolution
			
Learning a Deep Convolutional Network for Image Super-Resolution SRCNN是深度学习应用于SR领域的开山之作. 论文 2014 ECC ...
 - 代码随想录算法训练营day10 | leetcode 232.用栈实现队列 225. 用队列实现栈
			
基础知识 使用ArrayDeque 实现栈和队列 stack push pop peek isEmpty() size() queue offer poll peek isEmpty() size() ...
 - Matplotlib 实现画中画
			
需要导入的包 inset_axes 要实现画中画,即在原画轴上添加新轴,需要用到mpl_toolkits.axes_grid1.inset_locator的inset_axes. 基本用法 new_a ...
 - javascript中的二进制运算符
			
javascript的二进制运算符用于直接对二进制位进行计算,好处是速度快,缺点是不直观. 位运算符只对整数起作用,如果一个运算子不是整数,则会转换成整数后再执行;我们都知道javascript的数值 ...