C++ Logo

std-proposals

Advanced search

Re: [std-proposals] A Proposal to Add a New Multiset container Method to the Standard Library Technical Report

From: Jonathan Wakely <cxx_at_[hidden]>
Date: Tue, 11 Feb 2025 16:50:09 +0000
On Tue, 11 Feb 2025 at 16:20, Александр Поваляев <apovalyaev_at_[hidden]>
wrote:

> Hmm
>
> I think that what a 'reduce' method is supposed to do is a very common
> case.
>

I don't think I've ever needed it.


> std:;multiset can handle several elements with the same key value, so it
> is quite straightforward to have a method in-place which will take care of
> this. Implementing this behaviour each time in your code is anyway a
> possibility to make a mistake.
> Moreover, when 'reduce' is a method, there is a possibility to make its
> realization more efficient within the lapse of time (for example, when an
> internal structure is changed somehow).
> Cause equal_range requires a lot of excessive comparison operations which
> might be quite inefficient.
> For example, if std::multiset consists of N elements within the same key
> value (and N is quite big: 1000, 10000, e.t.c.), your code will require
> 1000 comparison operations to just delete a couple.
>

No it won't, it's a binary tree so it's logarithmic.

But here's an (untested) alternative that doesn't use equal_range:

template<typename T, typename Cmp, typename Alloc>
std::size_t
reduce(std::multiset<T, Cmp, Alloc>& s, const T& key, std::size_t count =
-1zu)
{
  std::size_t n = 0;
  auto it = s.find(key);
  if (it == s.end())
    return 0;
  while (n < count)
  {
    it = s.erase(it);
    ++n;
    if (it == s.end() || s.key_comp()(key, *it))
      break;
  }
  return n;
}

This will do n comparisons instead of O(log2(N)) comparisons, where N is
s.count(key). You could make it adaptive so it uses a linear search for
small count arguments and equal_range otherwise.

It still doesn't need to be a member function though.

Received on 2025-02-11 16:50:26