Performans: türü genel türetilmiştir
Oldukça anlayamadığım bir performans sorunu ile karşılaştım. Nasıl düzeltileceğini biliyorum ama Neden öyle anlamıyorum. Sadece eğlence için!
Konuşalım kodu. Kod sorunu yeniden oluşturmak için elimden geldiği kadar basit.
Genel bir sınıf diyebiliriz. Boş bir liste içinde ve yapıcı T
bir şey yok. Listede IEnumerable<T>
bir yöntem, örneğin Any()
çağıran Run
yöntem vardır.
public class BaseClass<T>
{
private List<T> _list = new List<T>();
public BaseClass()
{
Enumerable.Empty<T>();
// or Enumerable.Repeat(new T(), 10);
// or even new T();
// or foreach (var item in _list) {}
}
public void Run()
{
for (var i = 0; i < 8000000; i )
{
if (_list.Any())
// or if (_list.Count() > 0)
// or if (_list.FirstOrDefault() != null)
// or if (_list.SingleOrDefault() != null)
// or other IEnumerable<T> method
{
return;
}
}
}
}
Sonra boş olan türetilmiş bir sınıf var:
public class DerivedClass : BaseClass<object>
{
}
Hem sınıf ClassBase<T>.Run
yöntem çalışan performansını ölçmek izin. Türetilmiş bir tür erişim; sınıf 4 kez daha yavaş. Ve bunun sebebini anlayamıyorum. Serbest modunda derlenmiş, sonuç ısınma ile aynıdır. Oluyor .NET 4.5.
public class Program
{
public static void Main()
{
Measure(new DerivedClass());
Measure(new BaseClass<object>());
}
private static void Measure(BaseClass<object> baseClass)
{
var sw = Stopwatch.StartNew();
baseClass.Run();
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
}
}
Tam liste on gist
CEVAP
Güncelleme:
Microsoft Connect CLR ekibinden bir cevap var
Paylaşılan jenerik kod sözlük aramaları ile ilgili. Çalışma zamanı ve TAM olarak sezgisel Peki bu özel test için çalışmıyor. Bu konuda neler yapılabilir bir göz atalım.
Bu arada, BaseClass için iki kukla yöntemleri (hatta adı olması gerekmez) ekleyerek bu geçici bir çözüm bulabilirsiniz. Sezgisel biri beklendiği gibi çalışmasına neden olacaktır.
Özgün:
Bu başarısız JİT.
Bu çılgın şey ile tedavi edilebilir:
public class BaseClass<T>
{
private List<T> _list = new List<T>();
public BaseClass()
{
Enumerable.Empty<T>();
// or Enumerable.Repeat(new T(), 10);
// or even new T();
// or foreach (var item in _list) {}
}
public void Run()
{
for (var i = 0; i < 8000000; i )
{
if (_list.Any())
{
return;
}
}
}
public void Run2()
{
for (var i = 0; i < 8000000; i )
{
if (_list.Any())
{
return;
}
}
}
public void Run3()
{
for (var i = 0; i < 8000000; i )
{
if (_list.Any())
{
return;
}
}
}
}
Bu Run2 not()/Run3 ()değilher yerde aradı. Ama Run2 veya Run3 yöntemleri - performans ceza olarak önce alacaksın açıklama.
Bir şey ya da yöntem tablo boyutu, hizalama yığın ilişkili bir şey var sanırım.
P. S. değiştirebilirsiniz
Enumerable.Empty<T>();
// with
var x = new Func<IEnumerable<T>>(Enumerable.Empty<T>);
hala aynı hata.
&; türü yüklenemedi [Ad]".Genel" ...
Genel yöntem birden fazla(VEYA) türü k...
Bu tip 'T' genel tür veya yö...
Eğer genel bir türü bir dize ise test ...
C# Decimal veri türü performans...