¿Cómo acelerar la carga de tablas hash grandes?


7

Según tengo entendido por el manual (últimos párrafos de http://www.gnu.org/software/emacs/manual/html_node/elisp/Creating-Hash.html ) y la pregunta /programming/11745097 / en stackoverflow, se puede guardar una versión impresa de una tabla hash en el disco para cargarla para su uso posterior.

Por ejemplo, la versión impresa de una tabla hash creada por

(setq ht (make-hash-table :test 'equal))
(puthash "orange" 1 ht)
(puthash "apple" 2 ht)

es como sigue

#s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8 data ("orange" 1 "apple" 2))

¿Es esta versión impresa el mejor formato (por consideración de velocidad) que Emacs puede usar? ¿Existe un procedimiento especial para volver a formatear (compilar en bytes, cambiar) el formato impreso anterior a un formato mejor (quizás solo legible por máquina) para que Emacs cargue esta tabla hash más rápido. Si la respuesta es afirmativa, ¿cuáles son las formas de hacerlo?

Respuestas:


3

Sí, es el mejor formato (por consideración de velocidad).


Acepto tu juramento
Nombre

5

Tendrá que hacer hash e insertar cada valor sin importar qué, y a menos que esté lidiando con enormes tablas de hash, el tiempo empleado realmente no debería importar. Sin embargo, si sus tablas son grandes, entonces debe usar el :sizeparámetro para make-hash-tableque no se produzcan reasignaciones. Cuando una tabla hash alcanza el umbral, tener que reasignar un nuevo lugar en la memoria para poner los valores y volver a mostrar todas las entradas actuales será una gran pérdida de rendimiento.

Si sabe que está a punto de insertar 1 millón de entradas en una tabla hash, use (make-hash-table :size 1000000)

Considere el siguiente punto de referencia:

(benchmark 10
           '(let ((ht (make-hash-table :size 1000000)))
              (dotimes (n 1000000) (puthash n (1+ n) ht))
              ht))
"Elapsed time: 4.156233s (2.087411s in 10 GCs)"


(benchmark 10
           '(let ((ht (make-hash-table)))
              (dotimes (n 1000000) (puthash n (1+ n) ht))
              ht))
"Elapsed time: 10.276816s (7.713422s in 41 GCs)"

También puede definir su propia prueba y función hash para tablas hash. Si sabe que sus claves van a estar en un conjunto específico, podría escribir una igualdad más rápida y funciones de hashing que exploten eso. Ver: define-hash-table-test.


Comparación de tiempo muy interesante. Gracias. Como ha demostrado, establecer el tamaño de una tabla hash puede influir significativamente en su tiempo de creación.
Nombre

Sin embargo, permítanme mencionar que en la pregunta original, he preguntado sobre la velocidad desde un punto de vista ligeramente diferente. Ya he creado una tabla hash grande y ya he guardado esta tabla hash en el disco (por comando de impresión). Entonces tengo un archivo grande con cuyo contenido es similar #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8 data ("orange" 1 "apple" 2 ..............)). Puedo cargar esta tabla hash. Me interesó saber si este tipo de archivo es el mejor formato que Emacs puede usar para cargar rápidamente la tabla.
Nombre

Por lo tanto, el énfasis está más en el momento de cargar una tabla ya guardada en el disco que en el momento de la creación por primera vez.
Nombre
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.