projectfluent / fluent-rs

Rust implementation of Project Fluent
https://projectfluent.org
Apache License 2.0
1.08k stars 97 forks source link

Precompiling and Embedding Resources for Performance Optimization #352

Closed BSFishy closed 4 months ago

BSFishy commented 5 months ago

As I'm exploring the fluent crate, specifically the usage section in the README, I had a question about resource handling. The documentation suggests that resources are parsed at runtime every time an application starts. I'm curious if there's a way to precompile and bundle the AST to enhance startup performance.

I'm relatively new to localization system design, so forgive me for any negligence. My primary concern revolves around runtime slow downs related to parsing resource files. For instance, if my application supports multiple languages but typically only one is used per session, wouldn't embedding pre-parsed ASTs for each language speed up the initialization process? Although this might increase memory usage, it could potentially eliminate the need for parsing during runtime.

Am I off base here? Is the time it takes to parse negligible? Or is this a valid concern, the systems just haven't been built out to support something like this out of the box?

Additionally, references to issue #36 and the i18n-embed-fl crate suggest that embedding data might be beneficial, but I'd like a better understanding of the rationale behind this.

I'm enthusiastic about contributing to the Fluent project and have been closely following discussions on issues https://github.com/projectfluent/fluent/issues/358 and #347. Looking forward to getting to know more about the project and hopefully contributing as soon as the safe harbor stuff gets through!

zbraniecki commented 5 months ago

Hi, this is largely dependent on your project, but I'd like to stress that Fluent parsing is very fast. You can run cargo bench on your own but on a regular laptop (cd fluent-bundle; cargo bench), but here's some back of a napkin calculations:

parsing and resolving 500 messages in a single file takes about 16 microseconds on my laptop.

To put this in a perspective, to achieve 60fps framerate, you need each frame to take less than 16 milliseconds.

You can parse and resolve 500 fluent messages one thousand times each and every frame to deplete this budget.

Now, of course you wouldn't want to do that, but since runtime language change/reload happens very rarely, you are very unlikely to exceed even a single frame budget this way. You need to look downstream at your stack, what else is involved? Constructing translated UI tree, layout, etc. those also take time. Caching translated UI tree may be a win, at the cost of having to implement cache invalidation etc. All I'm saying here is that I doubt that even on a very slow mobile phone parsing and resolution of fluent messages costs enough to build infra to avoid. YMMV

alerque commented 4 months ago

I think this is already largely covered, just a few notes:

If there is something that can be done to make interfaces more ergonomic so that higher level crates can better facilitate this kind of thing we'd be happy to consider it and consider contributions, but I think we can say that directly adding a precompile/embedding system into these crates is out of scope.