This is a small optimization, but I have not benchmarked.
Instead of building a hash->node map for each address being relayed, and then picking the top ones, just compute the top 1-2 ones directly.
This is a small optimization, but I have not benchmarked.
Instead of building a hash->node map for each address being relayed, and then picking the top ones, just compute the top 1-2 ones directly.
I had an alternative version that used a heap (which needs less iterator arithmetic), but realized that just explicitly keeping track of the top two is faster (and doesn't need any allocations).
4741 | @@ -4742,19 +4742,27 @@ static void RelayAddress(const CAddress& addr, bool fReachable, CConnman& connma 4742 | static const uint64_t salt0 = GetRand(std::numeric_limits<uint64_t>::max()); 4743 | static const uint64_t salt1 = GetRand(std::numeric_limits<uint64_t>::max()); 4744 | uint64_t hashAddr = addr.GetHash(); 4745 | - std::multimap<uint64_t, CNode*> mapMix; 4746 | const CSipHasher hasher = CSipHasher(salt0, salt1).Write(hashAddr << 32).Write((GetTime() + hashAddr) / (24*60*60)); 4747 | 4748 | - auto sortfunc = [&mapMix, &hasher](CNode* pnode) { 4749 | + std::array<std::pair<uint64_t, CNode*>,2> best{{{0, nullptr}, {0, nullptr}}}; 4750 | +
There should be an assert here that nRelayNodes is <=2, no?
utACK.
As we only need 1 or 2, explicitly keep track of the best ones.
I had an alternative version that used a heap (which needs less iterator arithmetic), but realized that just explicitly keeping track of the top two is faster (and doesn't need any allocations).
Yes if you just need the top two, a heap is overkill.
Even if this doesn't speed up the critical path this conceptually makes a lot of sense.
utACK a33b169