jverzani / Mustache.jl

Port of mustache.js to julia
MIT License
129 stars 36 forks source link

Performance issues with including partials {{> ... }} #32

Open essenciary opened 8 years ago

essenciary commented 8 years ago

There seem to be some pretty bad performance issues with {{> ... }} For example in my code I get this measurements after the initial run:

template = Mustache.template_from_file(abspath(joinpath("app", "resources", string(resource), "views", string(action) * ".$RENDER_MUSTACHE_EXT")))
vals = merge(special_vals(), Dict([k => v for (k, v) in vars]))
@show vals
@time r = Mustache.render(template, vals)
vals = Dict{Any,Any}(:genie_assets_path=>"/")
0.083735 seconds (97.33 k allocations: 58.744 MB, 73.20% gc time)

The first line reads the template index.mustache.jl which is this:

<article class="content dashboard-page">
    {{> app/resources/dashboard/views/block_articles.mustache.jl }}
</article>

While block_articles.mustache.jl is a 6KB plain HTML file (no mustaches).

The culprit seems to be {{> app/resources/dashboard/views/block_articles.mustache.jl }}. If I include the content of block_articles.mustache.jl directly into index.mustache.jl, @time will output

0.000037 seconds (43 allocations: 9.109 KB)
essenciary commented 8 years ago

Also, parsing, in this case at least, when using {{> ... }} seems to be O(n) where n is the size of the template that is included. I've tested with a 50KB block_articles.mustache.jl plain HTML file and the parse time makes the application unusable in production.

Ideally including plain HTML should be O(1) and the performance of parsing the template should be a function of executing the mustaches.

Worse thing is that this ends up causing a segmentation fault in Julia after serving a few requests with HttpServer. How soon this happens is correlated to the size of the mustache templates (though it may not be directly the fault of this package, it does seem to trigger this behavior).

jverzani commented 8 years ago

I added a < partial tag for straight inclusion of a file. This bypasses the parse phase, which seems to be the bottle neck. Does this help?

essenciary commented 8 years ago

Thanks!

All right, so I should use {{ < ... }} which will just include the indicated file without parsing it.

Basically, this would only work if we'd be able to combine both {{ > ... }} and {{ < ... }} while taking care to extract most "dumb" markup into partials included via {{ < ... }} and putting mustaches into very small partials using {{ > ... }}. Right?

But we would not be able to use {{ > ... }} into a file included with {{ < ... }} -- which might be a big constraint. I'll give it a try and follow up if it doesn't work.

jverzani commented 8 years ago

Yeah, that's it. The parsing part is the big performance killer, this provides a bypass in some circumstances.

On Wednesday, August 10, 2016, Adrian Salceanu notifications@github.com wrote:

Thanks!

All right, so I should use {{ < ... }} which will basically just include the indicated file without parsing it.

Basically, this would only work if we'd be able to combine both {{ > ... }} and {{ < ... }} while taking care to extract most "dumb" markup into partials included via {{ < ... }} and putting mustaches into very small partials using {{ > ... }}. Right?

But we would not be able to use {{ > ... }} into a file included with {{ < ... }} -- which might be a big constraint. I'll give it a try and follow up if it doesn't work.

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/jverzani/Mustache.jl/issues/32#issuecomment-238884062, or mute the thread https://github.com/notifications/unsubscribe-auth/AAZvTPRnTlfpb1GC4JdWhtHIfCsUxFd1ks5qeeAOgaJpZM4JgcYX .

John Verzani Chair, Department of Mathematics College of Staten Island, CUNY verzani@math.csi.cuny.edu

essenciary commented 8 years ago

Got it, thanks!