C#研究系列-List<>与ArrayList的几个研究心得及问题(上)
2011-04-15 23:55
736 查看
代码放在https://gist.github.com/921076 上了,看不到的请留言。
第一个心得,是我看某本书提到,IList用起来要比ArrayList快。
这里面用到了我上一篇博客提到的高精度计时器(在这里能看到代码 http://sunxiunan.com/?p=1829 )
在开始定义了两个类。
//---------------------
// public class List : IList, ICollection, IEnumerable, IList, ICollection, IEnumerable
class CFromList : List
{}
// public class ArrayList : IList, ICollection, IEnumerable, ICloneable
class CFromArrayList : ArrayList
{}
//---------------------
List和ArrayList的定义在注释中给出,可以看出来其实都差不多。ArrayList只是多了ICloneable,还少了几个泛型接口继承。
在后面代码中都用Add方法向list中添加int类型数据,然后通过foreach形式枚举数据,注意!枚举部分的代码是有问题的,我们在(下)中会提到。
这里还要推荐一个非常棒的工具ILSpy,是sharpdevelop开发的,强烈建议dotnet程序员都下载使用。
我把ILSpy
disassemble出来的C#代码和IL代码分别列在后面。注意对于ArrayList的foreach语句,C#形式的代码与源代码有些差别(79
到96行),编译器加入一个IEnumerator enumerator2 =
cFromArrayList.GetEnumerator();本地变量。
另外使用int num5 =
(int)enumerator2.Current;这样访问iterator。而且还加入了IDisposable的finally部分。
再继续看IL代码部分,对于List形式,IL代码没有box装箱指令,而ArrayList在145行有个box指令,这是性能差别之一。
但是奇怪的是,在枚举部分,ILSpy生成的(以及ILDasm)IL代码,对于ArrayList和List而言,基本上差别不大,一样也有对
MoveNext和Current以及IDisposable接口的调用。
只不过ArrayList多出unbox和box的指令。
运行结果如我们所料,List要比ArrayList快不少。
但是我们在枚举部分的代码是有问题的,我明天在(下)中会介绍。
第一个心得,是我看某本书提到,IList用起来要比ArrayList快。
这里面用到了我上一篇博客提到的高精度计时器(在这里能看到代码 http://sunxiunan.com/?p=1829 )
在开始定义了两个类。
//---------------------
// public class List : IList, ICollection, IEnumerable, IList, ICollection, IEnumerable
class CFromList : List
{}
// public class ArrayList : IList, ICollection, IEnumerable, ICloneable
class CFromArrayList : ArrayList
{}
//---------------------
List和ArrayList的定义在注释中给出,可以看出来其实都差不多。ArrayList只是多了ICloneable,还少了几个泛型接口继承。
在后面代码中都用Add方法向list中添加int类型数据,然后通过foreach形式枚举数据,注意!枚举部分的代码是有问题的,我们在(下)中会提到。
这里还要推荐一个非常棒的工具ILSpy,是sharpdevelop开发的,强烈建议dotnet程序员都下载使用。
我把ILSpy
disassemble出来的C#代码和IL代码分别列在后面。注意对于ArrayList的foreach语句,C#形式的代码与源代码有些差别(79
到96行),编译器加入一个IEnumerator enumerator2 =
cFromArrayList.GetEnumerator();本地变量。
另外使用int num5 =
(int)enumerator2.Current;这样访问iterator。而且还加入了IDisposable的finally部分。
再继续看IL代码部分,对于List形式,IL代码没有box装箱指令,而ArrayList在145行有个box指令,这是性能差别之一。
但是奇怪的是,在枚举部分,ILSpy生成的(以及ILDasm)IL代码,对于ArrayList和List而言,基本上差别不大,一样也有对
MoveNext和Current以及IDisposable接口的调用。
只不过ArrayList多出unbox和box的指令。
运行结果如我们所料,List要比ArrayList快不少。
但是我们在枚举部分的代码是有问题的,我明天在(下)中会介绍。
// public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection, IEnumerable class CFromList : List<int>{} // public class ArrayList : IList, ICollection, IEnumerable, ICloneable class CFromArrayList : ArrayList{} public partial class Form1 : Form { private void button1_Click(object sender, EventArgs e) { CFromList list1 = new CFromList(); CFromArrayList list2 = new CFromArrayList(); //////////////////////////// HighResolutionTimer timera = new HighResolutionTimer(); for (int i = 0; i < 100000; i++) { list1.Add(i - 99999); } Int64 reta = timera.Stop(); //////////////////////////// HighResolutionTimer timerb = new HighResolutionTimer(); for (int i = 0; i < 100000; i++) { list2.Add(i - 99999); } Int64 retb = timerb.Stop(); //////////////////////////// int index = 0; HighResolutionTimer timer1 = new HighResolutionTimer(); foreach (int elem1 in list1) { list1[index++] = elem1 + 99; } Int64 ret1 = timer1.Stop(); //////////////////////////// index = 0; HighResolutionTimer timer2 = new HighResolutionTimer(); foreach (int elem2 in list2) { list2[index++] = elem2 + 99; } Int64 ret2 = timer2.Stop(); //////////////////////////// } }///////////////////////////////////////////////////////// result from ILSpy CFromList cFromList = new CFromList(); CFromArrayList cFromArrayList = new CFromArrayList(); HighResolutionTimer highResolutionTimer = new HighResolutionTimer(); for (int i = 0; i < 100000; i++) { cFromList.Add(i - 99999); } long num = highResolutionTimer.Stop(); HighResolutionTimer highResolutionTimer2 = new HighResolutionTimer(); for (int i = 0; i < 100000; i++) { cFromArrayList.Add(i - 99999); } long num2 = highResolutionTimer2.Stop(); int num3 = 0; HighResolutionTimer highResolutionTimer3 = new HighResolutionTimer(); foreach (int current in cFromList) { cFromList[num3++] = current + 99; } long num4 = highResolutionTimer3.Stop(); num3 = 0; HighResolutionTimer highResolutionTimer4 = new HighResolutionTimer(); IEnumerator enumerator2 = cFromArrayList.GetEnumerator(); try { while (enumerator2.MoveNext()) { int num5 = (int)enumerator2.Current; cFromArrayList[num3++] = num5 + 99; } } finally { IDisposable disposable = enumerator2 as IDisposable; if (disposable != null) { disposable.Dispose(); } } long num6 = highResolutionTimer4.Stop(); //////////////////////////////////////////////////// result from ILSpy IL format IL_0000: nop IL_0001: newobj instance void WindowsFormsApplication1.CFromList::.ctor() IL_0006: stloc.0 IL_0007: newobj instance void WindowsFormsApplication1.CFromArrayList::.ctor() IL_000c: stloc.1 IL_000d: newobj instance void WindowsFormsApplication1.HighResolutionTimer::.ctor() IL_0012: stloc.2 IL_0013: ldc.i4.0 IL_0014: stloc.3 IL_0015: br.s IL_002b // loop start (head: IL_002b) IL_0017: nop IL_0018: ldloc.0 IL_0019: ldloc.3 IL_001a: ldc.i4 99999 IL_001f: sub IL_0020: callvirt instance void [mscorlib]System.Collections.Generic.List`1<int32>::Add(!0) IL_0025: nop IL_0026: nop IL_0027: ldloc.3 IL_0028: ldc.i4.1 IL_0029: add IL_002a: stloc.3 IL_002b: ldloc.3 IL_002c: ldc.i4 100000 IL_0031: clt IL_0033: stloc.s 17 IL_0035: ldloc.s 17 IL_0037: brtrue.s IL_0017 // end loop IL_0039: ldloc.2 IL_003a: callvirt instance int64 WindowsFormsApplication1.HighResolutionTimer::Stop() IL_003f: stloc.s 4 IL_0041: newobj instance void WindowsFormsApplication1.HighResolutionTimer::.ctor() IL_0046: stloc.s 5 IL_0048: ldc.i4.0 IL_0049: stloc.3 IL_004a: br.s IL_0065 // loop start (head: IL_0065) IL_004c: nop IL_004d: ldloc.1 IL_004e: ldloc.3 IL_004f: ldc.i4 99999 IL_0054: sub IL_0055: box int32 IL_005a: callvirt instance int32 [mscorlib]System.Collections.ArrayList::Add(object) IL_005f: pop IL_0060: nop IL_0061: ldloc.3 IL_0062: ldc.i4.1 IL_0063: add IL_0064: stloc.3 IL_0065: ldloc.3 IL_0066: ldc.i4 100000 IL_006b: clt IL_006d: stloc.s 17 IL_006f: ldloc.s 17 IL_0071: brtrue.s IL_004c // end loop IL_0073: ldloc.s 5 IL_0075: callvirt instance int64 WindowsFormsApplication1.HighResolutionTimer::Stop() IL_007a: stloc.s 6 IL_007c: ldc.i4.0 IL_007d: stloc.s 7 IL_007f: newobj instance void WindowsFormsApplication1.HighResolutionTimer::.ctor() IL_0084: stloc.s 8 IL_0086: nop IL_0087: ldloc.0 IL_0088: callvirt instance valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<!0> [mscorlib]System.Collections.Generic.List`1<int32>::GetEnumerator() IL_008d: stloc.s 18 .try { IL_008f: br.s IL_00af // loop start (head: IL_00af) IL_0091: ldloca.s 18 IL_0093: call instance !0 [mscorlib]System.Collections.Generic.List`1/Enumerator<int32>::get_Current() IL_0098: stloc.s 9 IL_009a: nop IL_009b: ldloc.0 IL_009c: ldloc.s 7 IL_009e: dup IL_009f: ldc.i4.1 IL_00a0: add IL_00a1: stloc.s 7 IL_00a3: ldloc.s 9 IL_00a5: ldc.i4.s 99 IL_00a7: add IL_00a8: callvirt instance void [mscorlib]System.Collections.Generic.List`1<int32>::set_Item(int32, !0) IL_00ad: nop IL_00ae: nop IL_00af: ldloca.s 18 IL_00b1: call instance bool [mscorlib]System.Collections.Generic.List`1/Enumerator<int32>::MoveNext() IL_00b6: stloc.s 17 IL_00b8: ldloc.s 17 IL_00ba: brtrue.s IL_0091 // end loop IL_00bc: leave.s IL_00cd } // end .try finally { IL_00be: ldloca.s 18 IL_00c0: constrained. valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<int32> IL_00c6: callvirt instance void [mscorlib]System.IDisposable::Dispose() IL_00cb: nop IL_00cc: endfinally } // end handler IL_00cd: nop IL_00ce: ldloc.s 8 IL_00d0: callvirt instance int64 WindowsFormsApplication1.HighResolutionTimer::Stop() IL_00d5: stloc.s 10 IL_00d7: ldc.i4.0 IL_00d8: stloc.s 7 IL_00da: newobj instance void WindowsFormsApplication1.HighResolutionTimer::.ctor() IL_00df: stloc.s 11 IL_00e1: nop IL_00e2: ldloc.1 IL_00e3: callvirt instance class [mscorlib]System.Collections.IEnumerator [mscorlib]System.Collections.ArrayList::GetEnumerator() IL_00e8: stloc.s 19 .try { IL_00ea: br.s IL_0114 // loop start (head: IL_0114) IL_00ec: ldloc.s 19 IL_00ee: callvirt instance object [mscorlib]System.Collections.IEnumerator::get_Current() IL_00f3: unbox.any int32 IL_00f8: stloc.s 12 IL_00fa: nop IL_00fb: ldloc.1 IL_00fc: ldloc.s 7 IL_00fe: dup IL_00ff: ldc.i4.1 IL_0100: add IL_0101: stloc.s 7 IL_0103: ldloc.s 12 IL_0105: ldc.i4.s 99 IL_0107: add IL_0108: box int32 IL_010d: callvirt instance void [mscorlib]System.Collections.ArrayList::set_Item(int32, object) IL_0112: nop IL_0113: nop IL_0114: ldloc.s 19 IL_0116: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() IL_011b: stloc.s 17 IL_011d: ldloc.s 17 IL_011f: brtrue.s IL_00ec // end loop IL_0121: leave.s IL_0140 } // end .try finally { IL_0123: ldloc.s 19 IL_0125: isinst class [mscorlib]System.IDisposable IL_012a: stloc.s 20 IL_012c: ldloc.s 20 IL_012e: ldnull IL_012f: ceq IL_0131: stloc.s 17 IL_0133: ldloc.s 17 IL_0135: brtrue.s IL_013f IL_0137: ldloc.s 20 IL_0139: callvirt instance void [mscorlib]System.IDisposable::Dispose() IL_013e: nop IL_013f: endfinally } // end handler IL_0140: nop IL_0141: ldloc.s 11 IL_0143: callvirt instance int64 WindowsFormsApplication1.HighResolutionTimer::Stop() IL_0148: stloc.s 13
相关文章推荐
- .Net学习 第2季05 C#面向对象 ArrayList Hashtable List<> Dictionary<>
- C# IEnumerable<T>、IEnumerator<T>、List<T>、ArrayList、[]数组各各的区别
- C#中使用List<struct>的问题
- C#中的[],Array,List<>,ArrayList的区别
- .net集合类的研究--Array,ArrayList,List<T>
- C# List<T> Add方法循环添加时只保存了最后一次的数据(覆盖问题)
- C# 中的集合(Array/ArrayList/List<T>/HashTable/Dictionary)
- C# List<string>和ArrayList用指定的分隔符分隔成字符串
- C# 中的集合(Array/ArrayList/List<T>/HashTable/Dictionary)
- C# 数组、ArrayList和List<T>的区别
- [C#]泛型与非泛型集合类的区别及使用例程,包括ArrayList,Hashtable,List<T>,Dictionary<Tkey,Tvalue>,SortedList<Tkey,Tvalue>,Queue<T>,Stack<T>等
- C#中 ArrayList与string,string[],List<string> 数组集合转换
- C# 中的集合(Array/ArrayList/List<T>/HashTable/Dictionary)
- C#学习笔记--ArrayList?List<T>?Dictionary
- C#中List<T>对象的深度拷贝问题
- C# Winform DataGrid 绑定List<> Or ObservableCollection<> 类型无法自动刷新问题
- C#ArrayList 集合 和list<t>泛型集合
- .net集合类的研究--Array,ArrayList,List<T>
- C#中List<T>对象的深度拷贝问题
- c#初学-泛型ArrayList的使用和List<T>的比较