Closed thheller closed 7 years ago
Thanks for the note! I didn't know about either of those compiler options.
It looks like both :optimize-constants and :static-fns both default to true
under advanced optimizations, which is something I need to setup (#3).
A bigger question for me would be: What are use cases where you'd want :simple optimizations to get faster, but where you don't want to use :advanced optimizations?
The only case I can think of is that you're terrified about missing an externs declaration and breaking your app in production. (Not that this has ever happened to me...) If that's the only case, perhaps instead of trying to make :simple faster, we can make :advanced safer by running it without variable renaming.
That the Closure library has a VariableRenamingPolicy enum suggests that it's possible, though I don't know if this can be leveraged from the cljs compiler api.
Thoughts?
:advanced
mode is about much more than just renaming some vars. If you turn off everything that doesn't work properly without externs you get :simple
. You really can't do much more without.
:optimize-constants
is the most important since it will result in my.ns.some_fn($cljs$core$cst$foo)
with the keyword only being allocated once as opposed to my.ns.some_fn(new cljs.core.Keyword(...))
allocating it over and over again.
So with that and :static-fns
you get close enough performance wise.
Running benchmarks without these will produce misleading results since allocating keywords in a loop may cause many extra GC pauses.
If you really can ensure perfect externs though :advanced
will be far better.
Got it, thanks for the info!
What's the downside of :optimize-constaints
? Is the only reason it's off by default because it leads to longer compilation times?
Re: GC pauses, I'm looking into a way to disable GC during the benchmarks, since that seems to be the most straightforward way to measure memory usage (i.e., allocations per re-render).
:optimize-constants
does not work with incremental compilation.
I actually wasn't aware it was enabled for :advanced
automatically, it should probably be for :simple
and :whitespace
as well.
No idea if you can disable GC. Given how much React and the wrappers allocate that might not actually work too well too. Also wouldn't resemble real-world situations.
You might want to look at a setup like this: https://github.com/krausest/js-framework-benchmark http://www.stefankrause.net/wp/?p=218 http://www.stefankrause.net/wp/?p=191 http://www.stefankrause.net/wp/?p=283 http://www.stefankrause.net/wp/?p=301 http://www.stefankrause.net/wp/?p=316 http://www.stefankrause.net/wp/?p=392
Thanks for links, someone else pointed me towards that project.
Can you clarify what you meant by this:
:advanced mode is about much more than just renaming some vars. If you turn off everything that doesn't work properly without externs you get :simple.
My understanding from the Closure docs is that :advanced
will also do dead code elimination and inlining, which aren't obviously (to me) related to renaming.
In any event, I'll do some experiments later today and see what shakes out. Thanks!
Didn't have time to look at your full benchmark setup but you are missing two very important compiler options in your
build.clj
. In anything performance sensitive you want to have:static-fns true
and:optimize-constants true
.Without those I get
with
I suppose that is a gain, don't exactly sure what the numbers stand for.
Might have some more suggestions tomorrow.