ast*_*tef 8 .net c# dictionary compiler-optimization
编译器会优化此代码还是在每次调用方法后初始化集合?
private string Parse(string s)
{
var dict = new Dictionary<string, string>
{
{"a", "x"},
{"b", "y"}
};
return dict[s];
}
Run Code Online (Sandbox Code Playgroud)
如果答案是否定的,我建议使用此解决方案:在C#中创建常量字典
Yuv*_*kov 13
当出现这样的问题并且你不确定答案是什么时,看看"引擎盖下"总是好的.
这是打开优化器时生成的IL编译器:
Parse:
IL_0000: newobj System.Collections.Generic.Dictionary<System.String,System.String>..ctor
IL_0005: stloc.1 // <>g__initLocal0
IL_0006: ldloc.1 // <>g__initLocal0
IL_0007: ldstr "a"
IL_000C: ldstr "x"
IL_0011: callvirt System.Collections.Generic.Dictionary<System.String,System.String>.Add
IL_0016: ldloc.1 // <>g__initLocal0
IL_0017: ldstr "b"
IL_001C: ldstr "y"
IL_0021: callvirt System.Collections.Generic.Dictionary<System.String,System.String>.Add
IL_0026: ldloc.1 // <>g__initLocal0
IL_0027: stloc.0 // dict
IL_0028: ldloc.0 // dict
IL_0029: ldarg.1
IL_002A: callvirt System.Collections.Generic.Dictionary<System.String,System.String>.get_Item
IL_002F: ret
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,它调用每次newobj
分配,Dictionary<K,V>
每次都加载本地和调用Dictionary.Add
(这是与调用相当的语法糖Add
).它对类型没有熟悉的知识,以便缓存对象的创建.
不,它不会.它没有内在的知识Dictionary
.对于编译器,它只是一个普通的类,因此它不知道在这种特殊情况下它可以重用该实例.
这将是执行此操作的正确方法:
public class Something
{
private static readonly Dictionary<string, string> _dict = new Dictionary<string, string>
{
{"a", "x"},
{"b", "y"}
}
private string Parse(string s)
{
return _dict[s];
}
}
Run Code Online (Sandbox Code Playgroud)
这种方法有效,因为您知道对象的作用,并且您也知道它永远不会被修改.
请记住以下语法:
var dict = new Dictionary<string, string>
{
{"a", "x"},
{"b", "y"}
}
Run Code Online (Sandbox Code Playgroud)
这只是语法糖:
var dict = new Dictionary<string, string>();
dict.Add("a", "x");
dict.Add("b", "y");
Run Code Online (Sandbox Code Playgroud)
使这个适用于任何类的唯一要求是该类
IEnumerable
Add
方法.您建议使用switch
语句,但Dictionary
方法可以更灵活.例如,考虑您可能想要使用不同的相等比较器(如StringComparer.OrdinalIgnoreCase
).Dictionary
使用适当的比较器来处理这个比使用类似的东西更好switch(value.ToLowerInvariant())
.
归档时间: |
|
查看次数: |
798 次 |
最近记录: |