请问浅拷贝多次和深拷贝一次是否存在结果上的区别?

2019-12-05 17:18:22 +08:00
 Phishion

从结果来讲性能差别巨大,本质上 2 种方式拿到的都是完全不一样的副本才对。 那么是不是可以认为这跟列表推导一样是一种优化写法?如果这样的话,那么深拷贝的意义在哪呢?是为了极端条件下使用方便么?为什么比起手动递归性能损失那么多?

import time,copy
li = [i for i in range(10000000)]
xr = [i for i in range(10000000)]
li.append(xr)

# 方式 1:浅拷贝
st1 = time.process_time()
temp1 = copy.copy(li)
temp1[-1] = copy.copy(li[-1])
end1 = time.process_time()
 
# 方式 2:深拷贝
start2 = time.process_time()
temp3 = copy.deepcopy(li)
end2 = time.process_time()
 
print("方式 1 耗时:%s" % (end1 - st1))
print("方式 2 耗时:%s" % (end2 - start2))

`方式 1 耗时:0.2146999999999999

`方式 2 耗时:12.704364

2801 次点击
所在节点    Python
7 条回复
Heebe
2019-12-05 17:25:03 +08:00
那要看具体的业务逻辑需求
A.b.c
假设浅拷贝 A 到 B,那么复制的 B.b == A.b
如果是深拷贝,B.b != A.b,也就是子类会继续拷贝(可以认为是递归,直到所有都是结构体)
monsterxx03
2019-12-05 17:25:51 +08:00
l = [[1,2]]
l1 = l.copy()
l1[0][0] = 2
print(l1) # [[2,2]]
print(l) # [[2,2]]

浅拷贝不会复制嵌套的对象, 修改内部对象值,原对象也会变的
zixiaoguan
2019-12-05 17:27:58 +08:00
看你业务想要修改的数据在哪一层了,一般而言既然想修改的东西不想影响到其他,直接深拷贝就好啦,方便维护,不易出错。前端不要想太多的性能问题啦。
Heebe
2019-12-05 17:29:22 +08:00
@Heebe 补充,深拷贝和手写递归哪个性能优秀这个不用想,递归传递变量是已知变量名对象等,省略了查找和类型转换等,速度肯定会高一些的。所以,要看场景,如果是游戏服务器或者压力比较大的场景,有时候自己写一个会更加直接有效,如果是一些单机或者是不会太吃消耗的,深拷贝可以加快开发速度。另外还有一些场景,比如为止变量名、匿名等等。
Phishion
2019-12-05 17:30:01 +08:00
@monsterxx03 我知道不会复制嵌套对象,问题是我深拷贝处理性能非常差,浅拷贝手动递归和深拷贝在效果上一样的,但是性能节省非常多,这就很奇怪
zixiaoguan
2019-12-05 18:04:34 +08:00
通过调试这个属于时间复杂度的问题 具体你自己从 10W 开始调一下就知道了。因为深拷贝会给每个对象进行拷贝,而这个操作时遍历的,所以浅拷贝你的代码只拷贝 2 次,而深拷贝拷贝了 10000001 次。
zarte
2019-12-05 18:17:56 +08:00
深拷贝要分配空间并存入数据,浅拷贝只要指针指下。等你浅拷贝有问题的时候就需要深拷贝了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/626271

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX