Proof of concept: shape iv ancestor search #7429
Closed
+42
−1
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.
Opening this as draft because I'm not sure of the idea, but wanted to share it early. I haven't benchmarked realistic code or profiled or optimized yet.
This implements
rb_shape_get_iv_index_with_hint: a version of rb_shape_get_iv_index which uses a previous shape with a valid index for the given IV in order to speed up searches on a IV inline cache miss.This works by walking up both the hint shape's and current shape's tree branches in parallel until they meet at a common ancestor. If the common ancestor is deeper than the edge name we're looking for we can skip the remainder of the search. We also check for the edge name as we search.
The thinking behind this is that in many cases we have different, but very similar shapes, who share the common ancestor defining the IV we're looking for. This should also work well for a frozen version of a shape.
This is significantly faster when the divergence between the current and hint shape is shallow, but when it is not (there is no relation between the two shapes) it still resorts to a linear scan. The full scan is slower with this, as more work is being done, but I believe not 2x slower (the LL means we'll be stalling all the time on memory so walking two lists in parallel isn't so bad).
Benchmark: https://gist.github.com/jhawthorn/e9db7a1443eaa957cef772dccdc14d9a
With a shallow tree divergence
before:
ruby --disable-gems test_shape_search.rb 1.64s user 0.00s system 99% cpu 1.648 totalafter:
./miniruby test_shape_search.rb 0.67s user 0.00s system 99% cpu 0.666 totalWith a deep tree divergence (worse, assumed uncommon)
before:
ruby --disable-gems test_shape_search_deep.rb 1.64s user 0.00s system 99% cpu 1.643 totalafter:
./miniruby test_shape_search_deep.rb 1.88s user 0.01s system 99% cpu 1.889 totalcc @tenderlove @jemmaissroff