Clojure

Widen set to take Iterable/IReduceInit

Details

  • Type: Enhancement Enhancement
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Completed
  • Affects Version/s: Release 1.7
  • Fix Version/s: Release 1.7
  • Component/s: None
  • Labels:
    None
  • Patch:
    Code
  • Approval:
    Ok

Description

Similar to CLJ-1546 (same thing on vec), set should work on IReducibleInit or Iterable. Currently eduction will work via Iterable but through SeqIterator. set on an IReduceInit will throw an error.

user=> (set (eduction (map inc) (range 100)))  ;; works, but slower path
user=> (set (reify clojure.lang.IReduceInit  
       (reduce [_ f start]
         (reduce f start (range 10)))))
IllegalArgumentException Don't know how to create ISeq from: user$eval1198$reify__1199  clojure.lang.RT.seqFrom (RT.java:506)

Approach: Check for and use IReduceInit path if available, otherwise fallback to seq. Additionally, the patch adds a modification to return a set without it's meta (same approach as CLJ-1546) if a set is passed, which is fast constant time with no change in effective behavior.

Performance: (using Criterium quick-bench)

Timings done with either (count (set coll)) or (count (into #{} coll)):

coll 1.6.0 into 1.6.0 set 1.7.0-alpha4 set 1.7.0-alpha4+patch set
(set (range 100)) 15.4 µs 17.0 µs 11.4 µs 0.0 µs
(vec (range 1000000)) 360.7 ms 702.5 ms 391.1 ms 358.6 ms
(doall (range 1000000)) 363.6 ms 736.9 ms 387.5 ms 371.0 ms
(doall (range 5)) 404.9 ns 612.3 ns 481.9 ns 445.9 ns
(eduction (map identity) (vec (range 100))) n/a n/a 11.3 µs 8.7 µs

See also: CLJ-1546, CLJ-1384

Patch: clj-1618.patch

Screened by:

Activity

Alex Miller made changes -
Field Original Value New Value
Fix Version/s Release 1.7 [ 10250 ]
Attachment clj-1618.patch [ 13633 ]
Approval Vetted [ 10003 ]
Alex Miller made changes -
Description Similar to CLJ-1546 (same thing on vec), set should work on IReducibleInit or Iterable. Currently eduction will work via Iterable but through SeqIterator. set on an IReduceInit will throw an error.

{code}
user=> (set (eduction (map inc) (range 100))) ;; works, but slower path
user=> (set (reify clojure.lang.IReduceInit
       (reduce [_ f start]
         (reduce f start (range 10)))))
IllegalArgumentException Don't know how to create ISeq from: user$eval1198$reify__1199 clojure.lang.RT.seqFrom (RT.java:506)
{code}

*Approach:* Check for and use IReduceInit path if available, otherwise fallback to seq. Additionally, the patch adds a modification to return a set without it's meta (same approach as CLJ-1546) if a set is passed, which is fast constant time with no change in effective behavior.

*Performance:* (using Criterium quick-bench)

{code}
(def small-set (set (range 100)))
(def big-range (doall (range 1000000)))
(def little-range (doall (range 5)))
{code}

|| Expression || 1.6.0 || 1.7.0-alpha4 || 1.7.0-alpha4 + patch ||
|(count (set small-set))|17.0 µs|11.4 µs |11.8 ns|
|(count (into #{} small-set))|15.4 µs|13.8 µs |13.1 µs|
|(count (set big-range))|736.9 ms|387.5 ms |371.0 ms|
|(count (into #{} big-range))|363.6 ms|373.1 ms |379.9 ms|
|(count (set little-range))|612.3 ns|481.9 ns |445.9 ns|
|(count (into #{} little-range))|404.9 ns|433.1 ns |409.9 ns|

*See also:* CLJ-1546, CLJ-1384

*Patch:*

*Screened by:*
Similar to CLJ-1546 (same thing on vec), set should work on IReducibleInit or Iterable. Currently eduction will work via Iterable but through SeqIterator. set on an IReduceInit will throw an error.

{code}
user=> (set (eduction (map inc) (range 100))) ;; works, but slower path
user=> (set (reify clojure.lang.IReduceInit
       (reduce [_ f start]
         (reduce f start (range 10)))))
IllegalArgumentException Don't know how to create ISeq from: user$eval1198$reify__1199 clojure.lang.RT.seqFrom (RT.java:506)
{code}

*Approach:* Check for and use IReduceInit path if available, otherwise fallback to seq. Additionally, the patch adds a modification to return a set without it's meta (same approach as CLJ-1546) if a set is passed, which is fast constant time with no change in effective behavior.

*Performance:* (using Criterium quick-bench)

{code}
(def small-set (set (range 100)))
(def big-range (doall (range 1000000)))
(def little-range (doall (range 5)))
{code}

|| Expression || 1.6.0 || 1.7.0-alpha4 || 1.7.0-alpha4 + patch ||
|(count (set small-set))|17.0 µs|11.4 µs |0.0 µs|
|(count (into #{} small-set))|15.4 µs|13.8 µs |13.1 µs|
|(count (set big-range))|736.9 ms|387.5 ms |371.0 ms|
|(count (into #{} big-range))|363.6 ms|373.1 ms |379.9 ms|
|(count (set little-range))|612.3 ns|481.9 ns |445.9 ns|
|(count (into #{} little-range))|404.9 ns|433.1 ns |409.9 ns|

*See also:* CLJ-1546, CLJ-1384

*Patch:*

*Screened by:*
Alex Miller made changes -
Description Similar to CLJ-1546 (same thing on vec), set should work on IReducibleInit or Iterable. Currently eduction will work via Iterable but through SeqIterator. set on an IReduceInit will throw an error.

{code}
user=> (set (eduction (map inc) (range 100))) ;; works, but slower path
user=> (set (reify clojure.lang.IReduceInit
       (reduce [_ f start]
         (reduce f start (range 10)))))
IllegalArgumentException Don't know how to create ISeq from: user$eval1198$reify__1199 clojure.lang.RT.seqFrom (RT.java:506)
{code}

*Approach:* Check for and use IReduceInit path if available, otherwise fallback to seq. Additionally, the patch adds a modification to return a set without it's meta (same approach as CLJ-1546) if a set is passed, which is fast constant time with no change in effective behavior.

*Performance:* (using Criterium quick-bench)

{code}
(def small-set (set (range 100)))
(def big-range (doall (range 1000000)))
(def little-range (doall (range 5)))
{code}

|| Expression || 1.6.0 || 1.7.0-alpha4 || 1.7.0-alpha4 + patch ||
|(count (set small-set))|17.0 µs|11.4 µs |0.0 µs|
|(count (into #{} small-set))|15.4 µs|13.8 µs |13.1 µs|
|(count (set big-range))|736.9 ms|387.5 ms |371.0 ms|
|(count (into #{} big-range))|363.6 ms|373.1 ms |379.9 ms|
|(count (set little-range))|612.3 ns|481.9 ns |445.9 ns|
|(count (into #{} little-range))|404.9 ns|433.1 ns |409.9 ns|

*See also:* CLJ-1546, CLJ-1384

*Patch:*

*Screened by:*
Similar to CLJ-1546 (same thing on vec), set should work on IReducibleInit or Iterable. Currently eduction will work via Iterable but through SeqIterator. set on an IReduceInit will throw an error.

{code}
user=> (set (eduction (map inc) (range 100))) ;; works, but slower path
user=> (set (reify clojure.lang.IReduceInit
       (reduce [_ f start]
         (reduce f start (range 10)))))
IllegalArgumentException Don't know how to create ISeq from: user$eval1198$reify__1199 clojure.lang.RT.seqFrom (RT.java:506)
{code}

*Approach:* Check for and use IReduceInit path if available, otherwise fallback to seq. Additionally, the patch adds a modification to return a set without it's meta (same approach as CLJ-1546) if a set is passed, which is fast constant time with no change in effective behavior.

*Performance:* (using Criterium quick-bench)

{code}
(def small-set (set (range 100)))
(def big-range (doall (range 1000000)))
(def little-range (doall (range 5)))
{code}

|| Expression || 1.6.0 || 1.7.0-alpha4 || 1.7.0-alpha4 + patch ||
|(count (set small-set))|17.0 µs|11.4 µs |0.0 µs|
|(count (into #{} small-set))|15.4 µs|13.8 µs |13.1 µs|
|(count (set big-range))|736.9 ms|387.5 ms |371.0 ms|
|(count (into #{} big-range))|363.6 ms|373.1 ms |379.9 ms|
|(count (set little-range))|612.3 ns|481.9 ns |445.9 ns|
|(count (into #{} little-range))|404.9 ns|433.1 ns |409.9 ns|

*See also:* CLJ-1546, CLJ-1384

*Patch:* clj-1618.patch

*Screened by:*
Alex Miller made changes -
Description Similar to CLJ-1546 (same thing on vec), set should work on IReducibleInit or Iterable. Currently eduction will work via Iterable but through SeqIterator. set on an IReduceInit will throw an error.

{code}
user=> (set (eduction (map inc) (range 100))) ;; works, but slower path
user=> (set (reify clojure.lang.IReduceInit
       (reduce [_ f start]
         (reduce f start (range 10)))))
IllegalArgumentException Don't know how to create ISeq from: user$eval1198$reify__1199 clojure.lang.RT.seqFrom (RT.java:506)
{code}

*Approach:* Check for and use IReduceInit path if available, otherwise fallback to seq. Additionally, the patch adds a modification to return a set without it's meta (same approach as CLJ-1546) if a set is passed, which is fast constant time with no change in effective behavior.

*Performance:* (using Criterium quick-bench)

{code}
(def small-set (set (range 100)))
(def big-range (doall (range 1000000)))
(def little-range (doall (range 5)))
{code}

|| Expression || 1.6.0 || 1.7.0-alpha4 || 1.7.0-alpha4 + patch ||
|(count (set small-set))|17.0 µs|11.4 µs |0.0 µs|
|(count (into #{} small-set))|15.4 µs|13.8 µs |13.1 µs|
|(count (set big-range))|736.9 ms|387.5 ms |371.0 ms|
|(count (into #{} big-range))|363.6 ms|373.1 ms |379.9 ms|
|(count (set little-range))|612.3 ns|481.9 ns |445.9 ns|
|(count (into #{} little-range))|404.9 ns|433.1 ns |409.9 ns|

*See also:* CLJ-1546, CLJ-1384

*Patch:* clj-1618.patch

*Screened by:*
Similar to CLJ-1546 (same thing on vec), set should work on IReducibleInit or Iterable. Currently eduction will work via Iterable but through SeqIterator. set on an IReduceInit will throw an error.

{code}
user=> (set (eduction (map inc) (range 100))) ;; works, but slower path
user=> (set (reify clojure.lang.IReduceInit
       (reduce [_ f start]
         (reduce f start (range 10)))))
IllegalArgumentException Don't know how to create ISeq from: user$eval1198$reify__1199 clojure.lang.RT.seqFrom (RT.java:506)
{code}

*Approach:* Check for and use IReduceInit path if available, otherwise fallback to seq. Additionally, the patch adds a modification to return a set without it's meta (same approach as CLJ-1546) if a set is passed, which is fast constant time with no change in effective behavior.

*Performance:* (using Criterium quick-bench)

Timings done with either (count (set *coll*)) or (count (into #{} *coll*)):

|| coll || 1.6.0 into || 1.6.0 set || 1.7.0-alpha4 set || 1.7.0-alpha4+patch set ||
|(set (range 100))|15.4 µs|17.0 µs|11.4 µs |0.0 µs|
|(vec (range 1000000))|360.7 ms|702.5 ms|391.1 ms|358.6 ms|
|(doall (range 1000000))|363.6 ms|736.9 ms|387.5 ms |371.0 ms|
|(doall (range 5))|404.9 ns|612.3 ns|481.9 ns |445.9 ns|
|(eduction (map identity) (vec (range 100)))|n/a|n/a|11.3 µs|8.7 µs|

*See also:* CLJ-1546, CLJ-1384

*Patch:* clj-1618.patch

*Screened by:*
Stuart Halloway made changes -
Approval Vetted [ 10003 ] Screened [ 10004 ]
Rich Hickey made changes -
Approval Screened [ 10004 ] Ok [ 10007 ]
Stuart Halloway made changes -
Status Open [ 1 ] Closed [ 6 ]
Resolution Completed [ 1 ]

People

Vote (0)
Watch (1)

Dates

  • Created:
    Updated:
    Resolved: