-
Notifications
You must be signed in to change notification settings - Fork 5
perf: optimize diff algorithm with 4x speedup #24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
- Interning: map items to int IDs for O(1) comparisons - Prefix/Suffix trimming: skip common head/tail before diff - IntIntMap: primitive int->int hash map (no boxing) - Int32List: reduced memory for ID arrays Benchmarks (1000 items): - RandomDiff: ~36% faster (202ms -> 130ms) - PrefixSuffix: ~4x faster (377µs -> 88µs) - InsertDelete: ~40% faster (3.8ms -> 2.3ms)
- IntIntMap: primitive int->int hash map with open addressing - Int32List: memory optimization for ID arrays - anchors.dart: patience-style anchor finding with LIS algorithm (prepared for future integration)
- Patience anchors now mark unique matches with negative IDs - Use Uint8List bitmask for O(1) anchor membership check - IntIntMap for fast hash-based interning - Maintain correct collision handling Results: - RandomDiff(10000): 15.5s -> 13.0s (16% faster) - RandomDiff(1000): 202ms -> 124ms (39% faster) - PrefixSuffix(1000): 378µs -> 86µs (4.4x faster)
Added @pragma vm:prefer-inline to: - _Snake.hasAdditionOrRemoval(), isAddition(), diagonalSize() - _Range.oldSize(), newSize() Results: - RandomDiff(1000): 124ms -> 116ms (6% faster) - RandomDiff(10000): 13.0s -> 12.6s (3% faster)
…avior The prefix/suffix optimization was greedily locking in matches for duplicate elements, changing which duplicate gets preserved. This caused regression test failures for issue knaeckeKami#15. Removed prefix/suffix trimming from both interner.dart and calculateDiff(). Other optimizations (interning, IntIntMap, anchors, inline pragmas) remain.
|
Interning now maps items to integer IDs using only |
|
Or: add a caller-supplied key (e.g., |
…handle hash collisions during item interning.
|
Very very good catch! Fixed! |
|
I added an AOT benchmark harness (
It reports median us/iter for sizes 10/100/1000/10000, diff patterns none/few/many, for both int lists and object lists (8-field class with standard Summary:
Full tables (median us/iter, AOT): int
object
This seems at odds with the PR description claiming ~20% to 10x speedups. Can you clarify how those measurements were obtained (workload, inputs, tooling, JIT vs AOT, warmups/samples)? I want to align the benchmark methodology so we compare apples-to-apples. |
Summary
Significant performance improvements to the diff algorithm through multiple optimizations:
areItemsTheSame()comparisonsBenchmarks
Breaking Changes
None. All existing tests pass without modification.