(ns set-test | |
(:require [criterium.core :refer [bench quick-bench]]) | |
(:import [clojure.lang IPersistentSet])) | |
(defn- bubble-max-key | |
"Move a maximal element of coll according to fn k (which returns a | |
number) to the front of coll." | |
[k coll] | |
(let [max (apply max-key k coll)] | |
(cons max (remove #(identical? max %) coll)))) | |
(defn union | |
"Return a set that is the union of the input sets" | |
{:added "1.0"} | |
([] #{}) | |
([s1] s1) | |
([s1 s2] | |
(if (< (count s1) (count s2)) | |
(reduce conj s2 s1) | |
(reduce conj s1 s2))) | |
([s1 s2 & sets] | |
(let [bubbled-sets (bubble-max-key count (conj sets s2 s1))] | |
(reduce into (first bubbled-sets) (rest bubbled-sets))))) | |
(defn union-checking | |
"Return a set that is the union of the input sets" | |
{:added "1.0"} | |
([] #{}) | |
([s1] | |
(assert (instance? IPersistentSet s1) "First argument must be a set") | |
s1) | |
([s1 s2] | |
(assert (instance? IPersistentSet s1) "First argument must be a set") | |
(assert (instance? IPersistentSet s2) "Second argument must be a set") | |
(if (< (count s1) (count s2)) | |
(reduce conj s2 s1) | |
(reduce conj s1 s2))) | |
([s1 s2 & sets] | |
(let [bubbled-sets (bubble-max-key count (conj sets s2 s1))] | |
(reduce into (first bubbled-sets) (rest bubbled-sets))))) | |
(let [a #{1 2 3} | |
b #{2 3 4}] | |
(println "Benching Unchecked") | |
(flush) | |
(bench | |
(union a b)) | |
(println "Benching Checked") | |
(flush) | |
(bench | |
(union-checking a b))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment