2 lichjx lichjx 于 2016.09.19 17:09 提问

一个测试排序效率的小程序出现的现象,求解释

今天写了个小程序测试一些排序的效率玩,却发现计时器出现了个奇怪的现象,在取测试结果的时候
,如果测试的数组小,一切正常,每个排序的时间都能打印出来,但如果第二个数组很大,比如10万,第一个数组小,比如10,
则第一个打印结果的时间竟然变成了0ms,第二个排序的打印结果是正常的。
下面放代码:

这是事发地点:

 string[] res;
            //选择排序
            res = SortComponent<int>.selectionSortSimple(getBefroeSortArr());
            printEndInfo("selectionSortSimple:", res);
            //插入排序
            /*这行会出问题,第一组选择排序的执行时间变成了0 */
            //res = SortComponent<int>.insertSortSimple(getBefroeSortArr2(50000)); 
            /*这样取结果就没问题,选择排序的执行时间会打印出来*/
            string[] res1 = SortComponent<int>.insertSortSimple(getBefroeSortArr2(50000));
            printEndInfo("insertSortSimple:", res1);
            Console.ReadKey();

这是计时的类:

 class GCTiming
    {
        TimeSpan duration;
        public GCTiming()
        {
            duration = new TimeSpan(0);
        }
        public void StopTime()
        {
            duration = Process.GetCurrentProcess().TotalProcessorTime;
        }
        public void StartTime()
        {
            GC.Collect();
            GC.WaitForPendingFinalizers();
        }
        public TimeSpan Result()
        {
            return duration;
        }
    }

下面放上完整的程序:
progream.cs

  static void Main(string[] args)
        {
            printStartInfo();
            string[] res;
            //选择排序
            res = SortComponent<int>.selectionSortSimple(getBefroeSortArr());
            printEndInfo("selectionSortSimple:", res);
            //插入排序
            /*这行会出问题,第一组选择排序的执行时间变成了0 */
            //res = SortComponent<int>.insertSortSimple(getBefroeSortArr2(50000)); 
            /*这样取结果就没问题,选择排序的执行时间会打印出来*/
            string[] res1 = SortComponent<int>.insertSortSimple(getBefroeSortArr2(50000));
            printEndInfo("insertSortSimple:", res1);
            Console.ReadKey();
        }

        static void PrintArray(string[] array)
        {
           Console.WriteLine(SortUtil<string>.intArrToString(array));
        }

        static void printStartInfo()
        {
            Console.WriteLine("before sort:");
            PrintArray(Array.ConvertAll<int, string>(getBefroeSortArr(), s => s.ToString()));
        }

        static void printEndInfo(string name,string[] sortRes)
        {
            Console.WriteLine("after {0} sort:\r\n{2}\r\ntotal time is :{1}ms\r\n\r\n",name,sortRes[0],sortRes[1]);
        }

        static int[] getBefroeSortArr() {
            return new int[] { 2, 9, 2, 1, 8, 2, 3, 5, 19, 29, 13, 11, 45 };
        }

        static int[] getBefroeSortArr2(int length=100)
        {
            int[] arr = new int[length];
            Random rn = new Random();
            for (int i = 0; i < length; i++)
            {
                arr[i] = rn.Next(1, length);
            }
            return arr;
        }

排序类:

 /// <summary>
    /// 选择排序
    /// </summary>
    /// <typeparam name="T"></typeparam>
    class SortComponent<T> where T : IComparable<T>
    {

        public static string[] selectionSortSimple(T[] array)
        {
            int n = array.Length;
            GCTiming tiObj = new GCTiming();
            //Thread.Sleep(1000);
            tiObj.StartTime();
            Console.WriteLine("选择排序(selectionSort)开始:");
            for (int i = 0; i < n; i++)
            {
                int min = i;
                for (int j = i + 1; j < n; j++)
                {
                    if (array[min].CompareTo(array[j]) > 0)
                    {
                        min = j;
                    }
                }

                SortUtil<T>.swap(array, i, min);
            }
            tiObj.StopTime();
            return new string[] { tiObj.Result().TotalMilliseconds.ToString(), SortUtil<T>.intArrToString(array) };
        }

        public static string[] insertSortSimple(T[] array)
        {
            int n = array.Length;
            GCTiming tiOb = new GCTiming();
            tiOb.StartTime();
            Console.WriteLine("插入排序(insertionSort)开始:");
            //默认第一个元素排好序了,所以从第二个开始往排好序的方向比较
            for (int i = 1; i < n; i++)
            {
                //与排好序的方向比较,如果小于前面的就交换后继续比,直到相等或大于后,从刚才的i下标继续往n的方向取元素排序
                for (int j = i; j > 0; j--)
                {
                    if (array[j].CompareTo(array[j - 1]) < 0)
                    {
                        SortUtil<T>.swap(array, j, j - 1);
                    }
                    else//如果下标i指针项大于比较项,则无需再向排好序的方向继续比较,因为前面的都是排好序的
                    {
                        break;
                    }
                }
            }
            tiOb.StopTime();
            return new string[] { tiOb.Result().TotalMilliseconds.ToString(), SortUtil<T>.intArrToString(array) };
        } 


    }
 class SortUtil<T> 
    {
        public static void swap(T[] array, int i, int min)
        {
            T temp = array[i];
            array[i] = array[min];
            array[min] = temp;
        }

        void swap7(int x, int y)
        {
            if (x == y)
                return;
            y = x + y - (x = y);
        }

        public static string intArrToString(T[] array)
        {
           return string.Join(",", Array.ConvertAll<T, string>(array, s => s.ToString()));
        }
    }

1个回答

caozhy
caozhy   Ds   Rxr 2016.09.19 23:06

10个数字的排序,结果是0,很正常,因为取得的时间精度没有那么高,10个数字的排序是纳秒级别的,测量不出来。

lichjx
lichjx 是可以测出的,平均65ms
大约一年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片