我正在解决一个问题,它涉及非常快速地排序10个数字(int32).我的应用程序需要尽可能快地对10个数字进行数百万次排序.我正在对数十亿个元素的数据集进行采样,每次我需要从中挑选10个数字(简化)并对它们进行排序(并从排序的10个元素列表中得出结论).
目前我正在使用插入排序,但我想我可以实现一个非常快速的自定义排序算法,针对10个数字的特定问题,这将超过插入排序.
有没有人知道如何处理这个问题?
这是我很久以前遇到的问题.我想我可能会问你的想法.假设我有一个非常小的数字列表(整数),4或8个元素,需要快速排序.什么是最好的方法/算法?
我的方法是使用max/min函数(10个函数来排序4个数字,没有分支,iirc).
// s(i,j) == max(i,j), min(i,j)
i,j = s(i,j)
k,l = s(k,l)
i,k = s(i,k) // i on top
j,l = s(j,l) // l on bottom
j,k = s(j,k)
Run Code Online (Sandbox Code Playgroud)
我想我的问题更多地与实现有关,而不是算法的类型.
此时它变得有点依赖于硬件,所以让我们假设带有SSE3的Intel 64位处理器.
谢谢
我的CS作业需要一些帮助.我需要编写一个排序例程,在最坏的情况下使用7次比较对长度为5的数组进行排序(我已经证明,由于决策树的高度,需要7个).
我考虑使用决策树"硬编码",但这意味着算法非常复杂,并且我的导师暗示这不是它应该完成的方式.
我检查了快速排序,合并排序,堆排序,d-ary堆排序,插入排序,选择排序,都没有回答要求,这让我相信需要一个长度为5的数组的特定算法.
真的想得到正确方向的一些提示.
int a= {1,3,6,7,1,2};
Run Code Online (Sandbox Code Playgroud)
哪种是对以下数组进行排序的最佳排序技术,如果存在重复,则如何处理它们.也是最好的分拣技术....
void BubbleSort(int a[], int array_size)
{
int i, j, temp;
for (i = 0; i < (array_size - 1); ++i)
{
for (j = 0; j < array_size - 1 - i; ++j )
{
if (a[j] > a[j+1])
{
temp = a[j+1];
a[j+1] = a[j];
a[j] = temp;
}
}
}
}
Run Code Online (Sandbox Code Playgroud) 以下算法可以对三个变量进行排序x,y并使用以下z类型K进行比较operator<:
void sort2(K& x, K& y) {
if(y < x)
swap(x, y);
}
void sort3(K& x, K& y, K& z) {
sort2(x, y);
sort2(y, z);
sort2(x, y);
}
Run Code Online (Sandbox Code Playgroud)
这需要在"最坏情况"中进行三次交换.然而,基础数学告诉我们,三个值的排序只能使用两个交换来完成.
示例:值(c,b,a)将使用三个交换进行排序:(c,b,a) - >(b,c,a) - >(b,a,c) - >(a,b, C).然而,一次交换就足够了:(c,b,a) - >(a,b,c).
什么是最简单的算法,在所有情况下最多两次掉期对三个变量进行排序?
我有一些性能关键代码,涉及在C++中对大约3到10个元素之间的非常短的固定长度数组进行排序(参数在编译时更改).
在我看来,专门针对每个可能的输入大小的静态排序网络可能是一种非常有效的方法:我们进行必要的比较以确定我们所处的情况,然后进行最佳的交换数量以进行排序数组.
要应用此功能,我们使用一些模板魔法来推断数组长度并应用正确的网络:
#include <iostream>
using namespace std;
template< int K >
void static_sort(const double(&array)[K])
{
cout << "General static sort\n" << endl;
}
template<>
void static_sort<3>(const double(&array)[3])
{
cout << "Static sort for K=3" << endl;
}
int main()
{
double array[3];
// performance critical code.
// ...
static_sort(array);
// ...
}
Run Code Online (Sandbox Code Playgroud)
显然,编写所有这些代码非常麻烦,所以:
现在我只使用带有静态模板参数的插入排序(如上所述),希望它会鼓励展开和其他编译时优化.
欢迎你的想法.
更新: 我写了一些测试代码来比较'static'插入short和std :: sort.(当我说静态时,我的意思是数组大小是固定的并在编译时推断出来(可能是允许循环展开等).我至少得到20%的NET改进(请注意,生成包含在时间中).平台: clang,OS X 10.9.
代码在这里https://github.com/rosshemsley/static_sorting如果你想将它与你的stdlib实现进行比较.
我还没有为比较器网络分拣机找到一套很好的实现.
c++ arrays sorting template-meta-programming sorting-network
关于最快排序的固定长度6 int数组,我不完全理解这个排序网络如何击败像插入排序这样的算法.
形成该问题,这里是完成排序所需的CPU周期数的比较:
Linux 32位,gcc 4.4.1,Intel Core 2 Quad Q8300,-O2
- 插入排序(Daniel Stutzbach):1425
- 排序网络(Daniel Stutzbach):1080
使用的代码如下:
插入排序(Daniel Stutzbach)
static inline void sort6_insertion_sort_v2(int *d){
int i, j;
for (i = 1; i < 6; i++) {
int tmp = d[i];
for (j = i; j >= 1 && tmp < d[j-1]; j--)
d[j] = d[j-1];
d[j] = tmp;
}
}
Run Code Online (Sandbox Code Playgroud)
排序网络(Daniel Stutzbach)
static inline void sort6_sorting_network_v1(int * d){
#define SWAP(x,y) if (d[y] < d[x]) { int …Run Code Online (Sandbox Code Playgroud) 我没有在任何地方找到这个特定主题......
我在23个整数的std :: vector中的不同数据上调用nth_element()算法,每秒大约400,000次,更精确的"无符号短"值.
我想提高计算速度,这个特定的调用需要很大一部分CPU时间.现在我注意到,与std :: sort()一样,即使具有最高优化级别和NDEBUG模式(Linux Clang编译器),nth_element函数在探查器中也是可见的,因此比较是内联的而不是函数调用本身.好吧,更多的preise:不是nth_element()但是std :: __ introselect()是可见的.
由于数据的大小很小,我尝试使用二次排序函数PIKSORT,当数据大小小于20个元素时,它通常比调用std :: sort更快,可能是因为函数将是内联的.
template <class CONTAINER>
inline void piksort(CONTAINER& arr) // indeed this is "insertion sort"
{
typename CONTAINER::value_type a;
const int n = (int)arr.size();
for (int j = 1; j<n; ++j) {
a = arr[j];
int i = j;
while (i > 0 && a < arr[i - 1]) {
arr[i] = arr[i - 1];
i--;
}
arr[i] = a;
}
}
Run Code Online (Sandbox Code Playgroud)
然而,这比在这种情况下使用nth_element慢.
此外,使用统计方法是不合适的,比std :: nth_element更快
最后,由于值在0到约20000的范围内,因此直方图方法看起来不合适. …
解决以下问题的速度算法最有效的是什么?
给定6个阵列,D1,D2,D3,D4,D5和D6,每个包含6个数字,如:
D1[0] = number D2[0] = number ...... D6[0] = number
D1[1] = another number D2[1] = another number ....
..... .... ...... ....
D1[5] = yet another number .... ...... ....
Run Code Online (Sandbox Code Playgroud)
给定第二个数组ST1,包含1个数字:
ST1[0] = 6
Run Code Online (Sandbox Code Playgroud)
给定第三个数组ans,包含6个数字:
ans[0] = 3, ans[1] = 4, ans[2] = 5, ......ans[5] = 8
Run Code Online (Sandbox Code Playgroud)
使用数组D1,D2,D3,D4,D5和D6的索引,从0到存储在ST1 [0]中的数字减1,在本例6中,从0到6-1,将ans数组与每个D数组进行比较.如果在相同索引处的任何D中找不到一个或多个ans数,则结果应为0,如果在相同索引处的某个D中找到所有ans数,则结果应为1.也就是说,如果某些ans [i]不等于任何D N [i] 则返回0,并且如果每个ans [i]等于某个D N [i] 则返回1 .
到目前为止,我的算法是:
我试图尽可能地保持一切不受欢迎.
EML := ST1[0] //number contained in ST1[0]
EML1 := 0 //start index for the arrays D
While …Run Code Online (Sandbox Code Playgroud) 我正在阅读Osherove的"单元测试艺术",虽然我还没有看到他对性能测试有任何说法,但我还是想到了两个想法:
特别是出于上述第一个原因,我怀疑单元测试框架(例如NUnit)处理性能测试是否有意义.
我的问题是:我的发现/倾向是否符合社区的想法?
algorithm ×7
sorting ×7
c ×3
performance ×3
c++ ×2
arrays ×1
comparison ×1
cuda ×1
inline ×1
nth-element ×1
optimization ×1
unit-testing ×1