我有一个小部件的树状结构,例如集合包含模型,模型包含小部件。我想复制整个集合,与对对象进行“刺穿和去刺穿”相比,copy.deepcopy
更快,但是cPickle因为用C语言编写要快得多,所以
示例测试代码:
import copy
import pickle
import cPickle
class A(object): pass
d = {}
for i in range(1000):
d[i] = A()
def copy1():
return copy.deepcopy(d)
def copy2():
return pickle.loads(pickle.dumps(d, -1))
def copy3():
return cPickle.loads(cPickle.dumps(d, -1))
时间:
>python -m timeit -s "import c" "c.copy1()"
10 loops, best of 3: 46.3 msec per loop
>python -m timeit -s "import c" "c.copy2()"
10 loops, best of 3: 93.3 msec per loop
>python -m timeit -s "import c" "c.copy3()"
100 loops, best of 3: 17.1 msec per loop
最佳答案
问题是,pickle + unpickle可以更快(在C实现中),因为它不如Deepcopy通用:许多对象可以被深度复制但不能被酸洗。例如,假设您的类A
更改为...:
class A(object):
class B(object): pass
def __init__(self): self.b = self.B()
现在,
copy1
仍然可以正常工作(A的复杂性使其速度降低,但绝对不能阻止它); copy2
和copy3
中断,堆栈跟踪的末尾显示...: File "./c.py", line 20, in copy3
return cPickle.loads(cPickle.dumps(d, -1))
PicklingError: Can't pickle <class 'c.B'>: attribute lookup c.B failed
也就是说,酸洗总是假定类和函数是其模块中的顶级实体,因此,“按名称”对它们进行酸洗-深度复制绝对没有这样的假设。
因此,如果您遇到“某种程度的深度复制”速度绝对至关重要的情况,那么每一毫秒都很重要,并且您想利用您知道要应用于复制对象的特殊限制,例如进行酸洗的那些适用的方法,或赞成其他形式的序列化和其他快捷方式的方法,请务必继续进行-但是,如果您这样做,则必须意识到您将使系统永远受限于这些限制,并非常清楚地记录该设计决策,并明确地为 future 维护者的利益。
对于需要通用性的NORMAL情况,请使用
deepcopy
!-)关于python - copy.deepcopy与 pickle ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1410615/