-
Notifications
You must be signed in to change notification settings - Fork 31
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
kvstore: simplified stmt exec #467
Conversation
iterator for `exec` - avoid callbacks etc for simplified row reading
4 yield statements inside an iterator would be quite heavy when it comes to code bloat. In the generated code, each |
3 (one is |
down to 2 with reasonable code: 2079341 |
If I understand correctly, the benefits of providing this API are rather superficial (some people will like the syntax better), but there are objective technical downsides (code bloat due to inlining). Were there any problems with the fact that the existing API is based on closures (e.g. were you running into limitations regarding captured variables)? |
yes, regarding bloat, I have sympathy for not introducing unnecessary bloat, but I have more sympathy for readability in general - I think some of your fears about bloat miss the bigger picture a bt: if we're going to combat bloat, we need to look at the real costs, and as we've discussed with actual numbers before, macros (async) and generics (ie iterators are really really sad already in nim - if we take away the ability to yield more than once, we might as well remove them entirely from our codebase because at that point, the mental overhead of keeping them in short-term active language feature memory is way too large, and we should advocate for their complete removal from Nim. finally, compilers are really good at removing bloat through CSE in cases like this when there there is a boolean choice between the branches (works / doesn't work) - the actual bloat in the final binary will be nonexistent. |
I've mentioned to @Araq a couple of times that having something akin to "Heap Allocation Elision" would be quite important, both for async with a future that doesn't escape its scope (and multithreading with Flowvar) and for chained closure iterators:
I can open a RFC. See: https://discord.com/channels/371759389889003530/371759389889003532/809802135629856808
|
this is not quite relevant here: the reason to pass in a the heap allocation is of less importance generally, even though avoiding it would be nice (for orthogonal reasons) |
When you author code, there are many layers of knowledge that you take into account (algorithmic, hardware, compilation theory, etc). Claiming that some of this knowledge is too much overhead, while other parts are acceptable is unreasonable IMO. Iterators should be used whenever this makes sense. If there are simple ways to optimize them, they should be exploited. If you weighting the two sides on a decision like "should I use a function or an iterator", the size of the body of the iterator and the number of yield statements should just add weight towards selecting the function approach. Technically, it's possible to implement the iterators with multiple code generation strategies in the compiler (e.g. you can pass the body as a closure), so perhaps the code bloat concerns can be addressed in a systematic way in the future without requiring much rework of the code. |
price vs performance - if a feature has so many caveats that it becomes an exception that you manage to use it correctly, it's the feature that is wrong, not the developer. |
yes, this is what I would hope for, and as long as there's no measurable downside, it's good to write code as naturally as possible so as to give the right priority signals to the compiler devs: maybe it's an imaginary downside or maybe it's really prevalent and important, and sometimes, you just don't know until you try. |
iterator for
exec
- avoid callbacks etc for simplified row reading