Ale*_*sky 25 .net c# performance
我只是想着造型和性能.以前我曾经写过类似的东西,
var strings = new List<string> { "a", "b", "c" };
var ints = new List<int> { 1, 2, 3};
Run Code Online (Sandbox Code Playgroud)
但现在我更倾向于喜欢这种风格,
var strings = new [] { "a", "b", "c" }.ToList();
var ints = new [] { 1, 2, 3}.ToList();
Run Code Online (Sandbox Code Playgroud)
我更喜欢第二种风格,但现在正在考虑 - 是否真的值得这样写它或者它不是那么有效并且需要更多操作?
Jon*_*eet 42
我不同意达林:他们在表现上并不相同.后一版本必须创建一个新数组,然后ToList将其复制到新列表中.集合初始化程序版本相当于:
var tmp = new List<int>();
tmp.Add(1);
tmp.Add(2);
tmp.Add(3);
var ints = tmp;
Run Code Online (Sandbox Code Playgroud)
虽然它-假设列表,并附有足够大的缓冲,这将不需要任何进一步的分配开始了将涉及几个方法调用.如果对大量项目执行此操作,则需要比版本更多的分配ToList,因为它将按原样复制项目.
性能差异是可能是微不足道的,但它是非零的(而不是明确地在两个方向上更好的-有在阵列版本呼叫减少,但更多的分配).
我会更专注于风格而不是表现,除非你有理由怀疑差异是显着的,在这种情况下你应该衡量而不仅仅是猜测.
就个人而言,我更喜欢第一种形式 - 我认为从一开始就使用列表就更清楚了.另一种方法是编写自己的静态类:
public static class Lists
{
public static List<T> Of<T>(T item0)
{
return new List<T> { item0 };
}
public static List<T> Of<T>(T item0, T item1)
{
return new List<T> { item0, item1 };
}
public static List<T> Of<T>(T item0, T item1, T item2)
{
return new List<T> { item0, item1, item2 };
}
... as many times as you really care about, then ...
public static List<T> Of<T>(params T[] items)
{
return items.ToList();
}
}
Run Code Online (Sandbox Code Playgroud)
然后你可以写:
var ints = Lists.Of(1);
var ints = Lists.Of(1, 2, 3);
var ints = Lists.Of(1, 2, 3, 5, 6, 7, 8); // Use the params version
Run Code Online (Sandbox Code Playgroud)
这仍然清楚表明您正在使用列表,但利用类型推断.
你可能会认为它有点过分但:)
Jam*_*man 13
从绩效的角度来看两者之间的差异,前者表达了你想要以更好的方式实现的目标.
考虑用英语表达代码:
声明包含这些内容的字符串列表
和
声明具有这些内容的字符串数组,然后将其转换为字符串列表
对我来说,第一个似乎更自然.虽然我承认第二个可能对你更好.
示例1(var ints = new List {1,2,3};):提供31.5%的开销(Eumerable.ToList),List.Add()导致8.7%的开销.
例如2:在List.ctor上产生11.8%的开销,在Ensure Capacity上产生5%的开销.
(Red Gate ANTS Performance Profiler的结果)
你可以看到var ints = new List {1,2,3}; 通过反汇编执行更多操作
var intsx = new[] {1, 2, 3}.ToList();
0000003f mov edx,3
00000044 mov ecx,60854186h
00000049 call FFF5FD70
0000004e mov dword ptr [ebp-4Ch],eax
00000051 lea ecx,[ebp-50h]
00000054 mov edx,872618h
00000059 call 61490806
0000005e lea eax,[ebp-50h]
00000061 push dword ptr [eax]
00000063 mov ecx,dword ptr [ebp-4Ch]
00000066 call 614908E3
0000006b mov ecx,dword ptr [ebp-4Ch]
0000006e call dword ptr ds:[008726D8h]
00000074 mov dword ptr [ebp-54h],eax
00000077 mov eax,dword ptr [ebp-54h]
0000007a mov dword ptr [ebp-40h],eax
var ints = new List<int> { 1, 2, 3 };
0000007d mov ecx,60B59894h
00000082 call FFF5FBE0
00000087 mov dword ptr [ebp-58h],eax
0000008a mov ecx,dword ptr [ebp-58h]
0000008d call 60805DB0
00000092 mov eax,dword ptr [ebp-58h]
00000095 mov dword ptr [ebp-48h],eax
00000098 mov ecx,dword ptr [ebp-48h]
0000009b mov edx,1
000000a0 cmp dword ptr [ecx],ecx
000000a2 call 608070C0
000000a7 nop
000000a8 mov ecx,dword ptr [ebp-48h]
000000ab mov edx,2
000000b0 cmp dword ptr [ecx],ecx
000000b2 call 608070C0
000000b7 nop
000000b8 mov ecx,dword ptr [ebp-48h]
000000bb mov edx,3
000000c0 cmp dword ptr [ecx],ecx
000000c2 call 608070C0
000000c7 nop
000000c8 mov eax,dword ptr [ebp-48h]
000000cb mov dword ptr [ebp-44h],eax
}
Run Code Online (Sandbox Code Playgroud)
我想在第一种情况下,元素会自动添加到列表中,而在第二种情况下,首先创建一个数组,然后迭代它,并将每个元素添加到列表中.
虽然可能第二个将被优化以避免真正的阵列创建,但值得注意的是,如果此操作在循环内完成,则可能是对象分配量的两倍(除非它是直接优化的),而没有真正需要这样做.
你应该检查字节码以确定它.
我不喜欢C#内部,所以请小心谨慎!