1 static void Main(string[] args) 2 { 3 //数组是引用类型,除了数组元素,还包含一个类型对象指针,一个同步索引块,和一些开销字段 4 //创建一个值类型数组,会在托管堆上分配容纳100个未装箱值类型所需的内存块。 5 //引用类型只创建了一组引用,没有实际对象 6 #region 数组隐试实现IList,ICollection,IEnumerable 7 //FileStream[] fsArray;//CLR会自动使数组实现IList<T>,ICollection<T>,IEnumerable<T>接口 8 ////值类型因为内存布局不同,不会实现上面的接口 9 //fsArray = new FileStream[3]; 10 //M1(fsArray); 11 //M2(fsArray); 12 //M3(fsArray); 13 #endregion 14 15 // DynamicArrays(); 16 17 ArrayTypes(); 18 19 20 21 } 22 23 static void M1(IList<FileStream> f1) 24 { 25 26 } 27 28 static void M2(ICollection<Stream> f2) 29 { 30 31 } 32 33 static void M3(IEnumerable<object> f3) 34 { 35 36 } 37 38 #region 创建下限非0数组 39 40 static void DynamicArrays() 41 { 42 Int32[] lowerBounds = { 2005, 1 }; 43 Int32[] lengths = { 5, 4 }; 44 Decimal[,] quarterlyRevenue = (Decimal[,])Array.CreateInstance(typeof(Decimal), lengths, lowerBounds); 45 quarterlyRevenue[2005, 1] = 10; 46 } 47 #endregion 48 49 #region 数组访问性能 50 51 static void ArrayTypes() 52 { 53 Array a; 54 55 // Create a 1-dim, 0-based array, with no elements in it 56 a = new String[0]; 57 Console.WriteLine(a.GetType()); // System.String[] 58 59 // Create a 1-dim, 0-based array, with no elements in it 60 a = Array.CreateInstance(typeof(String), new Int32[] { 0 }, new Int32[] { 0 }); 61 Console.WriteLine(a.GetType()); // System.String[] 62 63 // Create a 1-dim, 1-based array, with no elements in it 64 a = Array.CreateInstance(typeof(String), new Int32[] { 0 }, new Int32[] { 1 }); 65 Console.WriteLine(a.GetType()); // System.String[*] <-- INTERESTING!下限非0数组 66 67 Console.WriteLine(); 68 69 //将所有多维数组都视为下限非0数组 70 71 // Create a 2-dim, 0-based array, with no elements in it 72 a = new String[0, 0]; 73 Console.WriteLine(a.GetType()); // System.String[,] 74 75 // Create a 2-dim, 0-based array, with no elements in it 76 a = Array.CreateInstance(typeof(String), new Int32[] { 0, 0 }, new Int32[] { 0, 0 }); 77 Console.WriteLine(a.GetType()); // System.String[,] 78 79 // Create a 2-dim, 1-based array, with no elements in it 80 a = Array.CreateInstance(typeof(String), new Int32[] { 0, 0 }, new Int32[] { 1, 1 }); 81 Console.WriteLine(a.GetType()); // System.String[,] 82 } 83 84 private const Int32 c_numElements = 10000; 85 public static void MultiDimArrayPerformance() 86 { 87 88 const Int32 testCount = 10; 89 Stopwatch sw; 90 91 // Declare a 2-dimensional array 92 Int32[,] a2Dim = new Int32[c_numElements, c_numElements]; 93 94 // Declare a 2-dimensional array as a jagged array (a vector of vectors) 95 Int32[][] aJagged = new Int32[c_numElements][]; 96 for (Int32 x = 0; x < c_numElements; x++) 97 aJagged[x] = new Int32[c_numElements]; 98 99 100 // 1: Access all elements of the array using the usual, safe technique 101 sw = Stopwatch.StartNew(); 102 for (Int32 test = 0; test < testCount; test++) 103 Safe2DimArrayAccess(a2Dim); 104 Console.WriteLine("{0}: Safe2DimArrayAccess", sw.Elapsed); 105 106 // 2: Access all elements of the array using the jagged array technique 107 sw = Stopwatch.StartNew(); 108 for (Int32 test = 0; test < testCount; test++) 109 SafeJaggedArrayAccess(aJagged); 110 Console.WriteLine("{0}: SafeJaggedArrayAccess", sw.Elapsed); 111 112 // 3: Access all elements of the array using the unsafe technique 113 sw = Stopwatch.StartNew(); 114 for (Int32 test = 0; test < testCount; test++) 115 Unsafe2DimArrayAccess(a2Dim); 116 Console.WriteLine("{0}: Unsafe2DimArrayAccess", sw.Elapsed); 117 Console.ReadLine(); 118 } 119 120 //普通访问,数组创建是比交错数组快,但访问效率最低 121 private static Int32 Safe2DimArrayAccess(Int32[,] a) 122 { 123 Int32 sum = 0; 124 for (Int32 x = 0; x < c_numElements; x++) 125 { 126 for (Int32 y = 0; y < c_numElements; y++) 127 { 128 sum += a[x, y]; 129 } 130 } 131 return sum; 132 } 133 134 //交错访问,效率和不安全访问相近,但创建数组是开销较大 135 private static Int32 SafeJaggedArrayAccess(Int32[][] a) 136 { 137 Int32 sum = 0; 138 for (Int32 x = 0; x < c_numElements; x++) 139 { 140 for (Int32 y = 0; y < c_numElements; y++) 141 { 142 sum += a[x][y]; 143 } 144 } 145 return sum; 146 } 147 148 //使用不安全的指针访问数组,效率最高 149 private static unsafe Int32 Unsafe2DimArrayAccess(Int32[,] a) 150 { 151 Int32 sum = 0; 152 fixed (Int32* pi = a) 153 { 154 for (Int32 x = 0; x < c_numElements; x++) 155 { 156 Int32 baseOfDim = x * c_numElements; 157 for (Int32 y = 0; y < c_numElements; y++) 158 { 159 sum += pi[baseOfDim + y]; 160 } 161 } 162 } 163 return sum; 164 } 165 166 #endregion 167 168 #region 使用stackalloc创建值类型数组 169 170 private static void StackallocDemo() 171 { 172 unsafe 173 { 174 const Int32 width = 20; 175 Char* pc = stackalloc Char[width]; // 在栈上分配数组 176 177 String s = "Jeffrey Richter"; // 15 字符 178 179 for (Int32 index = 0; index < width; index++) 180 { 181 pc[width - index - 1] = 182 (index < s.Length) ? s[index] : '.'; 183 } 184 Console.WriteLine(new String(pc, 0, width)); // ".....rethciR yerffeJ" 185 } 186 } 187 188 private static void InlineArrayDemo() 189 { 190 unsafe 191 { 192 CharArray ca; // 在栈上分配数组 193 Int32 widthInBytes = sizeof(CharArray); 194 Int32 width = widthInBytes / 2; 195 196 String s = "Jeffrey Richter"; // 15 字符 197 198 for (Int32 index = 0; index < width; index++) 199 { 200 ca.Characters[width - index - 1] = 201 (index < s.Length) ? s[index] : '.'; 202 } 203 Console.WriteLine(new String(ca.Characters, 0, width)); // ".....rethciR yerffeJ" 204 } 205 #endregion 206 207 } 208 private unsafe struct CharArray 209 { 210 // 数组内联欠入 211 public fixed Char Characters[20]; 212 }