【问题标题】:How can I efficiently call a function in a loop with python?如何使用 python 在循环中有效地调用函数?
【发布时间】:2021-02-14 14:03:12
【问题描述】:

我正在求解一个随机微分方程,并且我有一个包含求解它的算法的函数。所以我必须在每个时间步调用该函数(它类似于 Runge Kutta 的方法,但使用随机变量),然后我必须多次求解方程(因为解是随机的)才能使所有的平均值解决方案。这就是为什么我想知道如何在每次迭代中以最有效的方式调用这个函数。

【问题讨论】:

  • 只有一种方法可以调用函数。此外,完全不使用函数会稍微快一些。你能详细说明一下这个函数的作用吗?
  • 你能澄清你的问题吗?在循环中调用函数只有一种明显的方法,这是最有效的方法。您是否正在尝试做一些相关但不同的事情,例如在容器中的每个元素上调用一个函数?
  • 为什么要循环调用函数?你能详细说明你的用例吗?
  • 我正在求解一个随机微分方程,并且我有一个包含求解它的算法的函数。所以我必须在每个时间步调用该函数(它类似于 Runge Kutta 的方法,但使用随机变量),然后我必须多次求解方程(因为解是随机的)才能使所有的平均值解决方案。这就是为什么我想知道如何在每次迭代中以最有效的方式调用这个函数。
  • 从您的描述来看,呼叫行为似乎与性能无关。可能是您正在寻找并行性或编译。但是,无法肯定地说。您可能需要查看How to Askminimal reproducible example 帮助页面来提出更集中的问题。

标签: python performance function loops call


【解决方案1】:

一些优化函数调用的方法:

  • 如果函数参数和结果始终相同,则将函数调用移出循环
  • 如果某些函数参数重复并且给定参数集的结果相同,请使用 memoize 或 lru_cache

但是,既然您说您的应用程序是 Runge-Kutta 的变体,那么这些都不可能起作用;您将拥有不同的 t 值和建模状态向量,因此您必须在循环中调用该函数,并且这些值会不断变化。

如果您的算法很慢,那么您进行函数调用的效率就无关紧要了。着眼于优化函数以使其运行得更快(或转换为 Cython)——实际调用本身并不是瓶颈。

编辑:我看到您多次运行此程序,以确定此模拟的随机性质的一系列值。在这种情况下,您应该使用多处理在不同的 CPU 内核上运行多个模拟 - 这会加快一些速度。

【讨论】:

    【解决方案2】:

    如果您使用for 循环和range(),并且不会使用每次迭代附带的数字,则可以使用下划线来节省一些效率:

    for _ in range(100):
        print("Function call")
    

    如果你只打算在循环中使用函数,你可以直接传入你正在使用的函数的内容,省去函数的定义,节省一些效率。

    【讨论】:

      【解决方案3】:

      根据您的用例,使用itertools.starmap() 可能更有利。您可以将starmap() 视为fastermap() 的多变量实现。你可以找到更多关于它的信息here。它的行为大致相当于:

      def starmap(function, iterable):
          # starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000
          for args in iterable:
              yield function(*args)
      

      所以你可以像这样使用它:

      from itertools import starmap
      
      def myAddNumbers(a,b):
          return a+b
      
      myListOfArgTuples = [(1,2), (3,4), (5,6)]
      cosmicCartograph = starmap(myAddNumbers, myListOfArgs)
      

      请注意,starmap() 返回一个生成器对象,因此为了“执行”生成器,您需要实例化它:

      myResultsList = list(cosmicCartograph)
      # [3, 7, 11]
      

      myResultsSummed = sum(cosmicCartograph)
      # 21
      

      【讨论】:

        【解决方案4】:

        在可迭代对象上实现函数的最佳方法是使用map 函数。

        由于map 是用 C 语言编写并经过高度优化,其内部隐含循环可以比常规 Python for 循环更高效。

        【讨论】:

          最近更新 更多