国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

編寫高質量代碼改善C#程序的157個建議——建議16:元素數量可變的情況下不應使用數組

2019-11-14 14:06:46
字體:
來源:轉載
供稿:網友

建議16:元素數量可變的情況下不應使用數組

在C#中,數組一旦被創建,長度就不能改變。如果我們需要一個動態且可變長度的集合,就應該使用ArrayList或List<T>來創建。 而數組本身,尤其是一維數組,在遇到要求高效率的算法時,則會專門被優化以提升其效率。一維數組也成為向量,其性能是最佳的,在IL中使用了專門的指令來 處理它們(如newarr、ldelem、ldelema、ldelen和stelem)。

 

從內存的使用角度來講,數組在創建時被分配了一段固定長度的內存。如果數組的元素是值類型,則每個元素的長度等于相應的值類型的長度;如果數組的元素是引用類型,則每個元素的長度為該引用類型的IntPtr.Size(IntPtr:It's a class that wraps a pointer that is used when calling Windows API functions. The underlying pointer may be 32 bit or 64 bit, depending on the platform.)。數組的存儲結構一旦被分配,就不能再變化。而ArrayList是鏈表結構,可以動態的增減內存空間,如果ArrayList存儲的是值類型,則會為每個元素增加12字節的空間,其中4個字節擁有對象引用,8字節是元素裝箱時引入的對象頭。List<T>是ArrayList的泛型實現,它省去了裝箱和拆箱帶來的開銷。

注意:

由于數組本身在內存上的特點,因此在使用數組的過程中還應該注意大對象的問題。所謂“大對象”,是指那些占內存超過85000字節的對象,它們被分配在大對象堆里。大對象的分配和回收和小對象都不太一樣,尤其是回收,大對象在回收過程中會帶來效率很低的問題。所以,不能對數組指定過大的長度,這會讓數組成為一個大對象。

 

如果一定要動態改變數組的長度,一種方法是將數組轉換為ArrayList或List<T>,如下面代碼說是:

            int[] iArr = { 0, 1, 2, 3, 4, 5, 6 };            ArrayList arrayListInt = new ArrayList(iArr);   //將數組轉變為ArrayList            arrayListInt.Add(7);            List<int> listInt = iArr.ToList<int>();             //將數組轉變為List<T>            listInt.Add(7);

還有一種方法是數組的復制功能。數組繼承自System.Array,抽象類System.Array提供了一些有用的實現方法。其中就包括Copy方法,它負責將一個數組的內容復制到另外一個數組中。無論哪種方法,改變數組長度就相當于重新創建了一個數組對象。

 

為了讓數組看上去本身就具有動態改變長度的功能,可以創建一個名為Resize的擴展方法,代碼如下所示:

    public static class ClassForExtensions    {        public static Array ReSize(this Array array, int newSize)        {            Type t = array.GetType().GetElementType();            Array newArray = Array.CreateInstance(t, newSize);            Array.Copy(array, 0, newArray, 0, Math.Min(array.Length, newSize));            return newArray;        }    }

調用方法看起來如下:

int[] iArr = { 0, 1, 2, 3, 4, 5, 6 };iArr = (int[])iArr.ReSize(10);

下面對改變數組長度和改變Lisit<T>長度的耗時做一個比較,以便強調本建議的主題:在元素數量可變的情況下不應該使用數組。

        PRivate static void ResizeArray()        {            int[] iArr = { 0, 1, 2, 3, 4, 5, 6 };            Stopwatch watch = new Stopwatch();            watch.Start();            iArr = (int[])iArr.ReSize(10);            watch.Stop();            Console.WriteLine("ResizeArray: " + watch.Elapsed);        }        private static void ResizeList()        {            List<int> iArr = new List<int>(new int[] { 0, 1, 2, 3, 4, 5, 6 });            Stopwatch watch = new Stopwatch();            watch.Start();            iArr.Add(0);            iArr.Add(0);            iArr.Add(0);            watch.Stop();            Console.WriteLine("ResizeList: " + watch.Elapsed);        }

輸出為:

ResizeArray:00:00:00.0004441

ResizeList:00:00:0:0000036

當然,嚴格意義上講,List<T>不存在改變長度的說法,本建議只是為了比較,將iArr的長度變為10,同時還進行了賦值。即便這樣,我們可以看到,在時間效率上ResizeList比ResizeArray要高100倍以上。

 

 

轉自:《編寫高質量代碼改善C#程序的157個建議》陸敏技


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 榆社县| 饶河县| 云南省| 彩票| 米易县| 安乡县| 建昌县| 东兴市| 吐鲁番市| 黄陵县| 攀枝花市| 北宁市| 武宣县| 常德市| 中山市| 杭州市| 宝鸡市| 嵊州市| 彭州市| 云梦县| 隆德县| 常宁市| 红桥区| 临邑县| 海丰县| 汶川县| 定兴县| 旅游| 绍兴县| 喀喇沁旗| 福建省| 巴彦淖尔市| 中方县| 永宁县| 元谋县| 堆龙德庆县| 黎城县| 富宁县| 青铜峡市| 华池县| 灵宝市|