variable lista library example dict deepcopy python optimization deep-copy

lista - python deepcopy example



deepcopy() es extremadamente lento (3)

En realidad, la copia profunda es muy lenta. Pero podemos usar json, ujson o cPickle. podemos usar json / cPickle para volcar un objeto y cargarlo más tarde. Esta es mi prueba:

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))

como lo que podemos ver, json / ujson / cPickle es más rápido que deepcopy, pero pickle ...

Tengo un estado de juego en Python con aproximadamente 1000 objetos (sistemas planetarios + estrellas + planetas), y necesito copiarlo y aplicarle un montón de transformaciones cuando lo solicite. Sin embargo, a aproximadamente 1 solicitud / segundo, esto está ocupando el 24.63% de mi tiempo de ejecución . ¿Cómo puedo hacerlo rápido? Tenga en cuenta que copiar menos no es una opción, ya que las transformaciones tocan prácticamente todo.

EDITAR : bajó al 8% con la implementación juiciosa de __deepcopy__ en las cosas. Aún así, no es lo suficientemente bueno. (Lo suficientemente bueno es 1% o menos, planeo arrojar muchas más cosas a esto.) timeit dice 41.8ms por deepcopy() .


Puede proporcionar sus propias funciones de copia a los objetos de modo que no necesite una copia en profundidad. Deep Copy inspecciona cada objeto para verificar lo que se debe copiar. Esta es una operación costosa.


Si crea su propia clase para contener estos objetos, puede crear sus propios métodos que funcionan con copia y copia profunda. http://www.rafekettler.com/magicmethods.html#copying (Enlace roto)

Nuevo enlace para un repositorio de 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))

Aquí hay una descripción similar del enlace roto anterior.

Proceso de copiar

A veces, especialmente cuando se trata de objetos mutables, quiere poder copiar un objeto y hacer cambios sin afectar lo que ha copiado. Aquí es donde entra en juego la copia de Python. Sin embargo (afortunadamente), los módulos de Python no son sensibles, por lo que no tenemos que preocuparnos por un levantamiento de robots basado en Linux, pero sí tenemos que decirle a Python cómo copiar cosas de manera eficiente.

__copy__(self)

Define el comportamiento de copy.copy () para las instancias de su clase. copy.copy () devuelve una copia poco profunda de su objeto; esto significa que, aunque la instancia en sí es una instancia nueva, se hace referencia a todos sus datos, es decir, el objeto mismo se copia, pero sus datos aún se referencian ( y, por lo tanto, los cambios en los datos en una copia superficial pueden causar cambios en el original).

__deepcopy__(self, memodict={})

Define el comportamiento de copy.deepcopy () para las instancias de su clase. copy.deepcopy () devuelve una copia profunda de su objeto: el objeto y sus datos se copian. memodict es un caché de objetos copiados anteriormente; esto optimiza la copia y evita la recursión infinita al copiar estructuras de datos recursivas. Cuando quiera copiar profundamente un atributo individual, llame a copy.deepcopy () en ese atributo con memodict como primer argumento. ¿Cuáles son algunos casos de uso para estos métodos mágicos? Como siempre, en cualquier caso en el que necesite un control más preciso que el que le ofrece el comportamiento predeterminado. Por ejemplo, si está intentando copiar un objeto que almacena un caché como un diccionario (que puede ser grande), no tiene sentido copiar también el caché; si el caché se puede compartir en la memoria entre instancias, entonces debería ser.