You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This replaces the current array-based approach with a simple binary search tree. The runtime of the benchmark is ~13x faster (using hyperfine):
Before: 4.300 s ± 0.178 s
After: 323.2 ms ± 42.1 ms
My main goal with the binary search tree was simplicity of implementation. I figure fake-indexeddb has more value as a "reference implementation" for IndexedDB rather than a hyper-optimized database. (But it's still nice for it to be ~13x faster!)
I opted for a basic red-black tree with a deletion strategy borrowed from the scapegoat tree. Deletion in a scapegoat tree is much simpler: you just mark nodes with deleted tombstones and rebuild the tree if there are too many tombstones, which avoids rotations to rebalance. I felt this was a good compromise to try to keep things simple. I doubt most fake-indexeddb users are deleting a bunch of nodes (you'd more normally just throw away the whole database between each test), and even if they do, the amortized cost of the deletions is still O(log(n)).
(Using a scapegoat tree itself is a nice idea, but it falls apart on insertions. The FDBObjectStore.count performance should be reasonable test is extremely slow with a scapegoat tree, because nodes are inserted in sorted order, which basically devolves into a linked list where the tree is rebuilt on every insertion. Whereas with the current tree, that particular test is only slightly slower: 214ms vs 127ms. It could probably be faster if I avoided recursion/generators, but again I was opting for readability.)
BTW the FDBObjectStore.count performance should be reasonable regression looks caused by the lookup costs rather than the insertion costs, which I imagine is because we're comparing the cost of iterating through an array versus iterating through a custom binary search implementation. I still think it could be improved, but I'm not sure it's worth the effort.
Your call! 🙂 I was planning on doing some more tinkering this weekend, but maybe it's good to have a release just with this change, since there is some chance of regression with a big overhaul like this.
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
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.
Fixes #44
This replaces the current array-based approach with a simple binary search tree. The runtime of the benchmark is ~13x faster (using
hyperfine):My main goal with the binary search tree was simplicity of implementation. I figure
fake-indexeddbhas more value as a "reference implementation" for IndexedDB rather than a hyper-optimized database. (But it's still nice for it to be ~13x faster!)I opted for a basic red-black tree with a deletion strategy borrowed from the scapegoat tree. Deletion in a scapegoat tree is much simpler: you just mark nodes with
deletedtombstones and rebuild the tree if there are too many tombstones, which avoids rotations to rebalance. I felt this was a good compromise to try to keep things simple. I doubt mostfake-indexeddbusers are deleting a bunch of nodes (you'd more normally just throw away the whole database between each test), and even if they do, the amortized cost of the deletions is stillO(log(n)).(Using a scapegoat tree itself is a nice idea, but it falls apart on insertions. The
FDBObjectStore.count performance should be reasonabletest is extremely slow with a scapegoat tree, because nodes are inserted in sorted order, which basically devolves into a linked list where the tree is rebuilt on every insertion. Whereas with the current tree, that particular test is only slightly slower: 214ms vs 127ms. It could probably be faster if I avoided recursion/generators, but again I was opting for readability.)