C++ std::稳定排序:如何选择内存优化算法而不是时间优化算法?

C++ std::稳定排序:如何选择内存优化算法而不是时间优化算法?,c++,sorting,std,c++17,stable-sort,C++,Sorting,Std,C++17,Stable Sort,我希望使用std::stable\u sort。该算法的复杂度如下所述: O(N·log^2(N)),其中N=标准::cmp的距离(第一个,最后一个)应用。如果有额外的内存可用,则复杂度为O(N·log(N)) 在我的应用程序中,内存是至关重要的,因此,我更愿意使用优化的内存O(N·log^2(N)) 算法,而不是时间优化的O(N·log(N))算法。 我知道只有在安全的情况下才会选择时间优化版本 要执行此操作(内存可用)。然而,我的目标是对我的应用程序进行基准测试,因此,由于内存至关重要,我希

我希望使用
std::stable\u sort
。该算法的复杂度如下所述:

O(N·log^2(N)),其中N=标准::cmp的距离(第一个,最后一个)应用。如果有额外的内存可用,则复杂度为O(N·log(N))

在我的应用程序中,内存是至关重要的,因此,我更愿意使用优化的内存O(N·log^2(N)) 算法,而不是时间优化的O(N·log(N))算法。 我知道只有在安全的情况下才会选择时间优化版本 要执行此操作(内存可用)。然而,我的目标是对我的应用程序进行基准测试,因此,由于内存至关重要,我希望在内存消耗最低时对算法进行基准测试。因为我的系统当前有足够的内存来分配 在缓冲区中,它将自动选择
std::stable_sort
的O(N·log^2(N))版本。因此,我想断言to
std::stable\u sort
to 以内存优化版为例。这可能吗

此时将显示执行策略 然而,作为一个可以修改算法的参数,它似乎 只改变平行度的范围。

尽管选择了其中一个 并行或顺序版本实际上可能选择O(N·log(N))或 O(N·log^2(N))版本,这在网页的任何地方都没有说明

我想知道是否有人有过这种选择的经验。如果是的话
他们能提供任何建议吗?

您可以查看您的头,看看如果额外的缓冲区不可用,会调用哪个函数。对我来说,gcc就是这样

    std::__inplace_stable_sort(__first, __last, __comp);
这当然不符合标准。_u_inplace_stable_排序是一个辅助函数,不打算直接使用

std::stable_sort对此函数的调用是以下代码的结果

typedef _Temporary_buffer<_RandomAccessIterator, _ValueType> _TmpBuf;
  _TmpBuf __buf(__first, __last);

  if (__buf.begin() == 0)
std::__inplace_stable_sort(__first, __last, __comp);
  else
std::__stable_sort_adaptive(__first, __last, __buf.begin(),
                _DistanceType(__buf.size()), __comp);
typedef\u临时缓冲区\u TmpBuf;
_TmpBuf(第一个,最后一个);
如果(uu buf.begin()==0)
std::uuu就地_u稳定_u排序(uuu第一、最后、复合);
其他的
std::\uuuuu稳定\uu排序\u自适应(\uuuuu第一,最后,\uuuu buf.begin(),
_距离类型(u buf.size()),u comp);

不幸的是,没有标准的方法告诉
稳定排序
执行就地排序。在C++14中,我们仅有的选项

template<class RandomAccessIterator>
void stable_sort(RandomAccessIterator first, RandomAccessIterator last);

template<class RandomAccessIterator, class Compare>
void stable_sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
模板
void stable_sort(首先是RandomAccessIterator,最后是RandomAccessIterator);
模板
void stable_sort(首先是RandomAccessIterator,最后是RandomAccessIterator,比较comp);
正如您所指出的,C++17添加了允许执行策略的版本,但这些版本也不会影响决策。如果我们在[stable.sort]中查看复杂性需求,我们会得到

复杂性:它最多进行
N log²(N)
(其中
N==last-first
)比较;如果有足够的额外内存可用,则为
N日志(N)。

因此,如果可用,它必须使用更多内存


你要么自己写,你可以看看,要么找到一个为你提供函数的库。

阅读,你就有了答案。@Someprogrammerdude我想OP知道这一点,但希望能够选择O(N log^2(N)),即使有可用空间(但我不完全确定为什么).不管怎样,当你不在目标系统上运行基准测试时,它有多有用?我希望这个特定的问题与总体不同的性能相比只会有一个小的影响,如果你有特定的要求,也许你应该考虑将你自己的一个排序算法实现到你的代码库。你可以使用它(因为强制<代码> STD::Stable排序> <代码>不使用内存是不可能的)。. 它的默认C++实现不需要额外的内存,对于就地稳定排序来说是相当好的性能。如果您对内存有一定的控制权,还可以强制它使用固定大小的缓冲区,这样可以在避免动态内存分配的同时提高性能。还有一个符合你的要求,在某个时候可能会包含在Boost中。这是我的建议,但请注意你正在进入龙出没的领域。在下一个编译器版本中不需要此函数。@izaak_pyzaak可能不足以满足您的基准测试需求?考虑到基准测试本身本质上是特定于实现的?假设您使用libstdc++,也就是说,这个答案是正确的,但我想澄清一些可能被误解的地方<代码>标准::uuuu就地_u稳定_u排序(uuu第一、最后、复合)绝对符合标准。这样的名称保留供实现使用,以便实现可以在不受外部人员干扰(或干扰)的情况下使用它们。在代码中使用这些名称可能会产生不可预测的结果。@izaak_pyzaak——不要让对龙的恐惧吓跑你。试试看。如果成功了,就成功了。如果您更改了编译器,但它不起作用,那么您必须找到另一个解决方案。但这是最简单的方法。不要为自己做额外的工作。如果你真的使用了这个,需要一个评论。否则,当它不可避免地破裂时,维护者有理由带着杀人犯的眼神追上你。解释什么和为什么。是的,这看起来像是共识。我想我得自己写了。干杯