0

what is a faster?

sort two vectors and then do set_intersection... or

auto intersection = std::make_shared<MediaItems>();
std::sort(m_currentSearchResults->begin(), m_currentSearchResults->end());
std::sort(graphSearchResultMediaItems->begin(), graphSearchResultMediaItems->end());
std::set_intersection(
    m_currentSearchResults->begin(), m_currentSearchResults->end(),
    graphSearchResultMediaItems->begin(), graphSearchResultMediaItems->end(),
    std::back_inserter(*intersection));
std::swap(intersection, m_currentSearchResults);

or make them hashsets of the keys, and the do a find for-for-loop, then build the result by reverse lookup on the key?

auto projectKey = [](const auto& val) {return val.Key(); };
auto intersection = std::make_shared<MediaItems>();
std::unordered_set<mediaItemKey_t> currentRes;
std::unordered_set<mediaItemKey_t> graphRes;
std::ranges::for_each(std::views::transform(*m_currentSearchResults, projectKey), [&currentRes](const auto& val) { currentRes.emplace(val); });
std::ranges::for_each(std::views::transform(*graphSearchResultMediaItems, projectKey), [&graphRes](const auto& val) { graphRes.emplace(val); });
std::ranges::copy(
    currentRes
    | std::views::filter([graphRes](const auto& val) {return graphRes.find(val) != graphRes.end(); })
    | std::views::transform([strong_this](const auto& val) {return strong_this->m_mediaCollection->GetMediaItemByKey(val); }),
Jarod42
  • 203,559
  • 14
  • 181
  • 302
chrisg
  • 200
  • 8
  • 4
    Algorithmically, `O(n log n + m log m)` sort + `O(n + m)` intersection should be slower asymptotically than the `O(n)` + `O(m)` work done for the `unordered_set`. But C++'s `unordered_set`/`unordered_map` has a notoriously slow design, so it might take a *very* large input to overcome the (likely) higher constant (and non-constant, given how hash maps can behave) multipliers. Only way to know is to benchmark with representative data of the appropriate size (make sure to compile with optimizations enabled, or your benchmarks will be meaningless). – ShadowRanger Aug 17 '23 at 01:06
  • 10
    Why not profile it yourself? – o_oTurtle Aug 17 '23 at 01:07
  • O(n) doesn't tell the whole story. There is always a constant overhead, some datastructures are contiguous in memory (and then predictable access makes a huge difference). Then is the alogirthm branchless or not... In the end the design of your datastructure also matter. So you have only one thing to do : measure and measure again (on big enough datasets) and then reason about the bottlenecks you find. (Not only cpu usage, but cache misses and missed branch predictions are important too) – Pepijn Kramer Aug 17 '23 at 04:23
  • Answer to majority of such questions is either clear after just trying it out or depends on amount of objects involved and properties of (undisclosed) types of those. There are no much silver bullets nor useless things in C++ standard library. – Öö Tiib Aug 17 '23 at 06:32
  • Can you show the type declarations for `MediaItems`, `m_currentSearchResults`, and `graphSearchResultMediaItems`? I have this suspicion that there's extra work going into making copies of data structures than actual sorting/hashing in both. But I won't comment unless I know what these items are. – selbie Aug 17 '23 at 07:09

0 Answers0