Your GDScript arrays are slower than you think β€” I built a CLI that detects the pitfalls and benchmarks them A developer built gd-bench, a zero-dependency CLI that scans Godot .gd files for array-type performance pitfalls and generates runnable GDScript micro-benchmarks for each finding. The tool flags untyped arrays, typed arrays, packed arrays, and dictionaries used as sequential-key arrays, then emits headless benchmark scripts so developers can measure before rewriting. The developer says the scanner-plus-benchmark approach is meant to let the tool's advice be compared against the official docs' guidance in a single command. "Why is my enemy loop stuttering? I'm not even doing anything heavy here." Every Godot tutorial tells you to just use arrays. Nobody tells you that an untyped array holds Variants, that a sequential-key Dictionary is ~2x slower than a plain Array, or that the official docs contradict themselves about packed arrays. This is about gd-bench , a CLI I built that scans your .gd files for array-type performance pitfalls and generates runnable Godot micro-benchmarks for each one β€” with zero dependencies and no LLM anywhere. https://github.com/sunnydachs/gd-bench https://github.com/sunnydachs/gd-bench Point it at a Godot project. It scans every .gd file and reports where the array-type choice is costing you performance, then writes a runnable benchmark script per finding so you can measure before you rewrite. pip install gd-bench gd-bench . scan the current project gd-bench . --gen-bench also generate Godot micro-benchmarks per finding Example output a small demo project, 7 files : js game/main.gd:4 🐒 UNTYPED ARRAY var inventory = untyped array β€” Variant soup - game/main.gd:5 πŸ”§ TYPED ARRAY var scores: Array int = typed array β€” fine but Packed is faster - game/main.gd:6 βœ… PACKED ARRAY var points: PackedVector2Array = PackedVector2Array already optimal - summary: {"typed array": 5, "dict as array": 2, "untyped array": 1, "packed array": 3} It reports 4 kinds of findings: var x = 1, 2, 3 holds Variants; slowest to iterate Array int gives compile-time checks but is still Variant-backed; PackedInt32Array is faster for the same element type var d = {} filled with sequential keys is ~2x slower and uses about half the memory again versus a plain Array A static type checker will never tell you which of these is actually slower in your loop β€” and the official docs can't agree either. Only a measurement can. This was the core design decision. A linter could just say "use PackedInt32Array here" and be done. But I deliberately built it as scanner + benchmark generator instead. Three reasons: Deterministic work deserves deterministic tools. The detail I obsessed over: the tool must never hand you a rewrite suggestion it hasn't equipped you to verify. So the rule is: That single line ζ›Έγζ›γˆε‰γ«εΏ…γšθ¨ˆζΈ¬ / "always measure before rewriting" is what keeps the tool from becoming another "just use X" voice. The generated script is plain GDScript extends SceneTree , runs headless so you can run it in CI or on a machine without the editor: godot --headless --script gd-bench-out/bench gd untyped array 4.gd gd-bench: untyped array untyped array: 8231 usec typed array: 5120 usec ratio: 1.61x Not a toy example β€” the detection patterns come from the same shapes real Godot projects and issues use: DICT AS ARRAY cases that were doing 1000 sequential-key inserts per frame The real win wasn't just "it works" β€” it's that the tool's advice and the docs' advice can be compared in one command, which is exactly what the godot-docs issue is asking for. var lines, {} + indexed assignment ; it does not catch arrays built through multi-line expressions or passed as literals into function calls. Frame time scales with your worst inner loop. Array-type choice is exactly the class of problem where "scanner + generated measurement" earns its keep: the advice is cheap to give, but only a benchmark tells you if it was true for your code. This is one in a series on the same principles β€” read-only, deterministic, zero-dependency CLIs that detect drift between what your code implies and what it does. Siblings: dep-triage Dependabot PR cleanup , pivot-diag Excel pivot audits , doc-drift README code-example drift , plan-drift tracking plan ↔ implementation , oas-drift OpenAPI spec ↔ code . Feedback, and especially false-positive reports from your own Godot projects , are the most useful thing you can give me β€” drop them in the repo