diff --git a/dev/bench/chassis.clj b/dev/bench/chassis.clj new file mode 100644 index 0000000..651ecf1 --- /dev/null +++ b/dev/bench/chassis.clj @@ -0,0 +1,224 @@ +(ns bench.chassis + (:require [dev.onionpancakes.chassis.core :as c] + [dev.onionpancakes.chassis.compiler :as cc])) + +(defmethod c/resolve-alias ::Item + [_ _ {item ::item :as attrs} content] + [:div.item (merge {:id (:uuid item) + :class (:type item)} attrs) + [:h2 (:name item)] + [:p (:date item)] + [:p [:a.baz.buz {:href (str "/item/" (:uuid item))} + "See more details."]] + [:h3 "Description"] + [:p (:text item)]]) + +(defmethod c/resolve-alias ::ItemCompiled + [_ _ {item ::item :as attrs} content] + (cc/compile + [:div.item (merge {:id (:uuid item) + :class (:type item)} attrs) + [:h2 (:name item)] + [:p (:date item)] + [:p [:a.baz.buz {:href (str "/item/" (:uuid item))} + "See more details."]] + [:h3 "Description"] + [:p (:text item)]])) + +(defmethod c/resolve-alias ::Layout + [_ _ {title ::title :as attrs} content] + [:html {:lang "en"} + [:head + [:link {:href "/foobar1" :rel "stylesheet"}] + [:link {:href "/foobar2" :rel "stylesheet"}] + [:link {:href "/foobar3" :rel "stylesheet"}] + [:link {:href "/foobar4" :rel "stylesheet"}] + [:title title]] + [:body + [:header + [:h1 title]] + [:main attrs content] + [:footer "Footer"]]]) + +(defmethod c/resolve-alias ::LayoutCompiled + [_ _ {title ::title :as attrs} content] + (cc/compile + [:html {:lang "en"} + [:head + [:link {:href "/foobar1" :rel "stylesheet"}] + [:link {:href "/foobar2" :rel "stylesheet"}] + [:link {:href "/foobar3" :rel "stylesheet"}] + [:link {:href "/foobar4" :rel "stylesheet"}] + [:title title]] + [:body + [:header + [:h1 title]] + [:main attrs content] + [:footer "Footer"]]])) + +(defn item-element + [item] + [:div.item {:id (:uuid item) + :class (:type item)} + [:h2 (:name item)] + [:p (:date item)] + [:p [:a.baz.buz {:href (str "/item/" (:uuid item))} + "See more details."]] + [:h3 "Description"] + [:p (:text item)]]) + +(defn item-element-compiled + [item] + (cc/compile + [:div.item {:id (:uuid item) + :class (:type item)} + [:h2 (:name item)] + [:p (:date item)] + [:p [:a.baz.buz {:href (str "/item/" (:uuid item))} + "See more details."]] + [:h3 "Description"] + [:p (:text item)]])) + +(defn item-element-compiled-unambig + [item] + (cc/compile + [:div.item {:id (:uuid item) + :class (:type item)} + [:h2 nil (:name item)] + [:p nil (:date item)] + [:p [:a.baz.buz {:href (str "/item/" (:uuid item))} + "See more details."]] + [:h3 "Description"] + [:p nil (:text item)]])) + +(defn page + [data] + [:html {:lang "en"} + [:head + [:link {:href "/foobar1" :rel "stylesheet"}] + [:link {:href "/foobar2" :rel "stylesheet"}] + [:link {:href "/foobar3" :rel "stylesheet"}] + [:link {:href "/foobar4" :rel "stylesheet"}] + [:title (:title data)]] + [:body + [:header + [:h1 (:title data)]] + [:main + (->> (:items data) + (map item-element) + (interpose [:hr]))] + [:footer "Footer"]]]) + +(defn page-doall + [data] + [:html {:lang "en"} + [:head + [:link {:href "/foobar1" :rel "stylesheet"}] + [:link {:href "/foobar2" :rel "stylesheet"}] + [:link {:href "/foobar3" :rel "stylesheet"}] + [:link {:href "/foobar4" :rel "stylesheet"}] + [:title (:title data)]] + [:body + [:header + [:h1 (:title data)]] + [:main + (->> (:items data) + (map item-element) + (interpose [:hr]) + (doall))] + [:footer "Footer"]]]) + +(defn page-alias + [data] + [::Layout {::title (:title data)} + (->> (:items data) + (map #(vector ::Item {::item %})) + (interpose [:hr]))]) + +(defn page-alias-compiled + [data] + (cc/compile + [::LayoutCompiled {::title (:title data)} + (->> (:items data) + (map #(cc/compile [::ItemCompiled {::item %}])) + (interpose (cc/compile [:hr])))])) + +(defn page-compiled + [data] + (cc/compile + [:html {:lang "en"} + [:head + [:link {:href "/foobar1" :rel "stylesheet"}] + [:link {:href "/foobar2" :rel "stylesheet"}] + [:link {:href "/foobar3" :rel "stylesheet"}] + [:link {:href "/foobar4" :rel "stylesheet"}] + [:title (:title data)]] + [:body + [:header + [:h1 (:title data)]] + [:main + (->> (:items data) + (map item-element-compiled) + (interpose (cc/compile [:hr])))] + [:footer "Footer"]]])) + +(defn page-compiled-unambig + [data] + (cc/compile + [:html {:lang "en"} + [:head + [:link {:href "/foobar1" :rel "stylesheet"}] + [:link {:href "/foobar2" :rel "stylesheet"}] + [:link {:href "/foobar3" :rel "stylesheet"}] + [:link {:href "/foobar4" :rel "stylesheet"}] + [:title nil (:title data)]] + [:body + [:header + [:h1 nil (:title data)]] + [:main nil + (->> (:items data) + (map item-element-compiled-unambig) + (interpose (cc/compile [:hr])))] + [:footer "Footer"]]])) + +(defn chassis-page + [data] + (c/html [c/doctype-html5 (page data)])) + +(defn chassis-page-alias + [data] + (c/html [c/doctype-html5 (page-alias data)])) + +(defn chassis-page-alias-compiled + [data] + (c/html [c/doctype-html5 (page-alias-compiled data)])) + +(defn chassis-page-compiled + [data] + (c/html [c/doctype-html5 (page-compiled data)])) + +(defn chassis-page-compiled-unambig + [data] + (c/html [c/doctype-html5 (page-compiled-unambig data)])) + +(defn chassis-page-print-writer + [data] + (let [out (java.io.ByteArrayOutputStream. 16384) + charset (java.nio.charset.Charset/forName "UTF-8")] + (with-open [wtr (java.io.PrintWriter. out false charset)] + (c/write-html wtr [c/doctype-html5 (page data)])) + out)) + +(defn chassis-page-print-stream + [data] + (let [out (java.io.ByteArrayOutputStream. 16384)] + (with-open [pout (java.io.PrintStream. out false "UTF-8")] + (c/write-html pout [c/doctype-html5 (page data)])) + out)) + +(defn chassis-page-output-stream-writer + [data] + (let [out (java.io.ByteArrayOutputStream. 16384)] + (with-open [pout (java.io.OutputStreamWriter. out "UTF-8")] + (c/write-html pout [c/doctype-html5 (page data)])) + out)) diff --git a/dev/bench/enlive.clj b/dev/bench/enlive.clj new file mode 100644 index 0000000..f8da143 --- /dev/null +++ b/dev/bench/enlive.clj @@ -0,0 +1,50 @@ +(ns bench.enlive + (:require [net.cgrand.enlive-html :as enlive])) + +(defn item-element + [item] + [:div {:id (:uuid item) + :class (str "item " (:type item))} + [:h2 (:name item)] + [:p (:date item)] + [:p [:a.baz.buz {:href (str "/item/" (:uuid item))} + "See more details."]] + [:h3 "Description"] + [:p (:text item)]]) + +(enlive/deftemplate item-element-template "enlive/item.html" + [item] + [:.item] (comp (enlive/add-class (:type item)) + (enlive/set-attr :id (:uuid item))) + [:.name] (enlive/content (:name item)) + [:.date] (enlive/content (str (:date item))) + [:a] (enlive/set-attr :href (str "/item/" (:uuid item))) + [:.description] (enlive/content (:text item))) + +(enlive/deftemplate page-template-item-html "enlive/page.html" + [data] + [:head :title] (enlive/content (:title data)) + [:body :header :h1] (enlive/content (:title data)) + [:body :main] (enlive/content + (->> (:items data) + (map (comp enlive/html item-element)) + (interpose (enlive/html [:hr])))) + [:body :footer] (enlive/content "Footer")) + +(enlive/deftemplate page-template-item-template "enlive/page.html" + [data] + [:head :title] (enlive/content (:title data)) + [:body :header :h1] (enlive/content (:title data)) + [:body :main] (enlive/content + (->> (:items data) + (map item-element-template) + (interpose (enlive/html [:hr])))) + [:body :footer] (enlive/content "Footer")) + +(defn enlive-page-item-html + [data] + (apply str (page-template-item-html data))) + +(defn enlive-page-item-template + [data] + (apply str (page-template-item-template data))) diff --git a/dev/bench/hiccup.clj b/dev/bench/hiccup.clj new file mode 100644 index 0000000..4d101ec --- /dev/null +++ b/dev/bench/hiccup.clj @@ -0,0 +1,118 @@ +(ns bench.hiccup + (:require [hiccup2.core :as hiccup] + [hiccup.page :as hiccup.page])) + +(defn item-element + [item] + [:div.item {:id (:uuid item) + :class (:type item)} + [:h2 (:name item)] + [:p (:date item)] + [:p [:a.baz.buz {:href (str "/item/" (:uuid item))} + "See more details."]] + [:h3 "Description"] + [:p (:text item)]]) + +(defn item-element-compiled + [item] + (hiccup/html + [:div.item {:id (:uuid item) + :class (:type item)} + [:h2 (:name item)] + [:p (:date item)] + [:p [:a.baz.buz {:href (str "/item/" (:uuid item))} + "See more details."]] + [:h3 "Description"] + [:p (:text item)]])) + +(defn item-element-compiled-unambig + [item] + (hiccup/html + [:div.item {:id (:uuid item) + :class (:type item)} + [:h2 nil (:name item)] + [:p nil (:date item)] + [:p [:a.baz.buz {:href (str "/item/" (:uuid item))} + "See more details."]] + [:h3 "Description"] + [:p nil (:text item)]])) + +(defn page + [data] + [:html {:lang "en"} + [:head + [:link {:href "/foobar1" :rel "stylesheet"}] + [:link {:href "/foobar2" :rel "stylesheet"}] + [:link {:href "/foobar3" :rel "stylesheet"}] + [:link {:href "/foobar4" :rel "stylesheet"}] + [:title (:title data)]] + [:body + [:header + [:h1 (:title data)]] + [:main + (->> (:items data) + (map item-element) + (interpose (hiccup/html [:hr])))] + [:footer "Footer"]]]) + +(defn page-compiled + [data] + (hiccup/html + [:html {:lang "en"} + [:head + [:link {:href "/foobar1" :rel "stylesheet"}] + [:link {:href "/foobar2" :rel "stylesheet"}] + [:link {:href "/foobar3" :rel "stylesheet"}] + [:link {:href "/foobar4" :rel "stylesheet"}] + [:title (:title data)]] + [:body + [:header + [:h1 (:title data)]] + [:main + (->> (:items data) + (map item-element-compiled) + (interpose (hiccup/html [:hr])))] + [:footer "Footer"]]])) + +(defn page-compiled-unambig + [data] + (hiccup/html + [:html {:lang "en"} + [:head + [:link {:href "/foobar1" :rel "stylesheet"}] + [:link {:href "/foobar2" :rel "stylesheet"}] + [:link {:href "/foobar3" :rel "stylesheet"}] + [:link {:href "/foobar4" :rel "stylesheet"}] + [:title nil (:title data)]] + [:body + [:header + [:h1 nil (:title data)]] + [:main nil + (->> (:items data) + (map item-element-compiled-unambig) + (interpose (hiccup/html [:hr])))] + [:footer "Footer"]]])) + +(defn hiccup-page + [data] + (str + (hiccup/html + {:mode :html} + (hiccup.page/doctype :html5) + (page data)))) + +(defn hiccup-page-compiled + [data] + (str + (hiccup/html + {:mode :html} + (hiccup.page/doctype :html5) + (page-compiled data)))) + +(defn hiccup-page-compiled-unambig + [data] + (str + (hiccup/html + {:mode :html} + (hiccup.page/doctype :html5) + (page-compiled-unambig data)))) diff --git a/dev/bench/selmer.clj b/dev/bench/selmer.clj new file mode 100644 index 0000000..d45660d --- /dev/null +++ b/dev/bench/selmer.clj @@ -0,0 +1,6 @@ +(ns bench.selmer + (:require [selmer.parser :as selmer])) + +(defn selmer-page + [data] + (selmer/render-file "selmer/page.html" data)) diff --git a/dev/user.clj b/dev/user.clj index 51f18b3..ecb5437 100644 --- a/dev/user.clj +++ b/dev/user.clj @@ -1,13 +1,23 @@ (ns user - (:require [dev.onionpancakes.chassis.core :as c] + (:require [bench.chassis + :refer [page + chassis-page + chassis-page-alias chassis-page-alias-compiled + chassis-page-compiled chassis-page-compiled-unambig + chassis-page-print-writer chassis-page-print-stream + chassis-page-output-stream-writer]] + [bench.hiccup + :refer [hiccup-page hiccup-page-compiled + hiccup-page-compiled-unambig]] + [bench.selmer :refer [selmer-page]] + [bench.enlive + :refer [enlive-page-item-html enlive-page-item-template]] + [dev.onionpancakes.chassis.core :as c] [dev.onionpancakes.chassis.compiler :as cc] [dev.onionpancakes.chassis.tests.test-core :as t] [dev.onionpancakes.chassis.tests.test-compiler :as tc] [criterium.core :refer [bench quick-bench]] [hiccup2.core :as hiccup] - [hiccup.page :as hiccup.page] - [selmer.parser :as selmer] - [net.cgrand.enlive-html :as enlive] [clojure.walk :refer [macroexpand-all]])) (defmethod c/resolve-alias ::Foo @@ -51,330 +61,6 @@ (def data-small (make-data 10)) -(defn item-element - [item] - [:div.item {:id (:uuid item) - :class (:type item)} - [:h2 (:name item)] - [:p (:date item)] - [:p [:a.baz.buz {:href (str "/item/" (:uuid item))} - "See more details."]] - [:h3 "Description"] - [:p (:text item)]]) - -(defn page - [data] - [:html {:lang "en"} - [:head - [:link {:href "/foobar1" :rel "stylesheet"}] - [:link {:href "/foobar2" :rel "stylesheet"}] - [:link {:href "/foobar3" :rel "stylesheet"}] - [:link {:href "/foobar4" :rel "stylesheet"}] - [:title (:title data)]] - [:body - [:header - [:h1 (:title data)]] - [:main - (->> (:items data) - (map item-element) - (interpose [:hr]))] - [:footer "Footer"]]]) - -(defn page-doall - [data] - [:html {:lang "en"} - [:head - [:link {:href "/foobar1" :rel "stylesheet"}] - [:link {:href "/foobar2" :rel "stylesheet"}] - [:link {:href "/foobar3" :rel "stylesheet"}] - [:link {:href "/foobar4" :rel "stylesheet"}] - [:title (:title data)]] - [:body - [:header - [:h1 (:title data)]] - [:main - (->> (:items data) - (map item-element) - (interpose [:hr]) - (doall))] - [:footer "Footer"]]]) - -(defn item-element-compiled - [item] - (cc/compile - [:div.item {:id (:uuid item) - :class (:type item)} - [:h2 (:name item)] - [:p (:date item)] - [:p [:a.baz.buz {:href (str "/item/" (:uuid item))} - "See more details."]] - [:h3 "Description"] - [:p (:text item)]])) - -(defn page-compiled - [data] - (cc/compile - [c/doctype-html5 - [:html {:lang "en"} - [:head - [:link {:href "/foobar1" :rel "stylesheet"}] - [:link {:href "/foobar2" :rel "stylesheet"}] - [:link {:href "/foobar3" :rel "stylesheet"}] - [:link {:href "/foobar4" :rel "stylesheet"}] - [:title (:title data)]] - [:body - [:header - [:h1 (:title data)]] - [:main - (->> (:items data) - (map item-element-compiled) - (interpose (cc/compile [:hr])))] - [:footer "Footer"]]]])) - -(defn item-element-compiled-unambig - [item] - (cc/compile - [:div.item {:id (:uuid item) - :class (:type item)} - [:h2 nil (:name item)] - [:p nil (:date item)] - [:p [:a.baz.buz {:href (str "/item/" (:uuid item))} - "See more details."]] - [:h3 "Description"] - [:p nil (:text item)]])) - -(defn page-compiled-unambig - [data] - (cc/compile - [c/doctype-html5 - [:html {:lang "en"} - [:head - [:link {:href "/foobar1" :rel "stylesheet"}] - [:link {:href "/foobar2" :rel "stylesheet"}] - [:link {:href "/foobar3" :rel "stylesheet"}] - [:link {:href "/foobar4" :rel "stylesheet"}] - [:title nil (:title data)]] - [:body - [:header - [:h1 nil (:title data)]] - [:main nil - (->> (:items data) - (map item-element-compiled-unambig) - (interpose (cc/compile [:hr])))] - [:footer "Footer"]]]])) - -(defmethod c/resolve-alias ::Layout - [_ _ {title ::title :as attrs} content] - [:html (into {:lang "en"} attrs) - [:head - [:link {:href "/foobar1" :rel "stylesheet"}] - [:link {:href "/foobar2" :rel "stylesheet"}] - [:link {:href "/foobar3" :rel "stylesheet"}] - [:link {:href "/foobar4" :rel "stylesheet"}] - [:title title]] - [:body - [:header - [:h1 title]] - [:main content] - [:footer "Footer"]]]) - -(defmethod c/resolve-alias ::Item - [_ _ {item ::item :as attrs} content] - [:div.item (into {:id (:uuid item) - :class (:type item)} attrs) - [:h2 (:name item)] - [:p (:date item)] - [:p [:a.baz.buz {:href (str "/item/" (:uuid item))} - "See more details."]] - [:h3 "Description"] - [:p (:text item)]]) - -(defn page-alias - [data] - [::Layout {::title (:title data)} - (->> (:items data) - (map #(vector ::Item {::item %})) - (interpose [:hr]))]) - -(defn chassis-page - [data] - (c/html [c/doctype-html5 (page data)])) - -(defn chassis-page-alias - [data] - (c/html [c/doctype-html5 (page-alias data)])) - -(defn chassis-page-compiled - [data] - (c/html (page-compiled data))) - -(defn chassis-page-compiled-unambig - [data] - (c/html (page-compiled-unambig data))) - -(defn chassis-page-writer - [data] - (let [wtr (java.io.CharArrayWriter. 16384)] - (with-open [w wtr] - (c/write-html w [c/doctype-html5 (page data)])) - (.toString wtr))) - -(defn chassis-page-print-writer - [data] - (let [out (java.io.ByteArrayOutputStream. 16384)] - (with-open [w (java.io.PrintWriter. out false (java.nio.charset.Charset/forName "UTF-8"))] - (c/write-html w [c/doctype-html5 (page data)])) - (String. (.toByteArray out) "UTF-8"))) - -(defn chassis-page-print-stream - [data] - (let [out (java.io.ByteArrayOutputStream. 16384)] - (with-open [pout (-> (java.io.BufferedOutputStream. out 16384) - (java.io.PrintStream. false "UTF-8"))] - (c/write-html pout [c/doctype-html5 (page data)])) - (String. (.toByteArray out) "UTF-8"))) - -(defn chassis-page-output-stream-writer - [data] - (let [out (java.io.ByteArrayOutputStream. 16384)] - (with-open [pout (java.io.OutputStreamWriter. out "UTF-8")] - (c/write-html pout [c/doctype-html5 (page data)])) - (String. (.toByteArray out) "UTF-8"))) - -;; Hiccup - -(defn hiccup-item-element - [item] - (hiccup/html - [:div.item {:id (:uuid item) - :class (:type item)} - [:h2 (:name item)] - [:p (:date item)] - [:p [:a.baz.buz {:href (str "/item/" (:uuid item))} - "See more details."]] - [:h3 "Description"] - [:p (:text item)]])) - -(defn hiccup-page - [data] - (str - (hiccup/html - {:mode :html} - (hiccup.page/doctype :html5) - [:html {:lang "en"} - [:head - [:link {:href "/foobar1" :rel "stylesheet"}] - [:link {:href "/foobar2" :rel "stylesheet"}] - [:link {:href "/foobar3" :rel "stylesheet"}] - [:link {:href "/foobar4" :rel "stylesheet"}] - [:title (:title data)]] - [:body - [:header - [:h1 (:title data)]] - [:main - (->> (:items data) - (map hiccup-item-element) - (interpose (hiccup/html [:hr])))] - [:footer "Footer"]]]))) - -(defn hiccup-item-element-unambig - [item] - (hiccup/html - [:div.item {:id (:uuid item) - :class (:type item)} - [:h2 nil (:name item)] - [:p nil (:date item)] - [:p [:a.baz.buz {:href (str "/item/" (:uuid item))} - "See more details."]] - [:h3 "Description"] - [:p nil (:text item)]])) - -(defn hiccup-page-unambig - [data] - (str - (hiccup/html - {:mode :html} - (hiccup.page/doctype :html5) - [:html {:lang "en"} - [:head - [:link {:href "/foobar1" :rel "stylesheet"}] - [:link {:href "/foobar2" :rel "stylesheet"}] - [:link {:href "/foobar3" :rel "stylesheet"}] - [:link {:href "/foobar4" :rel "stylesheet"}] - [:title nil (:title data)]] - [:body - [:header - [:h1 nil (:title data)]] - [:main nil - (->> (:items data) - (map hiccup-item-element-unambig) - (interpose (hiccup/html [:hr])))] - [:footer "Footer"]]]))) - -(defn hiccup-page-runtime - [data] - (hiccup/html - {:mode :html} - (hiccup.page/doctype :html5) - (page data))) - -;; Selmer - -(defn selmer-page - [data] - (selmer/render-file "selmer/page.html" data)) - -;; Enlive - -(defn enlive-item-element - [item] - (enlive/html - [:div {:id (:uuid item) - :class (str "item " (:type item))} - [:h2 (:name item)] - [:p (:date item)] - [:p [:a.baz.buz {:href (str "/item/" (:uuid item))} - "See more details."]] - [:h3 "Description"] - [:p (:text item)]])) - -(enlive/deftemplate enlive-item-template "enlive/item.html" - [item] - [:.item] (comp (enlive/add-class (:type item)) - (enlive/set-attr :id (:uuid item))) - [:.name] (enlive/content (:name item)) - [:.date] (enlive/content (str (:date item))) - [:a] (enlive/set-attr :href (str "/item/" (:uuid item))) - [:.description] (enlive/content (:text item))) - -(enlive/deftemplate enlive-page-template-item-html "enlive/page.html" - [data] - [:head :title] (enlive/content (:title data)) - [:body :header :h1] (enlive/content (:title data)) - [:body :main] (enlive/content - (->> (:items data) - (map enlive-item-element) - (interpose (enlive/html [:hr])))) - [:body :footer] (enlive/content "Footer")) - -(enlive/deftemplate enlive-page-template-item-template "enlive/page.html" - [data] - [:head :title] (enlive/content (:title data)) - [:body :header :h1] (enlive/content (:title data)) - [:body :main] (enlive/content - (->> (:items data) - (map enlive-item-template) - (interpose (enlive/html [:hr])))) - [:body :footer] (enlive/content "Footer")) - -(defn enlive-page-item-html - [data] - (apply str (enlive-page-template-item-html data))) - -(defn enlive-page-item-template - [data] - (apply str (enlive-page-template-item-template data))) - (defn quick-bench-all [data] (println "Chassis")