Last active
December 3, 2016 08:31
-
-
Save tonsky/442eda3ba6aa4a71fd67883bb3f61d99 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(require '[criterium.core :as c]) | |
(defn new_= | |
"Equality. Returns true if x equals y, false if not. Same as | |
Java x.equals(y) except it also works for nil, and compares | |
numbers and collections in a type-independent manner. Clojure's immutable data | |
structures define equals() (and thus =) as a value, not an identity, | |
comparison." | |
{:inline (fn [x y] `(. clojure.lang.Util equiv ~x ~y)) | |
:inline-arities #{2} | |
:added "1.0"} | |
([x] true) | |
([x y] (clojure.lang.Util/equiv x y)) | |
([x y z] (and (clojure.lang.Util/equiv x y) | |
(clojure.lang.Util/equiv y z))) | |
([x y z & more] | |
(if (clojure.lang.Util/equiv x y) | |
(let [nmore (next more)] | |
(if nmore | |
(recur y z (first more) nmore) | |
(new_= y z (first more)))) | |
false))) | |
(defn new_not= | |
"Same as (not (= obj1 obj2))" | |
{:tag Boolean | |
:added "1.0" | |
:static true} | |
([x] false) | |
([x y] (not (new_= x y))) | |
([x y z] (not (new_= x y z))) | |
([x y z & more] | |
(if (new_= x y) | |
(let [nmore (next more)] | |
(if nmore | |
(recur y z (first more) nmore) | |
(new_not= y z (first more)))) | |
true))) | |
(defn new_< | |
"Returns non-nil if nums are in monotonically increasing order, | |
otherwise false." | |
{:inline (fn [x y] `(. clojure.lang.Numbers (lt ~x ~y))) | |
:inline-arities #{2} | |
:added "1.0"} | |
([x] true) | |
([x y] (. clojure.lang.Numbers (lt x y))) | |
([x y z] (and (. clojure.lang.Numbers (lt x y)) | |
(. clojure.lang.Numbers (lt y z)))) | |
([x y z & more] | |
(if (new_< x y) | |
(let [nmore (next more)] | |
(if nmore | |
(recur y z (first more) nmore) | |
(new_< y z (first more)))) | |
false))) | |
(defn new_<= | |
"Returns non-nil if nums are in monotonically non-decreasing order, | |
otherwise false." | |
{:inline (fn [x y] `(. clojure.lang.Numbers (lte ~x ~y))) | |
:inline-arities #{2} | |
:added "1.0"} | |
([x] true) | |
([x y] (. clojure.lang.Numbers (lte x y))) | |
([x y z] (and (. clojure.lang.Numbers (lte x y)) | |
(. clojure.lang.Numbers (lte y z)))) | |
([x y z & more] | |
(if (new_<= x y) | |
(let [nmore (next more)] | |
(if nmore | |
(recur y z (first more) nmore) | |
(new_<= y z (first more)))) | |
false))) | |
(defn new_> | |
"Returns non-nil if nums are in monotonically decreasing order, | |
otherwise false." | |
{:inline (fn [x y] `(. clojure.lang.Numbers (gt ~x ~y))) | |
:inline-arities #{2} | |
:added "1.0"} | |
([x] true) | |
([x y] (. clojure.lang.Numbers (gt x y))) | |
([x y z] (and (. clojure.lang.Numbers (gt x y)) | |
(. clojure.lang.Numbers (gt y z)))) | |
([x y z & more] | |
(if (new_> x y) | |
(let [nmore (next more)] | |
(if nmore | |
(recur y z (first more) nmore) | |
(new_> y z (first more)))) | |
false))) | |
(defn new_>= | |
"Returns non-nil if nums are in monotonically non-increasing order, | |
otherwise false." | |
{:inline (fn [x y] `(. clojure.lang.Numbers (gte ~x ~y))) | |
:inline-arities #{2} | |
:added "1.0"} | |
([x] true) | |
([x y] (. clojure.lang.Numbers (gte x y))) | |
([x y z] (and (. clojure.lang.Numbers (gte x y)) | |
(. clojure.lang.Numbers (gte y z)))) | |
([x y z & more] | |
(if (new_>= x y) | |
(let [nmore (next more)] | |
(if nmore | |
(recur y z (first more) nmore) | |
(new_>= y z (first more)))) | |
false))) | |
(defn new_== | |
"Returns non-nil if nums all have the equivalent | |
value (type-independent), otherwise false" | |
{:inline (fn [x y] `(. clojure.lang.Numbers (equiv ~x ~y))) | |
:inline-arities #{2} | |
:added "1.0"} | |
([x] true) | |
([x y] (. clojure.lang.Numbers (equiv x y))) | |
([x y z] (and (. clojure.lang.Numbers (equiv x y)) | |
(. clojure.lang.Numbers (equiv y z)))) | |
([x y z & more] | |
(if (new_== x y) | |
(let [nmore (next more)] | |
(if nmore | |
(recur y z (first more) nmore) | |
(new_== y z (first more)))) | |
false))) | |
(defn format-time [estimate] | |
(let [mean (first estimate) | |
[factor unit] (c/scale-time mean)] | |
(c/format-value mean factor unit))) | |
(defmacro race [body1 body2] | |
`(let [results1# (c/quick-benchmark ~body1 {}) | |
results2# (c/quick-benchmark ~body2 {}) | |
percent# (->> (/ (first (:mean results2#)) | |
(first (:mean results1#))) | |
(* 100) | |
(- 100) | |
(int))] | |
(println ~(pr-str body1) "\t" | |
(format-time (:mean results1#)) "=>" (format-time (:mean results2#)) | |
(str "(-" percent# "%)")))) | |
(race (= 5 5 5) (new_= 5 5 5)) | |
(race (= 5 5 5 5) (new_= 5 5 5 5)) | |
(race (not= 1 2 3) (new_not= 1 2 3)) | |
(race (not= 1 2 3 4) (new_not= 1 2 3 4)) | |
(race (< 1 2 3) (new_< 1 2 3)) | |
(race (< 1 2 3 4) (new_< 1 2 3 4)) | |
(race (<= 1 2 2) (new_<= 1 2 2)) | |
(race (<= 1 2 2 4) (new_<= 1 2 2 4)) | |
(race (> 3 2 1) (new_> 3 2 1)) | |
(race (> 3 2 1 0) (new_> 3 2 1 0)) | |
(race (>= 3 2 2) (new_>= 3 2 2)) | |
(race (>= 3 2 2 0) (new_>= 3 2 2 0)) | |
(race (== 5 5 5) (new_== 5 5 5)) | |
(race (== 5 5 5 5) (new_== 5 5 5 5)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Three-arities | |
(= 5 5 5) 24.508635 ns => 4.802783 ns (-80%) | |
(not= 1 2 3) 122.085793 ns => 21.828776 ns (-82%) | |
(< 1 2 3) 30.842993 ns => 6.714757 ns (-78%) | |
(<= 1 2 2) 30.712399 ns => 6.011326 ns (-80%) | |
(> 3 2 1) 22.577751 ns => 6.893885 ns (-69%) | |
(>= 3 2 2) 21.593219 ns => 6.233540 ns (-71%) | |
(== 5 5 5) 19.700540 ns => 6.066265 ns (-69%) | |
# Four-arities (vararg branch) | |
(= 5 5 5 5) 50.264580 ns => 31.361655 ns (-37%) | |
(not= 1 2 3 4) 130.517439 ns => 29.675640 ns (-77%) | |
(< 1 2 3 4) 68.059758 ns => 43.684409 ns (-35%) | |
(<= 1 2 2 4) 65.653826 ns => 45.194730 ns (-31%) | |
(> 3 2 1 0) 119.239733 ns => 44.305519 ns (-62%) | |
(>= 3 2 2 0) 65.738453 ns => 44.037442 ns (-33%) | |
(== 5 5 5 5) 50.773521 ns => 33.725097 ns (-33%) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment