v2.1: Refactors get_snapshot_storages() (backport of #3760) #3785
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.
Problem
AccountsDb::get_snapshot_storages()
is due for a refactor. We can speed it up for the common case, and also simplify.Since #3737, we now call
get_snapshot_storages()
every time weclean
. The observation here is we'll only need about 100 storages (on average), yet the current impl ofget_snapshot_storages()
Arc::clone's all the storages, and then filters out the unneeded ones. We can change this to only Arc::clone the useful ones instead.Additionally, the filter step is done in parallel. When we only have 100 storages, the parallel execution does not help. In fact, with a chunk size of 5000, we end up getting zero benefit, but do have to pay the cost of running in the thread pool.
Summary of Changes
Results
I ran this on against mnb and saw good results.
Since
get_snapshot_storages()
is called in two places, I wanted to look at the perf results in both.clean
Here, we only need ~100 storages each time. So not Arc::cloning and not using the thread pool really helps. The PR ends up running consistently, and meaningfully, faster:
Full snapshots do need all the storages, so we will end up Arc::cloning almost all the storages. And it's possible the thread pool does help here. For the most part, runtimes are pretty similar. The PR does have a worse worst-case filter time.
Overall, I think the common case of
clean
makes this change clearly a win. There is maybe a slight slow down for full snapshots, but that code is both infrequent, and in the background, so I don't think it matters much. Additionally, by not using a thread pool, we may reduce resource usage for the system as a whole.Justification to Backport
As per the Problem section, we now call get_snapshot_storages() during
clean
. Until the skipping rewrites feature is enabled, that means we'll be doing this extra work. The feature is in v2.1, and so mnb on v2.0 and v2.1 will be paying the extra cost. Thus, improving the performance for get_snapshot_storages() benefits the validator as a whole.In theory we could also backport to v2.0 as well, but I'm not currently advocating for that yet.
This is an automatic backport of pull request #3760 done by [Mergify](https://mergify.com).