2010-05-09 21 views
17

String.Format uygulamasına bakmak için Reflector kullanıyordum ve her zaman, 1, 2 & 3 argümanını alan String.Format aşırı yüklenmelerinin, bir nesne dizisi alan yöntemin en iyileştirilmiş sürümleri olduğu izlenimine maruz kalıyordum. Ancak, bulduğum şey, dahili olarak bir nesne dizisi oluşturdukları ve bir nesne dizisi alan bir yöntemi çağırdıklarıydı.Neden String.Format aşırı yüklenme var?

1 arg

public static string Format(string format, object arg0) 
{ 
    if (format == null) 
    { 
     throw new ArgumentNullException("format"); 
    } 
    return Format(null, format, new object[] { arg0 }); 
} 

2 bağımsız değişken

public static string Format(string format, object arg0, object arg1) 
{ 
    if (format == null) 
    { 
     throw new ArgumentNullException("format"); 
    } 
    return Format(null, format, new object[] { arg0, arg1 }); 
} 

3 bağımsız değişken

public static string Format(string format, object arg0, object arg1, object arg2) 
{ 
    if (format == null) 
    { 
     throw new ArgumentNullException("format"); 
    } 
    return Format(null, format, new object[] { arg0, arg1, arg2 }); 
} 

Nesne dizisi

public static string Format(string format, params object[] args) 
{ 
    if ((format == null) || (args == null)) 
    { 
     throw new ArgumentNullException((format == null) ? "format" : "args"); 
    } 
    return Format(null, format, args); 
} 

Dahili olarak hepsi aynı kodu kullanarak ve böylece 1, 2 & 3 argüman versiyonları hiçbir hızlı nesne dizisi sürümden daha vardır kullanarak sonunda.

Benim sorum şu ki - neden var? Eğer değerler virgülle ayrılmış listesi ile nesne dizisi sürümünü kullandığınızda

, derleyici otomatik nedeniyle 1, 2 & 3 versiyonları ne temelde parametreler/ParamArray anahtar kelimenin bir nesne diziye argümanları dönüştürür Böylece gereksiz görünüyorlar. BCL tasarımcıları neden bu aşırı yükleri ekledi?

cevap

7

Hans'in belirttiği gibi, bir dizi oluşturmak, bir dizeyi biçimlendirmenin en yaygın durumlarında gereksiz bir ek yük oluşturur. Bu, EXE'de yer kazandırır.

Diğer bir neden de, tüm diller varadik işlevleri desteklememesidir (C# params'un kullanımı). Bu, bu dillerdeki kullanıcıların, en sık kullanılan dize biçimlendirmesi durumları için dizi oluşturulmasını önlemesine olanak tanır. Bu, dizi oluşturma ve başlatma için basit sözdizimi olmayan diller için çok tasarruf sağlar.

+0

İyi puanlar! Bu onların varlığı için mükemmel bir anlam ifade ediyor. – GiddyUpHorsey

+0

"Bir dizi oluşturmak gereksiz bir fazlalıktır" Bu yöntem, dizi içinde yaratılmıştır "tepegöz" açısından ne kadar farklıdır? –

+1

@ChrisMarisic: Sorunun olduğu dizileri oluşturmanın bellek kullanımı veya GC yükü değil; Bu ekstra opcodes. Sadece string dizisi ile 'string.Format 'çağırmak sadece 3 IL opcodes gerektirir, aşırı yüklenme yoksa 10 opcodes gerektirir. Her ek parametre, bir aşırı yük kullanabiliyorsa, yalnızca bir dizi daha fazla opcode gerektirir. Çok fazla sayıda opcodes varsa, bir yöntem satır içi olamaz, bu büyük etkileri vardır. – Gabe

3

Arama yapmak için gereken uygulamadaki kodu unutuyorsunuz. Dizinin oluşturulması ve doldurulması, 3 döngüyü geçmekten çok daha fazla IL gerektirir.

+0

Kesinlikle haklısınız. Bunu düşünmemiştim. Bu yöntemlerin, her zaman orada olduklarını düşündüğüm performanstan ziyade çağrı kodu boyutunu optimize ettiğini söyleyebilirim. – GiddyUpHorsey

+0

Yani doğrudan IL olarak adlandırıyorsanız aşırı yükler mantıklı? –

İlgili konular