自定义排序和内置排序性能的PK
多线程+切分集合+二分排序的计算速度超过了微软内置排序的运算速度
遗憾的是,当设置1亿条数据时,多线程排序会造成内存溢出;
System.OutOfMemoryException
微软内置的排序算法肯定也用了多线程,不得不说微软内置排序算法确实很强大;
冒泡排序的性能真的很烂,如果数据超过千万条,估计要跑一天
元素个数=50000000 五千万条数据
多线程+切分集合+二分排序时间=32045228(Ticks)----3.2秒
内置排序所用时间=58400721(Ticks) ----5.8秒
元素个数=20000000 两千万条数据
多线程+切分集合+二分排序时间=13412114(Ticks) ----1.3秒
内置排序所用时间=23072997(Ticks)----2.3秒
元素个数=10000000 一千万条数据
切分集合+二分排序时间=2909079182(Ticks) ----290秒
多线程+切分集合+二分排序时间=7173966(Ticks)----0.7秒
内置排序所用时间=13966604(Ticks)----1.3秒
元素个数=100000 十万条数据
冒泡排序时间=716392135(Ticks)----71秒
二分排序时间=2636853(Ticks)----0.2秒
切分集合+二分排序时间=658131(Ticks)----0.065秒
多线程+切分集合+二分排序时间=351530(Ticks)----0.035秒
内置排序所用时间=84013(Ticks)0.008秒
716392135/84013=8 527倍
元素个数=100000,二分排序所用时间=2825701(Ticks) 0.2秒
元素个数=100000,冒泡排序所用时间=745813520(Ticks) 74秒
冒泡排序与二分排序时间之比为=263.939291524475
测试程序
//二分排序、冒泡排序、内置排序性能比较
static void test7()
{
List<int> list = new List<int>();
Random r = new Random();
Stopwatch watch = new Stopwatch();
for (int i = 0; i < 100000; i++)
{
list.Add(r.Next(0, 100000000));
}
//list = new List<int>() { 5, 4, 3, 2, 1 };
Console.WriteLine($"元素个数={list.Count}");
//冒泡排序
watch.Restart();
List<int> list10 = BubbleSortAscend(list);
watch.Stop();
Console.WriteLine($"冒泡排序时间={watch.ElapsedTicks}(Ticks)");
//二分排序
watch.Restart();
List<int> list20 = BinarySortAscend(list);
watch.Stop();
Console.WriteLine($"二分排序时间={watch.ElapsedTicks}(Ticks)");
//切分集合的二分排序
watch.Restart();
List<int> list30 = BinarySortAscendC(list);
watch.Stop();
Console.WriteLine($"切分集合+二分排序时间={watch.ElapsedTicks}(Ticks)");
//多线程的,切分集合的二分排序
watch.Restart();
List<int> list40 = BinarySortAscendT(list);
watch.Stop();
Console.WriteLine($"多线程+切分集合+二分排序时间={watch.ElapsedTicks}(Ticks)");
//内置排序
watch.Restart();
List<int> list50 = new List<int>(list);
list50.Sort();
watch.Stop();
Console.WriteLine($"内置排序所用时间={watch.ElapsedTicks}(Ticks)");
}
多线程+集合切分+二分排序(终极必杀技)
//将集合切分为10个,并用多线程分别排序
static List<int> BinarySortAscendT(List<int> list)
{
int min = list[0], max = list[0];
List<int> list1 = new List<int>();
List<int> list2 = new List<int>();
List<int> list3 = new List<int>();
List<int> list4 = new List<int>();
List<int> list5 = new List<int>();
List<int> list6 = new List<int>();
List<int> list7 = new List<int>();
List<int> list8 = new List<int>();
List<int> list9 = new List<int>();
List<int> list10 = new List<int>();
for (int i = 1; i < list.Count; i++)
{
if (list[i] < min) min = list[i];
if (list[i] > max) max = list[i];
}
int range = max - min;
int a1 = range / 10;
int a2 = range / 10 * 2;
int a3 = range / 10 * 3;
int a4 = range / 10 * 4;
int a5 = range / 10 * 5;
int a6 = range / 10 * 6;
int a7 = range / 10 * 7;
int a8 = range / 10 * 8;
int a9 = range / 10 * 9;
for (int i = 0; i < list.Count; i++)
{
if (list[i] >= min && list[i] < a1) list1.Add(list[i]);
else if (list[i] >= a1 && list[i] < a2) list2.Add(list[i]);
else if (list[i] >= a2 && list[i] < a3) list3.Add(list[i]);
else if (list[i] >= a3 && list[i] < a4) list4.Add(list[i]);
else if (list[i] >= a4 && list[i] < a5) list5.Add(list[i]);
else if (list[i] >= a5 && list[i] < a6) list6.Add(list[i]);
else if (list[i] >= a6 && list[i] < a7) list7.Add(list[i]);
else if (list[i] >= a7 && list[i] < a8) list8.Add(list[i]);
else if (list[i] >= a8 && list[i] < a9) list9.Add(list[i]);
else list10.Add(list[i]);
}
List<Task<List<int>>> taskList = new List<Task<List<int>>>();
Func<Object, List<int>> func1 = BinarySortAscendT;
var t1 = new Task<List<int>>(func1, list1); taskList.Add(t1);
var t2 = new Task<List<int>>(func1, list2); taskList.Add(t2);
var t3 = new Task<List<int>>(func1, list3); taskList.Add(t3);
var t4 = new Task<List<int>>(func1, list4); taskList.Add(t4);
var t5 = new Task<List<int>>(func1, list5); taskList.Add(t5);
var t6 = new Task<List<int>>(func1, list6); taskList.Add(t6);
var t7 = new Task<List<int>>(func1, list7); taskList.Add(t7);
var t8 = new Task<List<int>>(func1, list8); taskList.Add(t8);
var t9 = new Task<List<int>>(func1, list9); taskList.Add(t9);
var t10 = new Task<List<int>>(func1, list10); taskList.Add(t10);
foreach (var task in taskList) task.Start();
Task.WhenAll(taskList);
list1.AddRange(list2);
list1.AddRange(list3);
list1.AddRange(list4);
list1.AddRange(list5);
list1.AddRange(list6);
list1.AddRange(list7);
list1.AddRange(list8);
list1.AddRange(list9);
list1.AddRange(list10);
return list1;
}
集合切分+二分排序
//将集合切分为10个,再分别二分排序
static List<int> BinarySortAscendC(List<int> list)
{
int min = list[0], max = list[0];
List<int> list1 = new List<int>();
List<int> list2 = new List<int>();
List<int> list3 = new List<int>();
List<int> list4 = new List<int>();
List<int> list5 = new List<int>();
List<int> list6 = new List<int>();
List<int> list7 = new List<int>();
List<int> list8 = new List<int>();
List<int> list9 = new List<int>();
List<int> list10 = new List<int>();
for (int i = 1; i < list.Count; i++)
{
if (list[i] < min) min = list[i];
if (list[i] > max) max = list[i];
}
int range = max - min;
int a1 = range / 10;
int a2 = range / 10 * 2;
int a3 = range / 10 * 3;
int a4 = range / 10 * 4;
int a5 = range / 10 * 5;
int a6 = range / 10 * 6;
int a7 = range / 10 * 7;
int a8 = range / 10 * 8;
int a9 = range / 10 * 9;
for (int i = 0; i < list.Count; i++)
{
if (list[i] >= min && list[i] < a1) list1.Add(list[i]);
else if (list[i] >= a1 && list[i] < a2) list2.Add(list[i]);
else if (list[i] >= a2 && list[i] < a3) list3.Add(list[i]);
else if (list[i] >= a3 && list[i] < a4) list4.Add(list[i]);
else if (list[i] >= a4 && list[i] < a5) list5.Add(list[i]);
else if (list[i] >= a5 && list[i] < a6) list6.Add(list[i]);
else if (list[i] >= a6 && list[i] < a7) list7.Add(list[i]);
else if (list[i] >= a7 && list[i] < a8) list8.Add(list[i]);
else if (list[i] >= a8 && list[i] < a9) list9.Add(list[i]);
else list10.Add(list[i]);
}
list1 = BinarySortAscend(list1);
list2 = BinarySortAscend(list2);
list3 = BinarySortAscend(list3);
list4 = BinarySortAscend(list4);
list5 = BinarySortAscend(list5);
list6 = BinarySortAscend(list6);
list7 = BinarySortAscend(list7);
list8 = BinarySortAscend(list8);
list9 = BinarySortAscend(list9);
list10 = BinarySortAscend(list10);
list1.AddRange(list2);
list1.AddRange(list3);
list1.AddRange(list4);
list1.AddRange(list5);
list1.AddRange(list6);
list1.AddRange(list7);
list1.AddRange(list8);
list1.AddRange(list9);
list1.AddRange(list10);
return list1;
}
二分查找和二分排序
//降序排序集合的二分查找,返回值为应该插入的索引值
public static int BinarySearchDescend(List<int> list, int value, int low, int high)
{
if (list.Count == 0) return 0;
int middle = (low + high) / 2;
if (high == low + 1)
{
if (value <= list[high]) return high + 1;
else if (value <= list[low]) return low + 1;
else return low;
}
else if (high == low)
{
if (value <= list[high]) return high + 1;
else return high;
}
else
{
if (value > list[middle]) return BinarySearchDescend(list, value, low, middle);
else if (value < list[middle]) return BinarySearchDescend(list, value, middle, high);
else return middle;
}
}
//升序的二分查找,返回值为应该插入的索引值
public static int BinarySearchAscend(List<int> list, int value, int low, int high)
{
if (high - low > 1)
{
int middle = (low + high) / 2;
if (value < list[middle]) return BinarySearchAscend(list, value, low, middle);
else if (value > list[middle]) return BinarySearchAscend(list, value, middle, high);
else return middle;
}
else if (high == low + 1)
{
if (value >= list[high]) return high + 1;
else if (value >= list[low]) return low + 1;
else return low;
}
else
{
if (value >= list[high]) return high + 1;
else return high;
}
}
//二分排序-降序
static List<int> BinarySortDescend(List<int> list)
{
List<int> result = new List<int>();
int insertPos;
for (int i = 0; i < list.Count; i++)
{
insertPos = BinarySearchDescend(result, list[i], 0, result.Count - 1);
if (insertPos >= result.Count) result.Add(list[i]);
else result.Insert(insertPos, list[i]);
}
return result;
}
//二分排序-升序
static List<int> BinarySortAscend(List<int> list)
{
List<int> result = new List<int>();
int insertPos;
result.Add(list[0]);
int count = list.Count;
for (int i = 1; i < count; i++)
{
insertPos = BinarySearchAscend(result, list[i], 0, result.Count - 1);
if (insertPos >= result.Count) result.Add(list[i]);
else result.Insert(insertPos, list[i]);
}
return result;
}
//二分排序-升序-多线程
static List<int> BinarySortAscendT(Object obj)
{
List<int> list = (List<int>)obj;
List<int> result = new List<int>();
int insertPos;
result.Add(list[0]);
int count = list.Count;
for (int i = 1; i < count; i++)
{
insertPos = BinarySearchAscend(result, list[i], 0, result.Count - 1);
if (insertPos >= result.Count) result.Add(list[i]);
else result.Insert(insertPos, list[i]);
}
return result;
}