對像初始化器性能
c# 3.0 中的對像初始化器是否比正常方式更快?
這是不是更快
Object object = new Object { id = 1; }比這個 ?
Object object = new Object() object.id = 1;
在發布模式下,它們將編譯為完全相同的IL 程式碼(假設您實際上使用的是具有
id屬性的類型而不是Object)因此,根據定義,不會有性能差異。
我不知道哪個編譯速度更快,但編譯時間會略有不同,您可能不在乎。
但是,對像初始值設定項語法編寫得更快(鍵入更少),因此您可能應該使用它。
好的,根據 [SLaks][2] 的評論,並在閱讀後測試自己,結果發現我在這裡描述的差異僅存在於調試模式下。如果您為發布而編譯,它們都編譯為相同的程式碼。每天學些新東西 :)
(因此其餘答案假定為調試模式。)
產生的 IL存在差異,與此處其他人的回答相反,但差異可以忽略不計,實際上根本不會對您的程序產生任何性能影響。
不同之處在於使用對像初始化器,如下所示:
Object object = new Object { id = 1; }程式碼實際上是編譯的,就好像你寫了這個:
Object temp = new Object(); temp.id = 1; Object object = temp;(當然,除非 Object 沒有 Id 欄位/屬性,並且您實際上不能在不使用逐字標識符語法“@object”的情況下將變數命名為“object”。)
為什麼這很重要?好吧,您可能會注意到的一個區別是,如果任何賦值拋出異常(將值寫入對象,或者從表達式或函式中獲取值拋出異常),那麼使用對像初始化器,您將不會t 實際上看到變數中的任何對象,而在您的“手動”程式碼中,該對象將在那裡,初始化直到發生異常的點。
一個微小的差異,不應該有太大的性能差異,但可能會改變程序的行為。
這可以通過查看 IL 來驗證。以這個 C# 程序為例:
using System; namespace ConsoleApplication3 { class Test { public Int32 Id { get; set; } } class Program { static void Main(string[] args) { M1(); M2(); } static void M1() { Test t = new Test(); t.Id = 1; } static void M2() { Test t = new Test { Id = 1 }; } static void M3() { Test t; Test temp = new Test(); temp.Id = 1; t = temp; } } }並編譯它,通過Reflector執行它,你會得到 M1、M2 和 M3 的:
.method private hidebysig static void M1() cil managed { .maxstack 2 .locals init ( [0] class ConsoleApplication3.Test t) L_0000: nop L_0001: newobj instance void ConsoleApplication3.Test::.ctor() L_0006: stloc.0 L_0007: ldloc.0 L_0008: ldc.i4.1 L_0009: callvirt instance void ConsoleApplication3.Test::set_Id(int32) L_000e: nop L_000f: ret } .method private hidebysig static void M2() cil managed { .maxstack 2 .locals init ( [0] class ConsoleApplication3.Test t, [1] class ConsoleApplication3.Test <>g__initLocal0) L_0000: nop L_0001: newobj instance void ConsoleApplication3.Test::.ctor() L_0006: stloc.1 L_0007: ldloc.1 L_0008: ldc.i4.1 L_0009: callvirt instance void ConsoleApplication3.Test::set_Id(int32) L_000e: nop L_000f: ldloc.1 L_0010: stloc.0 L_0011: ret } .method private hidebysig static void M3() cil managed { .maxstack 2 .locals init ( [0] class ConsoleApplication3.Test t, [1] class ConsoleApplication3.Test temp) L_0000: nop L_0001: newobj instance void ConsoleApplication3.Test::.ctor() L_0006: stloc.1 L_0007: ldloc.1 L_0008: ldc.i4.1 L_0009: callvirt instance void ConsoleApplication3.Test::set_Id(int32) L_000e: nop L_000f: ldloc.1 L_0010: stloc.0 L_0011: ret }如果您查看程式碼,M2 和 M3 之間唯一不同的是第二個本地 (
<>g__initLocal0vstemp) 的名稱。但正如其他人已經回答的那樣,這種差異不會產生任何你應該注意到的性能差異。