【问题标题】:copy.deepcopy or create a new object?copy.deepcopy 还是创建一个新对象?
【发布时间】:2013-04-25 09:58:00
【问题描述】:

我正在开发一个实时应用程序,有时我需要为始终使用相同数据的新对象创建实例。

首先,我只是将它们实例化,但后来我意识到使用copy.deepcopy 可能会更快。现在,我发现有人说deepcopy 非常慢。

我不能简单地使用copy.copy,因为我的对象有列表。

我的问题是,您知道更快的方法还是我只需要放弃并再次实例化它们? 感谢您的宝贵时间

【问题讨论】:

  • 我想知道,如果我只是在这些对象中添加一个 'def __copy__(self):' 并复制回我在这些对象中的这些列表呢?
  • deepcopy 只是在结构上递归并创建新实例。它很聪明地避免了无限循环,并且可以自定义,仅此而已。
  • 所以deepcopy 将检查您的所有列表值以查看它们是否也需要复制; __copy__ 创建列表的新副本将有助于避免这种情况,是的。

标签: python real-time


【解决方案1】:

我相信copy.deepcopy() 仍然是纯 Python,因此不太可能给您带来任何速度提升。

在我看来,这有点像早期优化的经典案例。我建议您编写直观的代码,在我看来,这只是实例化每个对象。然后,您可以对其进行分析,并查看需要在哪里节省开支(如果有的话)。在您的实际用例中,一些完全不同的代码很可能会成为瓶颈。

编辑: 我在原始答案中忘记提及的一件事 - 如果您要复制列表,请确保使用切片表示法 (new_list = old_list[:]) 而不是遍历它在 Python 中,这会更慢。但是,这不会进行深层复制,因此如果您的列表有其他列表或字典,则需要使用 deepcopy()。对于dict 对象,使用copy() 方法。

如果您仍然发现构建对象需要花费时间,那么您可以考虑如何加快速度。您可以尝试使用__slots__,尽管它们通常是为了节省内存而不是 CPU 时间,所以我怀疑他们会为您买多少。在极端情况下,您可以将对象推送到 C 扩展模块,这可能会更快,但会增加复杂性。这一直是我过去采用的方法,我在底层使用原生 C 数据结构,并使用 Python 的特殊方法在顶部包装“类似列表”或“类似字典”的接口。当然,这确实取决于您是否对 C 编码感到满意。

(顺便说一句,除非你有令人信服的理由,否则我会避免使用 C++,C++ Python 扩展比普通 C 更容易构建 - 但是,如果你有良好的动机,这是完全可能的)

例如,如果您的对象有很长的列表,那么您可能从一种写时复制方法中获得一些好处,其中对象的克隆只保留相同的引用而不是复制列表。每次访问它们时,您都可以使用sys.getrefcount() 查看就地更新是否安全或是否需要复制。这种方法可能容易出错且过于复杂,但我想我会出于兴趣而提及它。

您还可以查看您的对象层次结构,看看您是否可以分解对象,以便可以在其他对象之间共享不需要复制的部分。同样,您在修改此类共享对象时需要小心。

然而,重要的一点是,您首先想让您的代码正确,然后然后让您的代码快速 一旦你从现实世界的使用中了解了做到这一点的最佳方法。

【讨论】:

    猜你喜欢
    • 2012-07-15
    • 2011-11-28
    • 1970-01-01
    • 2012-07-07
    • 2019-09-23
    • 2019-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多