Skip to content
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

partially render templates for improved performance? #67

Open
dvtate opened this issue Jun 26, 2024 · 3 comments
Open

partially render templates for improved performance? #67

dvtate opened this issue Jun 26, 2024 · 3 comments

Comments

@dvtate
Copy link

dvtate commented Jun 26, 2024

I'd like to pre-populate some fields in a template that will always be the same in order to improve performance. For example:

Hello {{user}}, welcome to {{server}}.

I'd like to prepopulate {{server}} since it will not change and this template will be generated potentially millions of times.

My first naive attempt to do this looked like this:

kainjow::mustache::data global_data;
global_data.set("server", get_hostname());
kainjow::mustache::mustache t = kainjow::mustache::mustache(template_str).render(global_data);

However this deletes the {{user}} field so the code

t.render({ "user", provided_username });

results in

Hello , welcome to localhost.

So, two questions:

  1. Is there a way to do this without manually setting each variable to "{{variable}}"?
  2. Would could this actually improve performance?

Thanks!

@KitsuneRal
Copy link
Contributor

KitsuneRal commented Jun 26, 2024

  1. Not that I know of. The problem is: how do you distinguish between intentionally absent values (like user in your case) and values that can be specified or unspecified depending on a data instance? Mustache cannot enforce non-emptiness of values. If you really need to make the prefilling work (see the next point) then you can derive from kainjow::mustache::context and replace certain {{...}} sections with themselves - or, if there are just few of such sections, just do global_data.set("{{user}}", "{{user}}"); and so on for each.
  2. This is the right question, and you are the only one who can answer it because it's your application and only you know how you use Mustache. From general considerations, I would say it's highly improbable for smaller templates - very very likely I/O and memory allocations from repeated rendering will dwarf any theoretical benefits from such optimisation. Entirely off the wall, if I were to deal with big (100 kBs or MBs) templates used numerous (1000s) times with some (1000s) values prefilled and others varying - I would do performance tests and see if prefilling makes sense for this kind of payloads. Anything less than that - I wouldn't even bother, unless shaving off milliseconds would make for a business case.

@dvtate
Copy link
Author

dvtate commented Jun 26, 2024

For now I'm using std::regex_replace on the templates before passing them into mustache... Maybe later I'll come up with something better.

This is a C++ framework so performance is usually pretty important for C++ devs, even if it's only a few percentage points improvement.

@kainjow
Copy link
Owner

kainjow commented Jun 29, 2024

If you have control of this template, you could maybe try the set delimiter tags and use different characters for the fields you want to pre-populate, then render that template with pre-populated fields, which would produce the final template for dynamic data.

For example, render this with a "server" value:

{{=[[ ]]=}}
Hello {{user}}, welcome to [[server]].

which would then produce:

Hello {{user}}, welcome to localhost.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants