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

Consider using string_builder.prepend in generated Gleam code #26

Open
michallepicki opened this issue Oct 23, 2022 · 4 comments
Open

Comments

@michallepicki
Copy link
Contributor

michallepicki commented Oct 23, 2022

I like that matcha can leverage string_builder to generate more efficient code for the Erlang VM by avoiding unnecessary binary concatenations (it's Erlang's iolist underneath after all, which can be easily used for IO and network operations without invoking string_builder.to_string). I'm not sure what Elixir templates get compiled to, but I suspect they rely on this to be fast as well, and possibly even use literal lists where possible to avoid unnecessary overhead.

Currently matcha uses string_builder.append a lot, I wonder how it affects performance? Underneath it creates a new list with existing builder at first element and appended string in tail position. So we end up with something like this: [ [ [ [ [ A | [] ] | B ] | C ] | D ] | E ]. A more natural representation for the same data would be: [ A | [ B | [ C | [ D | [ E | [] ] ] ] ] ] (which is just [A, B, C, D, E]).

Would it be more efficient to build up the result in reverse order and use string_builder.prepend? Can we measure this somehow?
Is it bad that potential side effects would be executed "from the end" of the template .matcha code? (In a well written "view layer" of an application there should be no side effects, but in a real application or when debugging, life happens)
Would the resulting .gleam code be much less readable, or would it be acceptable?

@lpil
Copy link

lpil commented Oct 23, 2022

I think we definitely want to maintain order of side effects, it would be very confusing otherwise.

I think a good approach could be to assign a variable for each chunk and then construct a single list from all of them.

It will be worth doing some benchmarking on the different generated code options before making any changes to the library to create them as it could be wasted effort otherwise.

@michallepicki
Copy link
Contributor Author

I think for benchmarking a realistic use-case would be rendering a template and sending this data through a socket. Probably hard to measure that without a lot of noise from other factors, so maybe rendering a template and saving to a file would be similar enough?

@lpil
Copy link

lpil commented Oct 23, 2022

I would also be interested in how quickly it can be collected to a string, and how fast it would be using the string concatenation operator.

@diemogebhardt
Copy link
Contributor

To whomever is going to tackle this in the future:

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