我最近对List<>
vs []
进行了一些粗略的性能测量,以获得一系列小型结构。 System.Array似乎赢了手,所以我顺其自然。
只是我突然意识到System.Array包含对象类型,所以肯定用结构填充它会导致拳击发生?
然而,the MSDN entry for System.Array声明:
在.NET Framework 2.0版中,Array类实现了
System.Collections.Generic.IList<T>
,System.Collections.Generic.ICollection<T>
,和System.Collections.Generic.IEnumerable<T>
通用接口。该 实现在运行时提供给数组,因此是 文档构建工具不可见。结果,通用 接口不会出现在Array的声明语法中 类,并没有接口成员的参考主题 只能通过将数组转换为通用接口类型来访问 (显式接口实现)。
这是否意味着毕竟不会发生拳击? (并会解释我的表现结果)
答案 0 :(得分:12)
如果使用索引器表示法,则不使用数组。 e.g。
new int[2];
x=[1]=3;
编译为以下IL(请注意,行号与其他一些代码片段无关)
IL_0011: ldc.i4.2
IL_0012: newarr System.Int32
IL_0017: stfld Int32[] x
IL_001c: ldarg.0
IL_001d: ldfld Int32[] x
IL_0022: ldc.i4.1
IL_0023: ldc.i4.3
IL_0024: stelem.i4
对于不能使用索引器的语言(我真的不知道它们是否存在)2在编译时为数组创建了其他方法。
它创建了这些公共方法::
public int Get(int index)
public void Set(int index,int value)
这些方法既不会封装,也不能通过C#访问。 (不要问我为什么他们是公共方法)。您可以使用IL或通过创建委托来执行它们。当你被迫做一个callvirt来调用这些方法时,它们会变慢。
stelem。*和ldelem。*系列用于处理存储到强类型数组类型。使用泛型时,通常使用constrained
时会将以下前缀附加readonly
或T[]
。 stelem.*
类型通常不检查类型。例如。使用stelem.i4
比使用stelem.any Int32
要快,除非您在前面添加readonly
,否则会强制进行类型检查。
现在,对于值类型数组,类型检查是完全没用的,它们是不协变的!
因为运行时生成从零开始的一维数组(称为SZ_array或矢量类型)类型,所以它们本身是已知的。
有一系列il op代码:newarr
,stelem.*
,ldelem.*
,ldlen
等。
List<T>
类型在BCL的Microsoft实现中使用T[]
作为其后备存储。 List<T>
没有框。无论使用列表还是数组,都要将数据存储在数组中。