2010-08-06 5 views
5

Estoy tratando de adaptar la estructura subyacente del código de trazado (matplotlib) que se actualiza en un temporizador para pasar de usar listas de Python para los datos de trazado a utilizar matrices numpy. Quiero poder bajar el paso del tiempo para la trama tanto como sea posible, y dado que los datos pueden subir a los miles de puntos, empiezo a perder un tiempo valioso rápidamente si no puedo. Sé que los arreglos numpy son preferidos para este tipo de cosas, pero estoy teniendo problemas para saber cuándo tengo que pensar como un programador de Python y cuando necesito pensar como un programador de C++ maximizo mi eficiencia de acceso a la memoria.¿Cómo se agrega y elimina la colección de basura Pythonic con matriz numpy?

Dice en los documentos scipy.org para la función append() que devuelve una copia de las matrices anexadas. ¿Todas estas copias se recogen basura correctamente? Por ejemplo:

import numpy as np 

a = np.arange(10) 
a = np.append(a,10) 
print a

Esta es mi lectura de lo que está pasando en el C++ - nivel, pero si sabía lo que estaba hablando, yo no estaría haciendo la pregunta, así que por favor me corrija si me '¡Estoy mal! = P

Primero se asigna un bloque de 10 enteros, y el símbolo a apunta al comienzo de ese bloque. Luego se asigna un nuevo bloque de 11 enteros, para un total de 21 ints (84 bytes) que se utilizan. Luego, el puntero a se mueve al inicio del bloque 11-int. Supongo que esto daría como resultado que el algoritmo de recolección de basura redujera a cero el recuento de referencias del bloque 10-int y lo desasignara. ¿Es esto correcto? Si no, ¿cómo me aseguro de no crear gastos generales cuando anexo?

Tampoco estoy seguro de cómo eliminar correctamente una matriz numpy cuando termino de usarla. Tengo un botón de reinicio en mis trazados que simplemente vacía todos los datos y comienza de nuevo. Cuando tenía listas, esto se hacía usando del data[:]. ¿Hay una función equivalente para las matrices numpy? ¿O debería simplemente decir data = np.array ([]) y contar con el recolector de basura para hacer el trabajo por mí?

Respuesta

10

El objetivo de la gestión automática de memoria es que no lo piense más. En el código que usted escribió, las copias serán recogidas basura (es casi imposible confundir la administración de memoria de Python). Sin embargo, debido a que np.append no está en su lugar, el código creará una nueva matriz en la memoria (que contiene la concatenación de a y 10) y luego la variable a se actualizará para apuntar a esta nueva matriz. Dado que a ahora ya no apunta a la matriz original, que tuvo un recuento de ref. 1, su refcount se reduce a 0 y se limpiará automáticamente. Puede usar gc.collect para forzar una limpieza completa.

La fortaleza de Python no reside en afinar el acceso a la memoria, aunque sí es posible optimizarla. Probablemente esté mejor ordenado preasignando a (usando, por ejemplo, a = np.zeros(<size>)); si necesitas un ajuste más fino que ese, comienza a ponerse un poco peludo. Puede echar un vistazo a Cython + Numpy tutorial por una forma muy simple y fácil de integrar C con Python para mayor eficiencia.

Las variables en Python solo apuntan a la ubicación donde se almacenan sus contenidos; puede del cualquier variable y disminuirá el recuento de referencia de su objetivo en uno. El objetivo se limpiará automáticamente después de que su recuento de referencia llegue a cero. La moraleja de esto es que no te preocupes por limpiar tu memoria. Sucederá automáticamente

+0

Así que básicamente tengo que relajarme. =) Gracias por la aclaración, pensé que así era como funcionaban las cosas, pero no estaba 100% claro al respecto. – pr0crastin8r

Cuestiones relacionadas