C#内联语句的性能

Performance of C# Inline Statement

我有一个模型的集合

public class MobileModelInfo
{
    public string Name { get; set; }
    public string Catagory { get; set; }
    public string Year { get; set; }
}

在这里,我通过 内联单一执行语句

MobileModelInfo 分配给 ObservableCollection

方法 #1

ObservableCollection<MobileModelInfo> mobList = new ObservableCollection<MobileModelInfo>((new List<MobileModelInfo>(){
    new MobileModelInfo { Name = "S4", Catagory = "Smart Phone", Year = "2011" },
    new MobileModelInfo { Name = "S5", Catagory = "Smart Phone", Year = "2013" },
    new MobileModelInfo { Name = "S6", Catagory = "Ultra Smart Phone", Year = "2015" },
    new MobileModelInfo { Name = "", Catagory = "Ultra Smart Phone", Year = "2016" }
}).Where(i => !string.IsNullOrEmpty(i.Name)).ToList());

现在考虑comman的实现方式

方法 #2

ObservableCollection<MobileModelInfo> mobList = new ObservableCollection<MobileModelInfo>();
MobileModelInfo mobObject = new MobileModelInfo();

mobObject.Name = "S4";
mobObject.Catagory = "Smart Phone";
mobObject.Year = "2011";
if(!string.IsNullOrEmpty(mobObject.Name))
    mobList.Add(mobObject);

mobObject = new MobileModelInfo();
mobObject.Name = "S5";
mobObject.Catagory = "Smart Phone";
mobObject.Year = "2013";
if(!string.IsNullOrEmpty(mobObject.Name))
    mobList.Add(mobObject);

mobObject = new MobileModelInfo();
mobObject.Name = "S6";
mobObject.Catagory = "Ultra Smart Phone";
mobObject.Year = "2015";
if(!string.IsNullOrEmpty(mobObject.Name))
    mobList.Add(mobObject);

mobObject = new MobileModelInfo();
mobObject.Name = "";
mobObject.Catagory = "Ultra Smart Phone";
mobObject.Year = "2016";
if(!string.IsNullOrEmpty(mobObject.Name))
    mobList.Add(mobObject);

这两种方法中哪一种性能好? 在我的主要项目中,我有一个非常复杂的模型 Class 集合。所以,请帮我选择一个最好的方法...

In the First Approach only one Execution should Perform since it will be expanded by the compiler but in Second Approach more than 25 (>25) Execution should Perform. So, I need to clarify which one is best approach in the Complex Data-structure.

第二个不是"the Comman Way"(这是我以前从未听说过的术语)。它是:

  • 令人费解(设置后检查名称 属性 是否为 null。
  • 在某个古老的 .NET 更新启用新语法之前执行此操作的唯一方法。

这几乎就是您学习它的原因。旧语法。没有显着的 - 特别是没有可衡量的 - 性能差异。

新语法对象初始值设定项基本上只是翻译成长格式的 shorthand 格式。如果愿意,您可以使用某种反汇编程序来确认这一点。您会发现代码几乎完全相同,除了一些编译器优化。

例如,这段代码:

TestClass t1 = new TestClass { iVal = 1, sVal = "two" };

生成以下 IL(根据 LINQPad):

IL_0001:  newobj      UserQuery+TestClass..ctor
IL_0006:  stloc.2     
IL_0007:  ldloc.2     
IL_0008:  ldc.i4.1    
IL_0009:  stfld       UserQuery+TestClass.iVal
IL_000E:  ldloc.2     
IL_000F:  ldstr       "two"
IL_0014:  stfld       UserQuery+TestClass.sVal
IL_0019:  ldloc.2     
IL_001A:  stloc.0     // t1

这是另一种方式:

TestClass t2 = new TestClass();
t2.iVal = 1;
t2.sVal = "two";

及其IL:

IL_001B:  newobj      UserQuery+TestClass..ctor
IL_0020:  stloc.1     // t2
IL_0021:  ldloc.1     // t2
IL_0022:  ldc.i4.1    
IL_0023:  stfld       UserQuery+TestClass.iVal
IL_0028:  ldloc.1     // t2
IL_0029:  ldstr       "two"
IL_002E:  stfld       UserQuery+TestClass.sVal

这里唯一的区别是先创建一个临时变量(loc.2)来创建,然后将其存储在命名的局部变量(loc.0)中。当您打开优化时,这种差异就会消失。

因此您可以使用任何一种方法,性能差异几乎为 0。我个人更喜欢新的对象初始化形式,就像我更喜欢 LINQ 查询语法一样。两者都只是后台发生的事情的语法糖,但它们在您阅读代码和编写代码的方式上可能会有很大差异。

顺便说一句,数组初始值设定项完全相同。这两个产生几乎相同的代码:

int[] a1 = new int[] { 1, 2, 3 };

int[] a2 = new int[3];
a2[0] = 1;
a2[1] = 2;
a2[2] = 3;