【问题标题】:Passing too many arguments to a function in Python将太多参数传递给 Python 中的函数
【发布时间】:2020-10-29 16:02:54
【问题描述】:

我正在开发一个执行渗透系统蒙特卡罗模拟的程序(使用 python)。为了能够从 GUI (tkinter) 运行它并使用多个进程,我在 main() 函数中定义了模拟的主要部分。问题是,这个程序是一个物理模拟,它需要很多参数(10+)。从 main() 调用的一些函数也需要很多参数,并且被调用很多次。例如,在我的 main() 中,我有一个 generate_wire() 函数,它接受 8 个参数,例如 wires_mean_length、wires_distribution 等。这个被调用了数百万次。

这会影响程序的效率吗?是否应该修复它,如果是,如何修复?

编辑:代码基本结构如下:

def generate_wire("8 parameters"):
     "generating a wire according to the parameters"

def main("main parameters"):
     for _ in range(nbr_sim):
         while True:
         generate_wire("8 parameters taken from the main parameters")
         "Various calculations"
         if percolation is True:
             break

if __name__ == '__main__':
     "GUI code"
     "Run button calls the main function with parameters from GUI entries"

【问题讨论】:

  • 请展示一些代码或研究,是的,它可能会影响性能
  • 完成! Ty 为您解答
  • 现在我开始明白我对效率一无所知但是我知道多个参数可能不是问题,除非可能是为了组织并且如果计算过程没有以图形方式显示(可能只是结果) 那么它不应该是低效的,但是对于巨大的循环,它需要一些时间(不能准确地告诉多少,实际上可以测量)
  • 确实没有显示计算,只存储了结果。测量它是个好主意,我会试试看。
  • 我已经运行了 foo 函数 100,000 次。使用全局变量后,另一个将 15 个参数传递给函数。我没有得到两个过程之间的任何显着时间差异。当然,这并不能证明什么,但我认为这两种方法都相当有效。

标签: python performance arguments simulation python-internals


【解决方案1】:

实际上,与其他设计相比,这不会影响程序的运行时间

您可以将所有参数放入字典或自定义类中并传递它们以使逻辑更清晰

您可以将函数中的逻辑直接提升到循环中,这样可以减少查找发生的频率

More about local variable lookups

def generate_wire_wrapper("8 parameters"):
    for _ in range(nbr_sim):
        "logic to generate a wire"
        "various calculations"

def main("main parameters"):
    generate_wire_wrapper("8 parameters taken from the main parameters")

但是,改进设计将是您真正的盟友

与其在循环中调用数千次相同的函数,不如考虑

  • 使用某种pool of workers 进行并行处理
  • 利用(或在必要时编写)C 中的逻辑来提高操作效率 科学图书馆的映射方法这样做是为了提高效率,其中一部分也是通过每一步做更多的工作来避开 GIL(例如,Pandas dataframes .apply 方法就是这样做的)

【讨论】:

  • 谢谢!我曾考虑将它传递给字典,但想知道它是否真的会在效率方面产生影响
  • @Ethalides 可能与创建新文件并从中导入数据几乎相同,而且速度并不慢,或者我可能不知道 python 如何处理导入
  • 参数和字典等是按引用的,因此它们只会产生查找名称所指内容的成本。你会付出更多的代价来获得更多的论据和深度。但是,查找成本非常小,并且在使用函数 var 时效率更高(奇怪的是,将导入方法作为参数可以使它们更有效,因为它避开了查找)。
  • 感谢您的详尽回答!问题是我无法并行运行此函数,因为我需要在每次迭代时获得先前的结果(每次添加导线时,我都在检查是否存在渗透路径)。我喜欢包装解决方案!而且我肯定会研究熊猫,实际上我应该早点这样做。
  • @Ethalides 随时 - 如果您发现每个步骤都依赖于前一个步骤,则可能有一些方法可以一次计算更多并展开您的循环。如果你能做一个最小的例子,这可能是一个令人兴奋/有价值的问题! Pandas 及其df.apply 只是该技术的一个示例,因此它可能根本不适用。但如果您有大量数据,它当然可以为您提供一个很好的解决方案。
猜你喜欢
  • 1970-01-01
  • 2015-01-23
  • 1970-01-01
  • 1970-01-01
  • 2021-11-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多