Skip to content

Instantly share code, notes, and snippets.

@favila
Created April 6, 2017 20:32
Show Gist options
  • Save favila/49148e956720478eebacf1e9a4f43071 to your computer and use it in GitHub Desktop.
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
(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