py/parse: Fold anonymous string objects. - #19598
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #19598 +/- ##
==========================================
- Coverage 98.55% 98.55% -0.01%
==========================================
Files 182 182
Lines 23316 23351 +35
Branches 5 5
==========================================
+ Hits 22980 23013 +33
- Misses 335 337 +2
Partials 1 1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Code size report: |
This commit adds the possibility for the compiler to merge anonymous string objects that get concatenated together, so that a single object is provided to the VM instead of having to build the object. For example, compiling statements like "Hello," + " " + "world!" would yield an opcode sequence like this: LOAD_CONST_STRING "Hello," LOAD_CONST_STRING " " BINARY_OP __add__ LOAD_CONST_STRING "world!" BINARY_OP __add__ whilst with folding, a single `LOAD_CONST_STRING` will be emitted, with the concatenation of the strings involved. This only applies if all members of the expressions are anonymous strings, otherwise the regular sequence of opcodes and partial strings will be emitted instead. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
67aeac4 to
7b4a4a1
Compare
Octoprobe PR report
FailuresGroup: run-tests.py --test-dirs=extmod_hardware
Group: run-tests.py --test-dirs=extmod_hardware --emit-native
Group: run-tests.py
Group: run-tests.py --via-mpy --emit native |
|
but is it needed? # fmt: off
s1 = "Hello World"
s2 = "Hello" " " "World"
s3 = "Hello" \
" " \
"World"
s4 = (
"Hello"
" "
"World"
)and they are all bytecode equivalent. |
That's why this is marked as draft :) I've got loads of code with strings wrapped using Now, I can probably make this more palatable by sneaking in |
|
On second thought, maybe this is better to stay out of the main source tree. Sorry :( |
|
Using adjacent string concatenation is IMO a good solution, rather than If anything this could be addressed with a small addition to the docs, saying that the former is optimised but the latter ( |
|
In the meantime I've added that to the flake8 plugin: https://codeberg.org/agatti/flake8-micropython/commit/cb06cb3084ccf11a38a33667e9a153f3eb040291. Docs-wise, where should that paragraph be added to, |
I think |
Summary
This PR adds the possibility for the compiler to merge anonymous string objects that get concatenated together, so that a single object is provided to the VM instead of having to build the object.
For example, compiling statements like
"Hello," + " " + "world!"would yield an opcode sequence like this:whilst with folding, a single
LOAD_CONST_STRINGopcode will be emitted, with the concatenation of the strings involved.This only applies if all members of the expressions are anonymous strings, otherwise the regular sequence of opcodes and partial strings will be emitted instead.
Testing
Besides making the test suite pass on Linux/x64 with
--via-mpy, a new test,basics/str_constfolding.pyhas been added to provide a few more string concatenation opportunities than what is available in the test suite right now.Trade-offs and Alternatives
The compiler/parser will obviously take up a bit more space, but I'm not sure how this can be shortened without making it more complicated than it is now.
For interactive usage, whilst folded parse nodes are removed from the tree, the QSTR backing the node leaves won't be evicted from within the parser. I'm not sure if it's a problem or not, or whether there's a way to mark now-unused QSTRs sitting in RAM as reclaimable or something like that.
Generative AI
I did not use generative AI tools when creating this PR.
I've had this in my own local tree for quite some time now, and I forgot to attempt upstreaming until now :| I've had some benefits with this for native-compiled files, however I'm not sure if this is worth of inclusion, hence why it's marked as draft.