2013-06-19 68 views
1

有時我會得到高度重複的代碼塊,特別是在處理DAL代碼時。C#編譯器是否會優化我的代碼可讀性度量?

例如:

command.Parameters.Add("@CName", SqlDbType.NVarChar, 50).Value = c.Name.DisplayName; 
command.Parameters.Add("@LKey", SqlDbType.NVarChar, 15).Value = c.Alf; 
command.Parameters.Add("@SalesTerritoryId", SqlDbType.NVarChar, 15).Value = c.Profile.SalesTerritoryId; 
command.Parameters.Add("@CAQ", SqlDbType.TinyInt).Value = (short)c.Profile.Quadrant; 

早在VB中有With語句,可以很好地整理東西。偶爾在C#中,我會做這樣的事情:

var cp = command.Parameters; 
cp.Add("@CName", SqlDbType.NVarChar, 50).Value = c.Name.DisplayName; 
cp.Add("@LKey", SqlDbType.NVarChar, 15).Value = c.Alf; 
cp.Add("@SalesTerritoryId", SqlDbType.NVarChar, 15).Value = c.Profile.SalesTerritoryId; 
cp.Add("@CAQ", SqlDbType.TinyInt).Value = (short)c.Profile.Quadrant; 

我個人覺得這是更可讀的,但我想知道如果在編譯時,做兩個版本成爲同IL,在編譯器是足夠聰明,知道我做了什麼,並簡單地優化它呢?

或cp作爲一個無用的參考後編譯?

+3

這是抖動優化的工作,而不是C#編譯器。不管它是否優化,它都沒有什麼區別,Parameters.Add()方法中的開銷數量遠遠超過這樣的微優化。顯然,幫助抖動不會造成傷害,也不會影響可讀性。 –

+2

真的很重要嗎?你有沒有發現這段代碼導致性能問題?如果沒有,轉到重要的事情。 – spender

+0

我*認爲*你的可讀性更強,因爲它不必爲每個指令提供'command.Parameters'參數。不知道在什麼時候創建變量的成本抵消了任何收益。 –

回答

1

即使在編譯形式,它也會保持不變。 (我還沒有嘗試任何優化開關,只是普通的舊版本構建)。問題是ngen會對MSIL做什麼,但就MSIL而言,它確實很重要。

static void foo() { 
    var command = new SqlCommand(); 
    command.Parameters.Add("@Name", SqlDbType.NVarChar, 50).Value = ""; 
} 

static void bar() { 
    var command = new SqlCommand(); 
    var cp = command.Parameters; 
    cp.Add("@Name", SqlDbType.NVarChar, 50).Value = ""; 
} 

富:

.method private hidebysig static void foo() cil managed 
{ 
    // Code size  37 (0x25) 
    .maxstack 4 
    .locals init ([0] class [System.Data]System.Data.SqlClient.SqlCommand command) 
    IL_0000: newobj  instance void [System.Data]System.Data.SqlClient.SqlCommand::.ctor() 
    IL_0005: stloc.0 
    IL_0006: ldloc.0 
    IL_0007: callvirt instance class [System.Data]System.Data.SqlClient.SqlParameterCollection [System.Data]System.Data.SqlClient.SqlCommand::get_Parameters() 
    IL_000c: ldstr  "@Name" 
    IL_0011: ldc.i4.s 12 
    IL_0013: ldc.i4.s 50 
    IL_0015: callvirt instance class [System.Data]System.Data.SqlClient.SqlParameter [System.Data]System.Data.SqlClient.SqlParameterCollection::Add(string, 
                                        valuetype [System.Data]System.Data.SqlDbType, 
                                        int32) 
    IL_001a: ldstr  "" 
    IL_001f: callvirt instance void [System.Data]System.Data.Common.DbParameter::set_Value(object) 
    IL_0024: ret 
} // end of method Program::foo 

酒吧:

.method private hidebysig static void bar() cil managed 
{ 
    // Code size  39 (0x27) 
    .maxstack 4 
    .locals init ([0] class [System.Data]System.Data.SqlClient.SqlCommand command, 
      [1] class [System.Data]System.Data.SqlClient.SqlParameterCollection cp) 
    IL_0000: newobj  instance void [System.Data]System.Data.SqlClient.SqlCommand::.ctor() 
    IL_0005: stloc.0 
    IL_0006: ldloc.0 
    IL_0007: callvirt instance class [System.Data]System.Data.SqlClient.SqlParameterCollection [System.Data]System.Data.SqlClient.SqlCommand::get_Parameters() 
    IL_000c: stloc.1 
    IL_000d: ldloc.1 
    IL_000e: ldstr  "@Name" 
    IL_0013: ldc.i4.s 12 
    IL_0015: ldc.i4.s 50 
    IL_0017: callvirt instance class [System.Data]System.Data.SqlClient.SqlParameter [System.Data]System.Data.SqlClient.SqlParameterCollection::Add(string, 
                                        valuetype [System.Data]System.Data.SqlDbType, 
                                        int32) 
    IL_001c: ldstr  "" 
    IL_0021: callvirt instance void [System.Data]System.Data.Common.DbParameter::set_Value(object) 
    IL_0026: ret 
} // end of method Program::bar 
+0

對,所以我引入了噪音/僞影。謝謝。 – rism

+0

@rism:程序員經常在代碼中引入「noise/artifacts」,以便在返回時更易讀/可維護。你的例子是引入這種「噪音」的習慣性例子。國際海事組織,這不是噪音,後面的例子產生的少數額外的操作碼是一個微小的代價,以便通過在變量中存儲共同性獲得增強的可讀性。就我而言,你的第一個例子很可能會在下一個閱讀代碼的人的大腦中引入噪聲。由於擔心最小IL的產生,所以易於閱讀。 – spender

+0

@spender完全同意。人>機器。 – rism

相關問題