为什么将我的模块分成多个文件会使它变慢?

2024-06-01 20:09:17 发布

您现在位置:Python中文网/ 问答频道 /正文

我制作了一个Python模块(^{}),直到最近,它还是一个包含许多类的大文件。在将相关类重构为单独的文件之后,所有的工作仍然正常,尽管速度慢了大约50%。我假设,如果有的话,它会更快一点,因为Python可以更有效地缓存每个文件的字节码,从而缩短启动时间。在

我用CPython运行这段代码(还没有用PyPy和它的同类测试过)。我在旧版本和重构版本上运行了line_profiler,重构前后每行所花费的处理时间百分比大致相同。在

以下是一些与我的程序有关的事情:

  • 它生成了很多像^{}这样的小类,实例化这些类可能很昂贵,尽管在重构之前这不是问题。在
  • 当创建这些类时,它从一个单独的文件中获取它们,它在一开始是import。在
  • 在耗时最长的部分(scalingmixing音频)中有很多基于numpy的数组操作
  • 如果在7.5秒内使用了三次以上,我有一个缓存来存储缩放后的笔记。(code

是什么原因导致我的代码在不做任何事情后变得更慢,只是将它分成多个文件?在


Tags: 模块文件代码版本字节line时间pypy
2条回答

你的重构似乎不仅仅是把类移到不同的文件中。例如,UncachedWavFile丢失了一个__setitem__方法。而且,在其他地方,魔法数字已经改变了。我建议你先去别处找减速器。在

我不认为将代码库重构为单独的文件在速度上有什么不同,只希望在启动时间上减少一点(甚至很小)。我建议在拆分之前进行分支,实际上只将代码分离到单独的文件中,分析代码的性能,然后慢慢添加拆分后添加的代码,每次都进行分析,看看是什么在减慢代码的速度。在

在进行了更多的基准测试之后,这是我所怀疑的事情之一:必须从另一个模块访问函数/类意味着对Python解释器的另一次查找,并且在一些紧密的循环中会出现轻微的减速。The Python wiki has something about this, too:

Avoiding dots...

Suppose you can't use map or a list comprehension? You may be stuck with the for loop. The for loop example has another inefficiency. Both newlist.append and word.upper are function references that are reevaluated each time through the loop. The original loop can be replaced with:

upper = str.upper
newlist = []
append = newlist.append
for word in oldlist:
    append(upper(word))

相关问题 更多 >