Ele*_*tro 26 python optimization deep-copy
我在Python中有一个游戏状态,有大约1000个对象(行星系统+星星+行星),我需要复制它并在请求时应用一堆变换.但是,在大约1个请求/秒时,这占我运行时的24.63%.我怎样才能让它变得快速?请注意,复制较少不是一个选项,因为变换几乎触及所有内容.
编辑:通过明智的实施来降低到8%__deepcopy__.不过,还不够好.(足够好是1%或更少,我计划在此投掷更多的东西.)timeit说每个41.8ms deepcopy().
che*_*ish 35
实际上,深度显示非常慢.但我们可以使用json,ujson或cPickle.我们可以使用json/cPickle来转储对象,并在以后加载它.这是我的测试:
Total time: 3.46068 s
File: test_deepcopy.py
Function: test at line 15
Line # Hits Time Per Hit % Time Line Contents
==============================================================
15 @profile
16 def test():
17 100 957585 9575.9 27.7 b = deepcopy(a)
18 100 862 8.6 0.0 c = copy(a)
19 100 42295 422.9 1.2 d = ujson.loads(ujson.dumps(a))
20 100 85040 850.4 2.5 e = json.loads(json.dumps(a))
21 100 2323465 23234.7 67.1 f = pickle.loads(pickle.dumps(a, -1))
22 100 51434 514.3 1.5 g = cPickle.loads(cPickle.dumps(a, -1))
Run Code Online (Sandbox Code Playgroud)
正如我们所看到的,json/ujson/cPickle比deepcopy更快,但是pickle ......
如果创建自己的类来容纳这些对象,则可以创建自己的用于复制和深度复制的方法。http://www.rafekettler.com/magicmethods.html#copying(链接断开)
github存储库的新链接https://github.com/RafeKettler/magicmethods
class MyClass():
def __copy__(self):
copy_object = MyClass()
return copy_object
def __deepcopy__(self, memodict={}):
copy_object = MyClass()
copy_object.value = self.value
return copy_object
if __name__ == "__main__":
my_inst = MyClass()
print(copy.deepcopy(my_inst))
Run Code Online (Sandbox Code Playgroud)
这是来自先前断开链接的类似描述。
复制中
有时,尤其是在处理可变对象时,您希望能够复制对象并进行更改而不影响复制对象。这就是Python副本发挥作用的地方。但是(幸运的是),Python模块不是有感觉的,因此我们不必担心基于Linux的机器人起义,但是我们必须告诉Python如何有效地复制内容。
__copy__(self)
为类的实例定义copy.copy()的行为。copy.copy()返回对象的浅表副本-这意味着,尽管实例本身是一个新实例,但其所有数据都被引用了-即,对象本身已被复制,但其数据仍被引用了(因此更改浅表副本中的数据可能会导致原始文件的更改)。
__deepcopy__(self, memodict={})
为类的实例定义copy.deepcopy()的行为。copy.deepcopy()返回对象的深层副本-对象及其数据均被复制。memodict是先前复制对象的缓存-优化复制并防止在复制递归数据结构时进行无限递归。当您想深层复制单个属性时,请以该属性作为第一个参数调用该属性的copy.deepcopy()。这些魔术方法有哪些用例?与往常一样,在任何情况下,您需要比默认行为所提供的控制更多的细粒度控制。例如,如果您尝试复制一个将缓存存储为字典的对象(可能很大),那么复制缓存也可能没有意义-如果可以在实例之间的内存中共享缓存,则它应该是。
您可以为对象提供自己的复制函数,这样您就不需要深层复制。深复制检查每个对象以检查需要复制的内容。这是一项昂贵的操作。