特殊排序算法和通用签名
special sorting algorithm and generic signature
我有一个强大的用例来定义我自己的排序算法,它比stl中最快的算法更快,并且通过利用底层数据的一些良好特性,我基本上可以在O(n)
中排序。
到目前为止还不错,现在的问题是,我想提供一个通用接口,它将适合任何类型的容器,例如T*
或std::vector<T>
等,只要应用几个关键概念,例如
- 有一个有效的运算符[]可用于访问集合的元素
- 该系列的元素支持"小于"的可比概念
为了获得想法,我去了头文件<std_algo.h>
,发现下面的函数接口与我想要的完全匹配,除了一个细节,我不知道编译器忽略容器类型会如何自动向量化在底层_RandomAccessIterator
中循环,这是我的问题。。。有没有办法让我拥有这一切?自动向量化+忽略基础集合类型的通用接口?
我认为由于"非规范"循环模式while (__last - __first > int(_S_threshold))
和类似if (__depth_limit == 0)
的条件,下面的代码不会自动向量化,但这最后一个我在算法中不需要。因此,我认为非规范类型的循环会阻止自动向量化。
template<typename _RandomAccessIterator, typename _Compare>
inline void sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
{
typedef typename iterator_traits<_RandomAccessIterator>::value_type
_ValueType;
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _ValueType,
_ValueType>)
__glibcxx_requires_valid_range(__first, __last);
if (__first != __last)
{
std::__introsort_loop(__first, __last,
std::__lg(__last - __first) * 2, __comp);
std::__final_insertion_sort(__first, __last, __comp);
}
}
有问题的循环看起来像这样:
// This is a helper function for the sort routine.
template<typename _RandomAccessIterator, typename _Size, typename _Compare>
void __introsort_loop(_RandomAccessIterator __first, _RandomAccessIterator __last, _Size __depth_limit, _Compare __comp)
{
while (__last - __first > int(_S_threshold))
{
if (__depth_limit == 0)
{
_GLIBCXX_STD_A::partial_sort(__first, __last, __last, __comp);
return;
}
--__depth_limit;
_RandomAccessIterator __cut =
std::__unguarded_partition_pivot(__first, __last, __comp);
std::__introsort_loop(__cut, __last, __depth_limit, __comp);
__last = __cut;
}
}
标准C++库在标准算法中使用迭代器,如sort()。这允许算法实现忽略底层容器的确切细节。此外,这种方法不允许使用operator[]()
进行索引。
考虑到这一点,我有两个建议供您考虑:
1) 修改您的专用排序以使用迭代器,而不是operator[]()
来访问容器中的元素。如果可以保持所需的O(n)速度,那么这可能是最理想的灵活性方法。
2) 使用模板化的容器类实现排序。类似的东西
template <class Container, class Compare>
void sort(Container cont, Compare comp);
应该做到这一点。
模板的美妙之处在于,在填充模板类型之前,它们不会被完全编译,因此编译器可以根据最终代码应用优化。T*
指针满足随机访问迭代器的所有必需属性,并且可以在任何需要它们的模板代码中轻松使用。
vector<float> v;
// load v
sort(&v[0], &v[v.size()]); // same as sort(v.begin(), v.end()) but possibly optimized better
- C++选择排序算法中的逻辑错误
- 排序算法c++
- 下面是排序算法O(n)吗
- 为什么我的排序算法会更改数组值
- C++运行时错误与快速排序算法抛出堆栈转储错误
- 排序算法问题(购买商店物品)(崩溃)
- 为什么这个选择排序算法仍然切换一个元素,当它已经是其他元素中最小的元素时?
- 为什么在此排序算法实现中,向量明显比数组慢?
- C++中合并排序算法的奇怪行为
- 我的排序算法程序中的堆错误
- 如何使用cpp编写选择排序算法以降序对元素列表进行排序?
- 解释一下这个排序算法是如何工作的?
- 快速排序函数在快速排序算法中如何工作?
- 分段故障,合并排序算法
- 这种排序算法已经存在吗?
- 为什么此代码上的排序算法不调用类的交换版本?
- 为什么我的替代排序算法不起作用?
- 选择排序算法生成无序结果
- 递归合并排序算法实现
- 这种快速排序算法有什么问题?