栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

长期的难题,如何在python中优化多级循环?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

长期的难题,如何在python中优化多级循环?

只需编译

为了获得最佳性能,我建议使用Numba(易于使用,性能良好)。另外,Cython可能是一个好主意,但是对您的代码进行了更多更改。

实际上,您一切都正确,并实现了一个易于理解的解决方案(对于人类而言,对于编译器而言最重要)。

基本上有两种获取性能的方法

  1. 向量化代码,如@scnerd所示。这通常比仅编译一个非常简单的代码(仅使用一些for循环)要慢一些,也更复杂。 不要 向量化代码,而要使用编译器。从一个简单的循环方法来说,这通常是需要做的工作,并且会导致更慢和更复杂的结果。此过程的优点是您只需要numpy,这是几乎每个处理某些数值计算的Python项目中的标准依赖项。

  2. 编译代码。如果您已经有一个包含几个循环而没有其他循环的解决方案,或者仅涉及几个非numpy函数,则这通常是最简单,最快的解决方案。

使用Numba的解决方案

您不必进行太多更改,我将pow函数更改为np.power,并对numpy中访问数组的方式进行了一些细微更改(这实际上不是必需的)。

import numba as nbimport numpy as np#performance-debug infoimport llvmlite.binding as llvmllvm.set_option('', '--debug-only=loop-vectorize')@nb.njit(fastmath=True)def Delta_Gaussf_nb(Nw, N_bd, N_kp, hw, width,eigv):    Delta_Gauss = np.zeros((Nw,N_kp,N_bd,N_bd),dtype=float)    for w1 in range(Nw):        for k1 in range(N_kp): for i1 in range(N_bd):     for j1 in range(N_bd):         if ( j1 >= i1 ):  Delta_Gauss[w1,k1,i1,j1] = np.exp(np.power((eigv[k1,j1]-eigv[k1,i1]-hw[w1])/width,2))    return Delta_Gauss

由于“如果”,SIMD向量化失败。在下一步中,我们可以将其删除(可能需要在njited函数外部进行调用

np.triu(Delta_Gauss)
)。我还并行化了功能。

@nb.njit(fastmath=True,parallel=True)def Delta_Gaussf_1(Nw, N_bd, N_kp, hw, width,eigv):    Delta_Gauss = np.zeros((Nw,N_kp,N_bd,N_bd),dtype=np.float64)    for w1 in nb.prange(Nw):        for k1 in range(N_kp): for i1 in range(N_bd):     for j1 in range(N_bd):         Delta_Gauss[w1,k1,i1,j1] = np.exp(np.power((eigv[k1,j1]-eigv[k1,i1]-hw[w1])/width,2))    return Delta_Gauss

性能

Nw = 20N_bd = 20N_kp = 20width=20hw = np.linspace(0., 1.0, Nw) eigv = np.zeros((N_kp, N_bd),dtype=np.float)Your version:0.5sfirst_compiled version: 1.37msparallel version:       0.55ms

这些简单的优化可以使速度提高约1000倍。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/517182.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号