2011-05-24 54 views
6

Se me ha asignado la tarea de leer un archivo .txt que es un registro de varios eventos y escribir algunos de esos eventos en un diccionario.Consumo de memoria del módulo Python Shelve

El problema es que el archivo a veces puede tener más de 3 GB de tamaño. Esto significa que el diccionario se vuelve demasiado grande para caber en la memoria principal. Parece que Shelve es una buena forma de resolver este problema. Sin embargo, dado que modificaré constantemente el diccionario, debo tener habilitada la opción writeback. Esto es lo que me preocupa: el tutorial dice que esto ralentizaría el proceso de lectura/escritura y usaría más memoria, pero no puedo encontrar estadísticas sobre cómo se ven afectados la velocidad y la memoria.

¿Alguien puede aclarar cuánto se ven afectados la velocidad de lectura/escritura y la memoria para que yo pueda decidir si usar la opción de reescritura o sacrificar algo de legibilidad para la eficiencia del código?

Gracias

+1

que depende de lo que está haciendo con el diccionario: si sólo se necesita modificar mediante la sustitución de los valores ('estantería [ 'clave'] = newvalue') No, lo hace necesita escribir de nuevo. Si está modificando tipos mutables en él ('shelf ['key']. Append (x)', necesita writeback. Por supuesto, puede dejar writeback off y siempre recuerde modificar y reemplazar valores en su estante, si Prefiero –

+0

Solo necesito agregar pares de clave y valor. Pero como estoy trabajando con diccionarios anidados, también agregaré k, v pares a los caracteres internos. – inspectorG4dget

+0

¿Puedes escribirlo para que siempre obtengas un valor? del estante, agréguelo a cualquier nivel, y luego colóquelo en el estante? –

Respuesta

1

Para bases de datos de este tamaño, de lado realmente es la herramienta equivocada. Si usted no necesita una arquitectura/servidor cliente altamente disponible , y lo que desea convertir el archivo TXT a una base de datos en memoria accesible locales, que realmente debería estar usando ZODB

Si necesita algo altamente disponible, por supuesto tendrá que cambiar a una base de datos formal "NoSQL", de la cual hay muchas para elegir.

Aquí hay un ejemplo simple de cómo convertir su base de datos shelve a una base de datos ZODB que resolverá sus problemas de uso/rendimiento de la memoria.

#!/usr/bin/env python 
 
import shelve 
 
import ZODB, ZODB.FileStorage 
 
import transaction 
 
from optparse import OptionParser 
 
import os 
 
import sys 
 
import re 
 

 
reload(sys) 
 
sys.setdefaultencoding("utf-8") 
 

 
parser = OptionParser() 
 

 
parser.add_option("-o", "--output", dest = "out_file", default = False, help ="original shelve database filename") 
 
parser.add_option("-i", "--input", dest = "in_file", default = False, help ="new zodb database filename") 
 

 
parser.set_defaults() 
 
options, args = parser.parse_args() 
 

 
if options.in_file == False or options.out_file == False : 
 
    print "Need input and output database filenames" 
 
    exit(1) 
 

 
db = shelve.open(options.in_file, writeback=True) 
 
zstorage = ZODB.FileStorage.FileStorage(options.out_file) 
 
zdb = ZODB.DB(zstorage) 
 
zconnection = zdb.open() 
 
newdb = zconnection.root() 
 

 
for key, value in db.iteritems() : 
 
    print "Copying key: " + str(key) 
 
    newdb[key] = value 
 
                                                   
 
transaction.commit()

Cuestiones relacionadas