Repository navigation
Conversation
Strip and uppercase each line once and keep the result in lists that all passes reuse. Check each line only against the rule for its opcode, and return early when no line starts with a rule opcode. Rule 6 still compares the original text, and the five-pass limit is unchanged. The benchmark based on test_compiler_for_loop_and_break takes 39% less time (138.75 ms -> 83.95 ms). On the loop/break test program, optimize_assembly alone goes from 87.5 us to 30.7 us. Co-Authored-By: Aiden <aiden@weco.ai>
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
TL;DR
optimize_assemblyinsrc/tiny8/compiler.pyfaster. It is the peephole step thatcompile_cruns on all generated code.test_compiler_for_loop_and_break: 138.75 ms -> 83.95 ms per batch, 39.4% less time.optimize_assemblyalone is 2.8x faster: 87.5 µs -> 30.7 µs.pytestpasses all 342 tests.ruff checkandruff format --checkpass.What & Why
Before this change, every pass called
strip()andupper()on the same line many times, once for each rule. Every line was also checked against all six rules, even when its opcode cannot start any of them. The code did this work again for each of the five passes.Now the function computes the stripped uppercase form and the opcode of each line one time. It keeps them in lists. The passes move line indexes and reuse these lists. The rule for the current opcode is the only rule that runs. Lines with other opcodes are copied without more checks. If no line starts with a rule opcode, the function returns early.
The output stays identical because each rule makes the same comparison as before. The old code compared uppercased operands, so it is equal to compare parts of the uppercased line. Rule 6 (
JMP label/label:) still compares the original text, so it stays case-sensitive. The five-pass limit, the rule order and the returned line text do not change. The function still does not change its input list.Results
Times are the best of 7
timeitrepeats, median of 3 runs, on one CPU core with Python 3.12.optimize_assembly, loop/break test program (73 lines)optimize_assembly, 9 compiler test programs (1,140 lines)optimize_assembly, 9 test programs x10 (11,400 lines)compile_cof the loop/break test programoptimize_assembly, 2-line input, no rule matchesFor very short inputs, the new setup step costs about 0.3 µs. This cost is small next to the time to compile any real program.
Why this is safe and easy to maintain
The change touches only
optimize_assembly. Each rule keeps its own block with the same comments and order, so a reader can compare it with the old code. The output is the same for all inputs, including mixed case, extra spaces, comments, near misses and changes that need more than one pass. The tests intests/test_compiler.pycover every rule. We also compared the full output and CPU state with the old code on many generated programs and edge cases.Validation
Benchmark: the workload compiles, assembles and runs the
test_compiler_for_loop_and_breakprogram. It also runsoptimize_assemblyon the unoptimized output of 9 compiler test programs and on edge cases. Three runs gave 0.608, 0.606 and 0.606 of the old time. A short way to reproduce the direct timing:Checklist
ruff checkpasses)pytestsucceeds)AI assistance
Codex (gpt-6.1-sol) generated the optimization candidates, and Weco Observe tracked them. Automated checks picked this candidate: output comparison against the old code, the native test suite and benchmarks. No human review is claimed.
Weco share link: https://dashboard.weco.ai/share/aEGnUnfD2URSr8uIXsb-UneA_cAu0Avi