godot icon indicating copy to clipboard operation
godot copied to clipboard

GDScript: Optimize `match`

Open dalexeev opened this issue 2 years ago • 2 comments

  • Closes #63719.
  • Closes #75682.

Optimize match with jump tables whenever possible. I want to use two kinds of tables:

  1. OPCODE_JUMP_TABLE_RANGE. Can be used for continuous (or with a little sparsity) ranges of integers (such as enums). For example, from 0 to 10, or from 2 to 12. Instead of doing N comparisons (in the worst case), the jump address is calculated using the value, offset, and size.
  2. OPCODE_JUMP_TABLE_BSEARCH. Can be used to binary search in a constant array sorted at compilation. Suitable when the value is not an integer or the range is very sparse.

When using variable patterns, destructuring (and match guards in the future), the old bytecode will be preserved (or the branches will be divided into subgroups in which optimizations can be performed).

TODO

Parser
  • [x] (Bonus) Allow pass in match.
  • [x] Add warning REDUNDANT_PATTERN (multiple patterns with a wildcard pattern).
  • [ ] Add the ability to ignore warnings in match.
Analyzer
  • [x] Add error on type mismatch for typed variables. Reduces the impact of the non-obvious comparison difference from == operator described in #74462.
  • [ ] Add warning DUPLICATE_PATTERN.
Codegen, VM, disassembler
  • [x] Add opcodes OPCODE_JUMP_TABLE_RANGE and OPCODE_JUMP_TABLE_BSEARCH.
Compiler
  • [ ] Do not perform unnecessary operations if the type is known.
  • [ ] Optimize match with jump tables.
  • [ ] Remove unreachable branches?
Miscellaneous
  • [ ] Add tests.
  • [ ] Make benchmarks: PR vs master vs if-elif-else.

dalexeev avatar Jun 27 '23 11:06 dalexeev

My project uses a lot of match in performance-critical sections where GDScript is a bottleneck, so it would be nice to know if I can expect a free speedup in them anytime soon. Is this PR abandoned?

MewPurPur avatar Mar 24 '24 10:03 MewPurPur

Is this PR abandoned?

As far as I remember, I stopped because of #58878. I implemented a workaround with SafeVariantSort, but this did not seem elegant enough to me, since I had to create a separate table variant_vector_constants. Also, the compiler part is unfinished, but I think it is doable.

dalexeev avatar Mar 24 '24 12:03 dalexeev