张德长

导航

自定义排序和内置排序性能的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;
        }

 

posted on 2022-06-02 01:14  张德长  阅读(34)  评论(0编辑  收藏  举报