Skip to content
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

use boost::unordered_flat_map for iterator cache's _object_to_iterator #344

Merged
merged 1 commit into from
Aug 13, 2024

Conversation

spoonincode
Copy link
Member

I've noticed for some time that,

int add( const T& obj ) {
auto itr = _object_to_iterator.find( &obj );
if( itr != _object_to_iterator.end() )
return itr->second;
_iterator_to_object.push_back( &obj );
_object_to_iterator[&obj] = _iterator_to_object.size() - 1;
return _iterator_to_object.size() - 1;
}

shows up as taking 1.5%+ of main thread time on EOS. This function isn't doing much, and the iterator cache doesn't get large in practice. I'm not sure what is going on, but the overhead seems limited to libc++ builds (our pinned reproducible builds).

Switch the _object_to_iterator map to boost::unordered_flat_map. There is no ordering requirement for this map (either in consensus or as part of the implementation). For a replay over blocks 381452700 through 381632370, the pinned build improves by a consistent ~2%. There is no performance difference for a stdlibc++ build.

fwiw I tried a boost::container::map and it was even slower (a bit).

@heifner
Copy link
Member

heifner commented Jul 5, 2024

What about using std::unordered_map ?

@spoonincode
Copy link
Member Author

What about using std::unordered_map ?

It might be hard to believe but std::unordered_map seems no different than std::map. My replays have a timing variance under 0.25% so seeing a consistent ~2% improvement vs no change when running over and over again makes me rather confident on it.

@greg7mdp
Copy link
Contributor

It might be hard to believe but std::unordered_map seems no different than std::map

I think it makes sense, most of the time is probably spent in malloc/free (1 bucket per pair inserted in both std::map and std::unordered_map).

@ericpassmore
Copy link
Contributor

Note:start
group: STABILITY
category: PERFORMANCE
summary: Improve performance of _object_to_iterator, a frequently used operation on the main thread.
Note:end

@spoonincode spoonincode marked this pull request as ready for review August 13, 2024 20:47
@spoonincode spoonincode merged commit b96ed53 into main Aug 13, 2024
36 checks passed
@spoonincode spoonincode deleted the unordered_flat_map_iterator_cache branch August 13, 2024 21:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants