-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Small clarification to perf results in README #8
Comments
Hi James, I have been a big fan of hiccup for ages! thank you for the compliment, it means a great deal. I want to include notes about compilation with hiccup but I'm having trouble finding performance increases by pre-compiling. I'm trying to benchmark
as well as simply
in the perf-info branch, which also has some timing info from my machine. |
The expression ;; Fully pre-compiled, as all literals
(fn [_] (hiccup/html [:span "example"]))
;; Partially pre-compiled, as a mix of literals and symbols
(fn [x] (hiccup/html [:span x]))
;; No pre-compilation, as no literals
(fn [x] (hiccup/html x)) So in order to simulate this, we'd need to evaluate (def run-big-hiccup
(eval `(fn [] (hiccup/html ~(drop 1 big-page))))) Except that won't work, because user=> (eval huff.perf/medium-page)
Syntax error compiling at (REPL:1:1).
Unable to resolve symbol: falsetrue in this context Looks like there's some bare symbols, so I'll quote them to make it literal: user=> (eval (w/postwalk #(if (symbol? %) `(quote ~%) %) huff.perf/medium-page))
Syntax error (IndexOutOfBoundsException) compiling fn* at (REPL:1:1).
Method code too large! So Clojure won't allow a literal as large as But even if we could, I don't think it's worth evaluating the run-time performance of pre-compilation, because in the ideal case, there is no run-time code. In other words, these two examples are equivalent: (def example-1
(let [pre-compiled (hiccup/html some-data)]
(fn [] pre-compiled)))
(def example-2
(eval `(fn [] (hiccup/html ~some-data))))) The most efficient Hiccup function is returning a literal string, with zero time spent on calculations at runtime, because that's all been handled at compile-time. |
You have some very concise and clean code in Huff, and for that to result in a faster overall parser than Hiccup is impressive! So first, let me offer my congratulations for what looks like a great library.
However, you may want to change:
To:
Or something to that effect. Hiccup uses pre-compilation when passed literal value, whereas Huff, I believe, does not. This means performance can differ significantly depending on how much literal data is passed. For example in Hiccup:
Is macro-expanded to:
(For
hiccup2.core/html
it gets a little more complex as it has to account for automatically escaping unknown strings, but overall it's the same principle.)This is obviously very fast because it just uses string concatenation, and will outperform a runtime parser. That's not to say a faster runtime parser like Huff couldn't be more useful in general, but it is worth clarifying.
On the subject of things worth clarifying, you may also want to mention that Huff has support for both Reagent-style fragments and Hiccup-style fragments in the form of lists. i.e. it looks like:
Will work correctly in Huff, at least judging from the tests.
The text was updated successfully, but these errors were encountered: