error OutOfMemory Python estantería
-
25-09-2019 - |
Pregunta
Tengo algunos datos almacenados en una base de datos que quiero proceso. el acceso DB es muy lento, por lo que decidí cargar todos los datos en un diccionario antes de cualquier transformación. Sin embargo, debido al enorme tamaño de los datos almacenados, me sale un error de falta de memoria (Veo más de 2 gigas siendo utilizados). Así que decidí usar una estructura de datos en disco, y descubrió que el uso de estantería es una opción. Esto es lo que hago (código Python pseudo)
def loadData():
if (#dict exists on disk):
d = shelve.open(name)
return d
else:
d = shelve.open(name, writeback=True)
#access DB and write data to dict
# d[key] = value
# or for mutable values
# oldValue = d[key]
# newValue = f(oldValue)
# d[key] = newValue
d.close()
d = shelve.open(name, writeback=True)
return d
Tengo un par de preguntas,
1) ¿Es realmente necesario el reescritura = verdad? ¿Qué hacer?
2) Todavía consigo una excepción OutofMemory, ya que no ejerce ningún control sobre cuando los datos se escriben en el disco. ¿Cómo puedo hacer eso? He intentado hacer una sincronización () cada pocas iteraciones, pero eso no ayuda tampoco.
Gracias!
Solución
fuerzas writeback=True
la plataforma para mantener en memoria cualquier artículo siempre tomó, y escribir de nuevo cuando el estante está cerrado. Por lo tanto, consume mucha más memoria, y reduce la velocidad de cierre.
La ventaja del parámetro es que, con ella, No necesita el código retorcido mostrar en su comentario para elementos mutables cuyos mutador es un método - sólo
shelf['foobar'].append(23)
funciona (si shelf
se abrió con reescritura habilitado), asumiendo el tema en 'foobar'
clave es una lista, por supuesto, aunque sería en silencio ser un no-operación (dejando el tema en el disco sin cambios) si shelf
se abrió sin reescritura - - en el último caso que realmente haces necesidad de código
thelist = shelf['foobar']
thelist.append(23)
shekf['foobar'] = thelist
en el espíritu de su comentario -. Que es estilísticamente un poco de un rollo
Sin embargo, puesto que son tener problemas de memoria, sin duda recomiendo no el uso de esta opción de reescritura dudosa. Creo que se puede llamar "dudosos", ya que yo era la primera propuesta y su aplicación, pero eso fue hace muchos años, y me he arrepentido mayoría de hacerlo - que GENERALES más confusión (como sus evidencias Q) de lo permite la elegancia y la practicidad en el código escrito originalmente para trabajar con predice en movimiento (que pueden utilizar el primer idioma, no el segundo, y por lo tanto necesita volver a escribir con el fin de ser utilizable con estantes sin rastreo). Ah, bueno, lo siento, no parece una buena idea en ese momento.
Otros consejos
Con el módulo de sqlite3
es probablemente su mejor opción aquí. Usted puede ser capaz de utilizar SQLite completamente en la memoria de todos modos ya que su consumo de memoria podría ser un poco más pequeño que el uso de objetos pitón de todos modos. Por lo general es una mejor opción que el uso de shelve
de todos modos; usos shelve
pickle
debajo, que no suele ser lo que quiera.
El infierno, sólo podría convertir toda su base de datos existente en una base de datos SQLite. SQLite es agradable y rápido.