Skip to content

Instantly share code, notes, and snippets.

@halgari
Created May 16, 2018 02:14
Show Gist options
  • Save halgari/8487946dfdcf3cb28cdb93f4650405d7 to your computer and use it in GitHub Desktop.
Save halgari/8487946dfdcf3cb28cdb93f4650405d7 to your computer and use it in GitHub Desktop.
(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