【问题标题】:Is there a more efficient way to allocate lots of instances of a class in a loop?有没有更有效的方法在循环中分配大量的类实例?
【发布时间】:2017-05-19 19:21:28
【问题描述】:

我正在编写一个 Python 程序,并且有一个导致性能问题的内部循环。我在上面运行了一个分析器,我发现 50% 的时间都花在了对象分配上。基本上是这样的:

result_list = []
for i in range(BIG_NUMBER):
    obj = MyClass()
    # do stuff with obj...
    result_list.append(obj)

obj = MyClass() 行占用了 50% 的时间。有没有办法在 Python 中有效地分配大量这些对象?也许是某种批量分配?

无需复制/粘贴整个MyClass,具有以下特点:

  • 它是一个 ORM 对象,所以它基本上将属性映射到数据库值
  • 它有很多属性函数、一个元类等,所以它是一个相当“胖”的类

# do stuff with obj... 行主要设置各种属性,通常通过setattr,但在少数情况下通过自定义函数。所以如果有 10 个属性需要设置,9 个通常是通过setattr,而 1 个可能是通过一个特殊的函数。这部分需要大约 40% 的时间,我正在单独对其进行优化。

【问题讨论】:

  • 你能加# do stuff with obj...吗,这对回答问题很重要。
  • 它还取决于 MyClass - 它可以使用 __slots__ 吗?子类namedtuple?
  • 这种性能开销是由于函数调用本质上是昂贵的。 MyClass() 调用元类的 __calll__ 方法,该方法反过来又调用类的 __new____init__。三个级别的函数调用来创建MyClass 对象的实例,这就是为什么需要更长的时间。
  • 一个 ORM 可以做很多隐藏的工作。例如,如果您不需要验证,也许您可​​以尝试禁用或绕过它(直接写入其隐藏的存储结构)。
  • 什么是MyClass.__init__?如果初始化需要一半的时间,我认为初始化代码是最相关的。

标签: python performance


【解决方案1】:

如果对象从一个空的构造函数调用开始,如果循环,你能不把它拉出​​来吗?然后copy.deepcopy你的种子对象?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-28
    • 2017-12-27
    • 2022-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多