Hash consing

In computer science, particularly in functional programming, hash consing is a technique used to share values that are structurally equal. The term hash consing originates from implementations of Lisp[1][2] that attempt to reuse cons cells that have been constructed before, avoiding the penalty of memory allocation. Hash consing is most commonly implemented with hash tables storing weak references that may be garbage-collected when the data stored therein contains no references from outside the table.[3][4] Hash consing has been shown to give dramatic performance improvementsboth space and timefor symbolic and dynamic programming algorithms. An interesting property of hash consing is that two structures can be tested for equality in constant time, which in turn can improve efficiency of divide and conquer algorithms when data sets contain overlapping blocks.[5]

Example

Simple, not very efficient, but suitable for demonstration of the concept implementation of a memoizer by means of hash table and weak references in Scheme:

;; weak hashes
;;
(require 'hash-table)

(define (make-weak-table . args)
  (apply make-hash-table args))

(define (weak-table-set! table key data)
  (let ((w (hash-table-ref table key #f)))
    (if w
        (vector-set! w 0 data)
      (let ((w (make-weak-vector 1)))
        (vector-set! w 0 data)
        (hash-table-set! table key w)))))

(define (weak-table-ref table key)
  (let ((w (hash-table-ref table key #f)))
    (if w
        (vector-ref w 0)
      #f)))

;; memoizer factory: for given (side-effect-free) procedure,
;; return a procedure which does the same memoizing some of results
;; in the sense of equal? on the whole list of args
;;
(define (make-weak-memoizer proc)
  (let ((cache (make-weak-table equal?)))
    (lambda args
      (let ((x (weak-table-ref cache args)))
        (if (bwp-object? x)
            (let ((r (apply proc args)))
              (weak-table-set! cache args r)
              r)
          x)))))
gollark: Why would it be a good thing, I mean.
gollark: Why?
gollark: Yes, potatOS has a process system, and it's standalone. Nobody noticed, as usual.
gollark: Perhaps if I hook up that uncool HTTP backend to skynet or something, add more backdoors, run the GUI on the potatOS process system, and add it as an autobundled program it'll be better.
gollark: znepotatobOS?

See also

References

  1. Deutsch, Laurence Peter (1973). "An Interactive Program Verifier". Palo Alto: Xerox Palo Alto Research Center Terhnical Report CSL-73-1. Cite journal requires |journal= (help)
  2. Goto, Eiichi (1974). "Monocopy and associative algorithms in extended Lisp". Tokyo: University of Tokyo Technical Report TR 74-03. Cite journal requires |journal= (help)
  3. Allen, John (1978). Anatomy of Lisp. McGraw Hill. ISBN 0-07-001115-X.
  4. Fillâtre, Jean-Christophe; Conchon, Sylvain (2006). "Type-Safe Modular Hash-Consing". Workshop on ML. ACM.
  5. Liljenzin, Olle (2013). "Confluently Persistent Sets and Maps". arXiv:1301.3388. Bibcode:2013arXiv1301.3388L. Cite journal requires |journal= (help)

Further reading

  • Ershov, A.P. (1958). "On programming of arithmetic operations". Communications of the ACM. 1 (8): 3–6. doi:10.1145/368892.368907.
  • Jean Goubault. Implementing Functional Languages with Fast Equality, Sets and Maps: an Exercise in Hash Consing. In Journées Francophones des Langages Applicatifs (JFLA’93), pages 222–238, Annecy, February 1993.


This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.