国产探花免费观看_亚洲丰满少妇自慰呻吟_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個建議》陸敏技


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 綦江县| 漠河县| 炉霍县| 连江县| 汶川县| 花垣县| 清徐县| 新乡市| 修文县| 星座| 壶关县| 泽州县| 丹棱县| 濮阳县| 句容市| 棋牌| 噶尔县| 比如县| 天全县| 金湖县| 镇安县| 高阳县| 漯河市| 宁明县| 西和县| 尚义县| 绥芬河市| 三亚市| 吉隆县| 双峰县| 隆回县| 博兴县| 固镇县| 西乌| 安康市| 东城区| 屏南县| 若羌县| 察哈| 巴塘县| 勐海县|