<< Back to previous view

[CLJ-1373] LazySeq should utilize cached hash from its underlying seq. Created: 09/Mar/14  Updated: 23/Jun/15

Status: Open
Project: Clojure
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Jozef Wagner Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: collections, performance
Environment:

1.6.0 master SNAPSHOT


Attachments: File clj-1373.diff    
Patch: Code
Approval: Triaged

 Description   

Even if underlying seq contains a cached hash, LazySeq computes it every time.

user=> *clojure-version*
{:major 1, :minor 7, :incremental 0, :qualifier "master", :interim true}
user=> (def a (range 100000))
#'user/a
user=> (time (hash a))
"Elapsed time: 21.812 msecs"
375952610
user=> (time (hash a))        ;; hash is cached
"Elapsed time: 0.036 msecs"
375952610
user=> (def b (seq a))
#'user/b
user=> (time (hash b))
"Elapsed time: 0.042 msecs"   ;; uses cached hash
375952610
user=> (def c (lazy-seq b))
#'user/c
user=> (time (hash c))        ;; SHOULD use underlying hash
"Elapsed time: 27.758 msecs"
375952610
user=> (time (hash c))        ;; SHOULD use underlying hash
"Elapsed time: 17.846 msecs"
375952610

Approach: If seq produced by LazySeq implementing IHashEq, use it to calculate the hasheq().
Patch: clj-1373.diff



 Comments   
Comment by Jozef Wagner [ 09/Mar/14 9:20 AM ]

Added patch which checks if underlying seq implements IHashEq and if yes, uses that hash instead of recomputing.

Comment by Alex Miller [ 04/May/15 9:34 AM ]

In this patch, can you update the else case (the original code) to use s rather than this, so seq() is not re-called?

Comment by Jozef Wagner [ 04/May/15 12:30 PM ]

Added patch [^clj-1373-2.diff] that reuses s for else case.

Comment by Alex Miller [ 23/Jun/15 2:15 PM ]

The -2 patch doesn't compile so I guess that was a bad suggestion.

Generated at Tue Jun 30 20:57:00 CDT 2015 using JIRA 4.4#649-r158309.