copy.deepcopy还是创建一个新对象?

时间:2013-04-25 09:58:00

标签: python real-time

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

首先,我做了它只是实例化它们,但后来我意识到可能用copy.deepcopy它会更快。现在,我发现那些说deepcopy非常缓慢的人。

我无法简单地copy.copy,因为我的对象有列表。

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

1 个答案:

答案 0 :(得分:3)

我相信copy.deepcopy()仍然是纯粹的Python,因此它不太可能为你提供任何速度提升。

听起来有点像早期优化的经典案例。我建议你编写的代码是直观的,在我看来,它只是简单地实例化每个对象。然后,您可以对其进行分析,并查看需要节省的资金(如果有的话)。很可能在你的真实用例中,一些完全不同的代码片段将成为瓶颈。

编辑: 我在原始答案中忘记了一件事 - 如果您要复制列表,请确保使用切片表示法(new_list = old_list[:])而不是迭代通过它在Python中,这将更慢。但是,这不会执行深层复制,因此如果您的列表包含其他列表或词典,则需要使用deepcopy()。对于dict个对象,请使用copy()方法。

如果您仍然发现构建您的对象是花费时间的话,那么您可以考虑如何加速它。你可以尝试使用__slots__,虽然它们通常是为了节省内存而不是CPU时间,所以我怀疑他们会给你买多少钱。在极端情况下,您可以将对象推送到C扩展模块,这可能会以更高的复杂性为代价更快。这始终是我过去采用的方法,我在底层使用本机C数据结构,并使用Python的特殊方法在顶部包装“类似列表”或“类似dict”的界面。当然,这确实取决于你对使用C编码感到满意。

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

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

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

重要的一点是,首先希望让代码正确 然后 让代码快速< / em>一旦您了解了从现实世界中使用的最佳方法。