Replies: 2 comments 1 reply
-
Hey, thanks for the detailed post. I'm not very active on Mindcode or Mindustry anymore, so feel free to create issues and pull requests as you see fit. I will review them and deploy them to production. |
Beta Was this translation helpful? Give feedback.
1 reply
-
Implemented in the March 2023 update or moved to wish list, closing. |
Beta Was this translation helpful? Give feedback.
0 replies
# for free
to join this conversation on GitHub.
Already have an account?
# to comment
-
Good morning @francois,
First of all, I’d like to thank you for creating Mindcode – it’s a tool that vastly improved my Mindustry experience. I couldn’t create or maintain the code I’ve written without it. Moreover, as the information on Mindustry Logic is pretty scarce, your examples on the compiler page itself and in the Mindcode syntax documentation helped me a lot understanding Mindustry logic itself. Kudos to you for this wonderful tool! 👍
Lately I’ve took some interest in the Mindcode itself (and I hope my activity here doesn’t feel too overwhelming). Over the time I spent just using Mindcode I got some ideas to further advance it, and now I feel confident I could even participate on the project a bit. At the same time, I want to be sure my ideas and contributions would fit well both into the current framework of Mindcode and your vision for its future.
What actually brought me here was my initial attempt to optimize the Mindcode’s output a bit further. I’ve developed a proof-of-concept outside of Mindcode at first, then tried to incorporate it into Mindcode itself. I have now a few working improvements of the optimizer ready to roll out, and a few others in the works. Shall I create issues for these ideas, so that we could discuss them if necessary and then turn them into a PR? Here’s a list of all of them:
Eliminate jumps to the next line (solves #50)
This has a significant impact (on my two largest Mindcode programs it eliminated 5-6% of instructions). Additionally, "always false" jumps are also removed, but this has very limited impacts (I get them from my
while true
loops I sometimes use). This one is PR-ready.Propagate jump targets
Moderate impact. If a jump (conditional or unconditional) targets an unconditional jump, the target of the first jump is redirected to the target of the second jump, repeated until the end of jump chain is reached. This doesn’t lessen the number of instructions, but results in a faster execution, while preserving the logic. Two additional optimizations are also performed:
end
instruction is handled as if it was an unconditional jump to the start of the program. As far as I know, in Mindustry v6 Logic reaching the end of instruction list,end
andjump 0 always
are identical. Will investigate v7 about this.@time
,@tick
or@counter
. I’ll add an exception for these.) I do have a few of these in my Mindcode codebase, but perhaps it’s a consequence of not having a break statement and will disappear once that is implemented.Remove inaccessible instructions
Limited impact. The compiler normally doesn’t generate them, but inaccessible instructions can appear as a result of the previous optimization (jumps that were left hanging because the jumps that led to them were re-targeted). A list of active labels is created (I do include set and write operations used for functions when creating the list), and instructions that follow an unconditional jump and don’t have an active target are removed.
Remove temporary variables before instruction that consumes them (solves #52)
This has a significant impact (removes a whopping 30% of instructions in my most drawing-heavy program). It is an optimization which generically implements all the OptimizeSetThen_Something_ classes and extends it to all existing instructions. It looks for instructions that set temporary variables to something and later use the variables as a parameter to another instruction. The original argument passed to the set is passed directly into the other instruction and the set instruction is removed. The replacement is only made when the variable is temporary and isn’t used anywhere else in the code (so this should be pretty safe). This would replace lots of the original optimizers in the pipeline (probably all of the OptimizeSetThen_Something_ except the OptimizeSetThenPrint, as this one does more things). For additional safety it would be checked the involved instruction argument is input; optimization wouldn’t be performed for output arguments.
Remove temporary variables after instruction that produces them
Moderate impact. This is similar to previous optimization, except done to the output arguments of instructions. Would replace Optimize_Something_ThenSet classes. Safety checks analogous to the previous case are be performed.
Remove unnecessary assignments in case expressions
Limited impact. Case expression creates
astX
variable, which is then testes in individual branches. If the case expression is a user-defined variable, theastX
can be replaced with that variable directly.All of the above were tested at least as a concept and some of them are ready to be made into a PR. I have a few more that I haven’t tried yet, but I intend to:
Ternary operation optimization
A ternary expression
currently compiles down to 6 instructions (after all of the above optimizations). It could be shortened down to
I’ll be working on this one.
Join strings in consecutive prints
This is a small one. If there are two consecutive print instructions with no label in between them, and both output a string, merge them into one instruction outputting a joined string. Therefore
would compile to
saving one instruction.
Note: in the user interface, Mindustry 6 Logic limits the length of strings to 36 characters (double quotes count against the limit). However, when the instructions are pasted from a clipboard, longer print strings are imported without truncation.
Improving Boolean expressions in conditions
The code
could be turned into
Similarly, for
or
:could be turned into
However, all this might perhaps be generalized into short-circuit Boolean evaluation, which might be better handled in the compiler itself. I’m still pondering this.
Improving function calls
Some code can also be eliminated in function calls. I’m looking into it. I don’t use functions regularly, as the time and space price is considerable for the programs I create.
All these improvements stem from my own experience with Mindustry, so they're real-life based, but my perspective certainly isn't universal and I might be missing on something big. Still, I believe these improvements would benefit most of the users.
(Sorry for such a long post.)
Beta Was this translation helpful? Give feedback.
All reactions