El trasfondo: Estoy construyendo un trie para representar un diccionario, usando un algoritmo de construcción mínimo. La lista de entrada es de 4.3M utf-8 strings, ordenados lexicográficamente. El gráfico resultante es acíclico y tiene una profundidad máxima de 638 nodos. La primera línea de mi script establece el límite de recursión en 1100 a través de sys.setrecursionlimit()
.Tocando la máxima profundidad de recursión usando Pickle/cPickle
El problema: me gustaría poder serializar mi trie en el disco, por lo que puedo cargarlo en la memoria sin tener que reconstruir desde cero (aproximadamente 22 minutos). He intentado ambos pickle.dump()
y cPickle.dump()
, con el texto y los protocolos binarios. Cada vez, me sale una pila-huella que tiene el siguiente aspecto:
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 649, in save_dict
self._batch_setitems(obj.iteritems())
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 663, in _batch_setitems
save(v)
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 725, in save_inst
save(stuff)
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 648, in save_dict
self.memoize(obj)
RuntimeError: maximum recursion depth exceeded
Mis estructuras de datos son relativamente simples: trie
contiene una referencia a un estado de inicio, y define algunos métodos. dfa_state
contiene un campo booleano, un campo de cadena y una asignación de diccionario de etiqueta a estado.
No estoy muy familiarizado con el funcionamiento interno de pickle
- ¿mi profundidad de recursión máxima debe ser mayor/igual n veces la profundidad del trie para algunos n? ¿O podría ser causado por algo más que desconozco?
Actualización: Establecer la profundidad de recursión en 3000 no ayudó, por lo que esta avenida no parece prometedora.
Actualización 2: Tenían razón; Estaba siendo miope al suponer que Pickle usaría una profundidad de anidamiento pequeña debido a las limitaciones de recursión predeterminadas. 10,000 hizo el truco.
He encontrado que aumentar el límite de recursión tiene un fuerte impacto en el uso de la memoria ... – fccoelho
http://svn.python.org/projects/python/trunk/Tools/scripts/find_recursionlimit.py puede ayudarlo a encontrar la parte superior límite de su hardware – Ullullu