Created
April 6, 2017 20:32
-
-
Save favila/49148e956720478eebacf1e9a4f43071 to your computer and use it in GitHub Desktop.
Test different str implementations for cljs. Code used for this jsperf (which no longer runs due to DropBox): https://jsperf.com/cljs-core-str-possibilities
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
(ns str-test | |
(:import goog.string.StringBuffer)) | |
(defn ^:export str-tostr | |
([x] (if (nil? x) | |
"" | |
(.toString x))) | |
([x & ys] | |
(loop [sb (StringBuffer. (str-tostr x)) more ys] | |
(if more | |
(recur (. sb (append (str-tostr (first more)))) (next more)) | |
(.toString sb))))) | |
(defn ^:export str-arr | |
([x] | |
(js-str #js [x])) | |
([x & ys] | |
(loop [sb (StringBuffer. (str-arr x)) more ys] | |
(if more | |
(recur (. sb (append (str-arr (first more)))) (next more)) | |
(.toString sb))))) | |
(let [a (array nil)] | |
(defn ^:export str-arr-noalloc | |
([x] | |
(aset a 0 x) | |
(let [s (js-str a)] | |
(aset a 0 nil) | |
s)) | |
([x & ys] | |
(loop [sb (StringBuffer. (str-arr-noalloc x)) more ys] | |
(if more | |
(recur (. sb (append (str-arr-noalloc (first more)))) (next more)) | |
(.toString sb)))))) | |
(defn ^:export str-switch | |
([x] | |
(case (js* "typeof ~{}" x) | |
"string" x | |
"object" (if ^boolean (js* "~{}===null" x) "" (.toString x)) | |
("boolean" "number") (js-str x) | |
"undefined" "" | |
(.toString x))) | |
([x & ys] | |
(loop [sb (StringBuffer. (str-switch x)) more ys] | |
(if more | |
(recur (. sb (append (str-switch (first more)))) (next more)) | |
(.toString sb))))) | |
(defn ^:export str-arr-reduce | |
([x] | |
(js-str #js [x])) | |
([x & ys] | |
(reduce (fn [a b] (js* "~{}+~{}" a (str-arr-reduce b))) (str-arr-reduce x) ys))) | |
(let [a (array nil)] | |
(defn ^:export str-arr-noalloc-reduce | |
([x] | |
(aset a 0 x) | |
(let [s (js-str a)] | |
(aset a 0 nil) | |
s)) | |
([x & ys] | |
(reduce (fn [a b] (js* "~{}+~{}" a (str-arr-noalloc-reduce b))) (str-arr-noalloc-reduce x) ys)))) | |
(defn ^:export str-switch-reduce | |
([x] | |
(case (js* "typeof ~{}" x) | |
"string" x | |
"object" (if ^boolean (js* "~{}===null" x) "" (.toString x)) | |
("boolean" "number") (js-str x) | |
"undefined" "" | |
(.toString x))) | |
([x & ys] | |
(reduce (fn [a b] (js* "~{}+~{}" a (str-switch-reduce b))) (str-switch-reduce x) ys))) | |
(defn ^:export str-tostr-reduce | |
([x] (if (nil? x) | |
"" | |
(.toString x))) | |
([x & ys] | |
(reduce (fn [a b] (js* "~{}+~{}" a (str-tostr-reduce b))) (str-tostr-reduce x) ys))) | |
(defn assert-ok-str [in out] | |
(assert (= (str in) out))) | |
(defn assert-oks [ins outs] | |
(dorun (map assert-ok-str ins outs))) | |
(defn ^:export assert-ok [in out] | |
(if (string? in) | |
(assert-ok-str in out) | |
(assert-oks in out))) | |
(deftype Hasvalueof [] | |
Object | |
(toString [o] "[toString]") | |
(valueOf [o] "[valueOf]")) | |
(def tests | |
[[0 "0"] ["a" "a"] [true "true"] [nil ""] [:key/word ":key/word"] | |
['symb/ol "symb/ol"] [false "false"] [[1 2 3 4] "[1 2 3 4]"] | |
[1234.5678 "1234.5678"] [0x09 "9"] [(Hasvalueof.) "[toString]"]]) | |
(def ^:export test-in (mapv first tests)) | |
(def ^:export test-out (mapv second tests)) | |
(defn ^:export test-1arg [f] | |
(mapv f test-in)) | |
(defn ^:export test-varg [f] | |
(apply f test-in)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment