简体   繁体   English

C#内联语句的性能

[英]Performance of C# Inline Statement

I'm having a Collection of a Model 我正在收集模型

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

Here I'm assigning the MobileModelInfo into a ObservableCollection via Inline Single Execution Statement 在这里,我通过内联单个执行语句MobileModelInfo分配到ObservableCollection

Approach #1 方法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());

Now Consider the Comman Way of Implementation 现在考虑通用的实现方式

Approach #2 方法#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);

Out of these two approach which one gives good performance? 在这两种方法中,哪一种可以提供良好的性能? In my main Project I'm having a very complex Model Class Collection. 在我的主项目中,我有一个非常复杂的模型类集合。 So, kindly assist me to choose a best way... 因此,请协助我选择最佳方式...

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. 在第一种方法中,只应执行一个执行,因为它会被编译器扩展,但在第二种方法中,应执行超过25(> 25)个执行。 So, I need to clarify which one is best approach in the Complex Data-structure. 因此,我需要阐明在复杂数据结构中哪种方法最好。

The second is not "the Comman Way" (Which is a term I never heard before). 第二个不是“通用方式”(这是我以前从未听说过的术语)。 It is: 它是:

  • Convoluted (checking name property for null after setting it. 令人费解(设置后检查name属性是否为null。
  • The ONLY way to do it before a certain ancient .NET update enabled the new syntax. 在某些古老的.NET更新之前,唯一的方法是启用新语法。

Which pretty much is why you learned it. 几乎是您了解它的原因。 Old syntax. 旧语法。 There is no significant - particularly no measurable - performance difference. 没有显着(尤其是没有可测量的)性能差异。

The new syntax object initializers are basically just a shorthand format that is translated into the long form. 新的语法对象初始化器基本上只是一种简写格式,可以转换为长格式。 You can confirm this with a disassembler of some sort if you like. 如果愿意,可以使用某种反汇编程序进行确认。 You will find that the code is as close to identical as it can get, barring some compiler optimizations. 您会发现,除了一些编译器优化外,代码与所获得的代码几乎一样。

For instance, this code: 例如,此代码:

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

Generates the following IL (according to LINQPad): 生成以下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

Here's the other way: 这是另一种方式:

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

And its IL: 及其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

The only difference here is that the first creates a temporary variable ( loc.2 ) to do the creation and then stores it in the named local variable ( loc.0 ). 唯一的区别是,第一个创建临时变量( loc.2 )进行创建,然后将其存储在命名的局部变量( loc.0 )中。 That difference disappears when you turn optimization on. 打开优化后,这种差异就会消失。

So you can use either method with virtually 0 difference in performance. 因此,您可以使用两种方法的性能差异几乎为0。 Personally I prefer the new object initializer form, just like I prefer the LINQ query syntax. 就个人而言,我更喜欢新的对象初始化形式,就像我更喜欢LINQ查询语法一样。 Both are just syntactic sugar for things happening in the background, but they can have large differences in the way you read the code, and in how you write it. 两者都是后台发生的事情的语法糖,但是它们在读取代码的方式和编写方式上可能会有很大的差异。

Incidentally, array initializers are exactly the same. 顺便说一下,数组初始化器是完全相同的。 These two produce virtually identical code: 这两个产生几乎相同的代码:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM