Skip to content

Instantly share code, notes, and snippets.

@davidsantiago
Created December 16, 2009 00:20
Show Gist options
  • Save davidsantiago/257453 to your computer and use it in GitHub Desktop.
Save davidsantiago/257453 to your computer and use it in GitHub Desktop.
;;; clj-html.core & compojure.html performance
;;; ORIGINALLY FOUND AT http://gist.github.com/45136
(use '[clj-html.core :rename {html htmlc htmli htmli2}]
'clj-html.utils
'[compojure.html :rename {html htmli}]
'[hiccup :rename {html hhtml escape-html hic-escape-html h hh}])
(defn- htmli-item-partial
[item]
[:div.item
[:p.special item]])
(defn- hhtml-item-partial
[item]
(hhtml [:div.item
[:p.special item]]))
(defn- htmlc-item-partial
[item]
(htmlc
[:div.item
[:p.special item]]))
(defn- string-builder-partial
[item]
(let [builder (StringBuilder.)]
(.append builder "<div id=\"item\"><p class=\"special\"")
(.append builder item)
(.append builder "</div>")
(.toString builder)))
(defn- htmli-template
[html-f items title header]
(html-f
[:html
[:head [:title title]]
[:body
[:div#container
[:div#content {:id (str "foo" "bar") :class (str "biz" "bat")}
(if true
[:h1#custom-header (str "Custom " header)]
[:h1#header header])
[:div#items
(map htmli-item-partial items)]]]]]))
(defn- hhtml-template
[items title header]
(hhtml
[:html
[:head [:title title]]
[:body
[:div#container
; This code would run about 4x faster than the four lines following this comment
; [:div#content {:id "foobar" :class "bizbat"}
; [:h1#custom-header (str "Custom " header)]
[:div#content {:id (str "foo" "bar") :class (str "biz" "bat")}
(if true
[:h1#custom-header (str "Custom " header)]
[:h1#header header])
[:div#items
(map hhtml-item-partial items)]]]]]))
(defn- htmlc-template
[items title header]
(htmlc
[:html
[:head [:title title]]
[:body
[:div#container
[:div#content {:id (str "foo" "bar") :class (str "biz" "bat")}
(if true
(htmlc [:h1#custom-header (str "Custom " header)])
(htmlc [:h1#header header]))
[:div#items
(map-str htmlc-item-partial items)]]]]]))
(defn- string-builder-template
[items title header]
(let [builder (StringBuilder.)]
(.append builder "<html><head><title>")
(.append builder (str title))
(.append builder "</title></head><body><div id=\"container\"><div id=\"content\" id=\"")
(.append builder (str "foo" "bar"))
(.append builder "\" class=\"")
(.append builder (str "biz" "bat"))
(.append builder "\">")
(if true
(do
(.append builder "<h1 id=\"custom-header\">")
(.append builder (str "Custom" header))
(.append builder "</h1>"))
(do
(.append builder "<h1 id=\"header\">")
(.append builder (str header))
(.append builder "</h1>")))
(doseq [item items]
(.append builder (string-builder-partial item)))
(.append builder "</div></div></body></html>")
(.toString builder)))
(def items ["foo" "bar" "bat"])
(def title "title")
(def header "header")
(defn bench
[name f]
(print (str name ": "))
(time (dotimes [_ 10000] (f items title header))))
(assert (= (htmlc-template items title header)
((partial htmli-template htmli2) items title header)
(hhtml-template items title header)))
(dotimes [_ 2]
(bench "compojure.html " (partial htmli-template htmli))
(bench "hiccup " hhtml-template)
(bench "clj-html.core(i) " (partial htmli-template htmli2))
(bench "clj-html.core(c) " htmlc-template)
(bench "StringBuilder " string-builder-template)
(println))
; Results 12/15/2009
; compojure.html : "Elapsed time: 4181.599 msecs"
; hiccup : "Elapsed time: 546.03 msecs"
; clj-html.core(i) : "Elapsed time: 1158.701 msecs"
; clj-html.core(c) : "Elapsed time: 75.67 msecs"
; StringBuilder : "Elapsed time: 34.797 msecs"
; Results 12/15/2009 with non-bozo code in hhtml-template (see comment above)
; compojure.html : "Elapsed time: 4281.57 msecs"
; hiccup : "Elapsed time: 137.102 msecs"
; clj-html.core(i) : "Elapsed time: 1227.933 msecs"
; clj-html.core(c) : "Elapsed time: 78.817 msecs"
; StringBuilder : "Elapsed time: 36.117 msecs"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment