我有一个Python脚本,它包含一个循环,每个时间步骤调用scipy.optimize.fsolve (99次(55 + 54)次),现在我需要大约10^5次时间步骤。脚本的其余部分也不是很快,但据我所知,从Spyder的输出来看,对fast的调用是迄今为止最耗时的。使用我当前的设置,运行脚本需要超过10个小时,所以我可以稍微加快速度。
根据我在互联网上读到的内容,我已经第一次尝试了pypy :在conda (MacOS 10.15.5,PyPy 7.3.1和pypy3.6 7.3.1)下的一个单独环境中安装它,以及它自己版本的numpy、scipy和Pypy3.67.3.1,但到目前为止,它实际上比Python慢一些(195 s对171 s,耗时100步)。
从我所读到的这里 (PyPy Status博客,10月17日)来看,这可能与使用numpy而不是numpypy和/或重复分配临时数组有关。除了多次调用PyPy 10 million+之外,我还使用了相当多的numpy数组,所以据我所知,这是有意义的。
问题是,我不是一个开发人员,而且我对PyPy完全陌生,所以像JIT跟踪这样的术语对我来说没有多大意义,对我来说,破解其中的内容可能会很有挑战性。此外,过去在2017年10月发生的事情现在可能不再适用了。此外,即使我设法加快了numpy数组位,我仍然不确定sure部分。
有人能指出我是否值得在PyPy上投资时间吗?还是Cython在这种情况下更适合呢?甚至是mpi4py?
如果这有帮助的话,我很乐意分享我的代码,但是它包含了800多行代码,所以仅仅把它包含在这篇文章中对我来说并不是一个好主意。
非常感谢!西塔
编辑:感谢大家的快速和友好的回应!这是一个公平的观点,关于需要查看我的代码,我说它是这里 (链接有效期到2020年6月19日)。Arterial_1D.py是模块,CoronaryTree.py是调用Arterial_1D.py的脚本。对于一个最小的工作示例,我添加了一个额外的行,在这种情况下不加注释(在代码中明确标记)。此外,我将时间步骤数设置为100,以使代码在合理的时间内运行(在我的示例中,最小示例为0.61 s,完整冠状树为37.3 s)。
编辑2:我很傻,在我最初的文章中,我提到了分别使用PyPy和Python运行100步代码的197次和171次,但在这种情况下,我在PyPy环境中调用了PyPy,所以它使用了PyPy版本的Numpy。在我的基本环境中,运行100个步骤需要30多个步骤,所以在本例中,PyPy比Python慢得多,这促使我查看这个PyPy状态博客文章。
发布于 2020-06-11 13:52:28
如果不查看代码,我们就无法真正帮助您进行优化。但是既然你已经有了很好的描述,让我用我认为你可以尝试加速的东西来回答。
第一件事是第一件事。来自于scipy.optimize.fsolve的源代码,它封装了MINPACK的hybrd和hybrj算法,它们是相当快的FORTRAN子程序。因此,在您的例子中,切换到PyPy将不会有多大的好处,如果对这个已确定的瓶颈有任何帮助的话。
,你能做些什么来优化你的程序?,最明显的数字事情之一就是矢量化你的函数的args。但是似乎你在运行一种时间步长算法,而大多数标准的时间步进算法都无法在时间上向量化。如果您的“每一时间步骤XX次”是一种隐式的空间循环(即网格),您可以考虑将其矢量化以实现一些速度上的提高。下一步是放大函数的猜测/启动根估计。看看你的算法是否可以在整个时间间隔内利用一个好的开始解决方案(做一些文献挖掘)。请注意,与其说这与“编程”有关,不如说与您对数值方法的了解有关。
接下来,在您关于“脚本的其余部分也不太快”的评论中,我将使用来处理代码中剩下的python部分,特别是循环。它是非常积极的发展,伟大的社区和战斗考验。我个人曾在许多HPC型问题上使用过它。Cython还有一个方便的html注释,它突出了在本机python实现上可能实现的潜在优化。
希望这能有所帮助!干杯
https://stackoverflow.com/questions/62324869
复制相似问题