Closed Dynom closed 4 years ago
Thanks for the detailed report!
I opened #182, which I think fixes this. It would be great if you could run your benchmark on that and report back if this improves the v5 results?
If you like, we can also incorporate your benchmark setup in this repository for future reference!
Hi,
Thanks for your fast reply!
I've looked at your PR and placed a few comments. I'm not familiar enough with Jet to give any real feedback however.
I'm not entirely sure if a faster loader is the best solution, I think that preventing the lookups would be an even better approach. If anything the relatively slow disk I/O might help to illustrate the problem quite nicely.
I didn't fix it using a faster loader, I eliminated a code path you exposed in your benchmarks using GetTemplate()
where the parsed template (AST) was not cached in the Set after parsing, so subsequent calls to the same function had to open the template file and parse it all over again.
I'm pretty sure this is the major difference to v2: v2 cached the template correctly after parsing it once. If you can upload a zip containing you benchmark data, I'll run the benchmark myself to check whether my guess is correct.
Ah you're right 👌
When running against your branch:
BenchmarkJets
BenchmarkJets/Jetv2_________
BenchmarkJets/Jetv2_________-8 50058 23629 ns/op 5041 B/op 87 allocs/op
BenchmarkJets/Jetv5-sauerbraten
BenchmarkJets/Jetv5-sauerbraten-8 42816 27449 ns/op 6028 B/op 157 allocs/op
I'm not sure if removing the public set.Parse is breaking things for others. I used it in a test to verify correctness and it might be a breaking change for other leaning on it. It's clearly documented that it doesn't store it in cache, which was great for using it in tests.
If this is still the way forward I'll remove it from my tests, it's nothing I heavily lean on right now.
Thanks for verifying my PR, those numbers look ok, even though I'm sure we can still optimize at some point!
Oh, removing those methods is definitely breaking, and I'm not yet sure we will. It's good to know the problem was where I thought it was, though. The thing with Set.Parse() at the moment is that while it will not add the template you parse to the cache, it will cache all templates that are included or extended by the parsed template. I'll have to find a clean way to make sure those will be treated like the original template before re-adding Parse().
@sauerbraten Can u please create a new tag for this issue?
FYI: https://github.com/CloudyKit/jet/issues/178
Please ignore anything from kataras.
@summerblue: definitely, but I want to merge https://github.com/CloudyKit/jet/pull/183 since we now have breaking changes anyway. I'll do that and then prepare the v6 release.
@summerblue: https://github.com/CloudyKit/jet/releases/tag/v6.0.0
I've been doing several proof of concepts and the performance of v5's loading of templates is significantly less than of the v2 branch:
The setup
Versions:
The implementation and templates are identical, with the exception of some differences required for the different Jet versions:
The files:
The benchmark
Considerations
I noticed quite a bit of time spent in io (
Loader.Exists
). I wrote a quick-n-dirty Loader that pre-fetches all *.jet files and adds them to a map for faster subsequent lookups. This reduces the execution time to 17 ms (down from 267ms). But I think it only masks the problem, instead of properly solving it.I noticed many invocations to
Loader.Exists
andLoader.Load()
for already observed files. My guess so far is that some state should be preserved infunc (st *Runtime) executeList
whenst.executeInclude()
is invoked. Or that the way file paths are canonicalised should be more in line with how templates can be used in version 5. e.g.:{{ include "./index.jet" }}
{{ include "/index.jet" }}
{{ include "index.jet" }}
might all point to the same file.
Further findings
After I've plugged a different Loader I managed to get it down to the following. However I think this isn't the approach to take. I think the lazy-loading approach is probably a fine route to take, but right now it appears to not resolving efficiently.