.NET yansıması ne kadar maliyetlidir?


210

Yansımanın ne kadar kötü kullanıldığını sürekli duyuyorum. Genel olarak düşünmekten kaçınır ve nadiren sorunumu çözmenin imkansız olduğu durumları bulsam da, merak ediyordum ...

Uygulamalarda yansımayı kullananlar için performans isabetlerini ölçtünüz mü ve gerçekten çok mu kötü?


Bu soruyu da kontrol etmek isteyebilirsiniz. stackoverflow.com/questions/224232/…
smaclell

1
Fasterflect.codeplex.com adresindeki API'yi kullanın. Getters / setters / invokers ve diğer bazı şeyler için yansımayı 500x hızlandıracak. Genişletmeniz gerekiyorsa, kaynak ve nasıl çalıştığı hakkında bilgi de vardır.
Brandon Moore

3
Bu bilgi 2014 yılında nasıl kontrol ediyor? Bu 4 yılda bir şey değişti mi?
Mart'ta Arnthor

1
Bir örnek özelliğine değer atamanın basit görevi, yansımayla (PropertyInfo.SetValue (örnek, değer)) basit kodlamadan (example.property = değer) yapmaktan yaklaşık 150 kat daha yavaştır. Bu, .NET 4.0
Thanasis Ioannidis

Yanıtlar:


130

Bu. Ama bu ne yapmaya çalıştığınıza bağlı.

İşlemleri (eklentileri) dinamik olarak yüklemek için yansıma kullanıyorum ve performansı "cezası" sorun değil, çünkü işlem uygulamanın başlatılması sırasında yaptığım bir şey.

Ancak, her birinde yansıma çağrıları olan bir dizi iç içe döngüyü yansıtıyorsanız, kodunuzu tekrar ziyaret etmeniz gerektiğini söyleyebilirim :)

"Birkaç kez" işlemler için, yansıma mükemmel bir şekilde kabul edilebilir ve herhangi bir gecikme veya sorun görmezsiniz. Bu çok güçlü bir mekanizmadır ve .NET tarafından bile kullanılır, bu yüzden neden denememeniz gerektiğini anlamıyorum.


Ben yöntemi yakalamak için deneyin, try-catch hata günlüğü geçerli yöntemin sınıf adı. temel olarak günlük kaydı hatası sırasında fonksiyon isminin kodlanmasını önlemek için. Endişelenmem gerekiyor mu?
Sangram Nandkhile

@Sangram hayır, sorun değil
Karthik AMR

@Sangram no, sürekli yakalamak gereken çok fazla hata yoksa, o zaman farklı bir sorun olmalı :)
Martin Marconcini

5
@Sangram, yansıma performansı sizin durumunuzda sorun olmamasına rağmen, sade eski istisnaların kutudan çok daha zarif bir şekilde sağladığı şeyleri yeniden uygulamaya çalışıyorsunuz gibi görünüyor ...
Jacek Gorgoń

152

Jeff Richter, Gündelik İşlerin Performansı adlı konuşmasında , bir yöntemi yansıtarak çağırmanın, normal olarak çağırmaktan yaklaşık 1000 kat daha yavaş olduğunu gösteriyor.

Jeff'in ipucu: yöntemi birden çok kez çağırmanız gerekiyorsa, bulmak için yansımayı bir kez kullanın, daha sonra bir temsilciye atayın ve sonra temsilciyi arayın.


18
Devscovery'ye de katıldım ve .NET 3.5 için bu sonuçlarla hemfikirim. .NET 4 için Devscovery performans kıyaslama programının yeniden derlenmesi büyük gelişme gösteriyor! Maliyet 100 kat daha yavaş düşer. Typeof () aramaları için yansıma kullanılması .NET 3.5 ve .NET 4 arasında değişmez.
John Wigger

61

Yansıtma performansı uygulamaya bağlıdır (yinelenen çağrılar önbelleğe alınmalıdır, örneğin:) entity.GetType().GetProperty("PropName"). Günlük bazda gördüğüm yansımaların çoğu, veri okuyucularından veya diğer depo türü yapılardan varlıkları doldurmak için kullanıldığından, bir nesne özelliklerini almak veya ayarlamak için kullanıldığında performansı özellikle yansıma üzerinde karşılaştırmaya karar verdim.

Tüm yinelenen çağrıları ve yalnızca gerçek SetValue veya GetValue çağrısını önbelleğe aldığından adil olduğunu düşündüğüm bir test geliştirdim. Performans testi için tüm kaynak kodu şu adresteki bitbucket'tedir: https://bitbucket.org/grenade/accessortest . İnceleme memnuniyetle karşılanır ve teşvik edilir.

Buraya vardığım sonuç, pratik olmadığı ve yansıma uygulamasının iyi yapıldığı bir zamanda 100.000 satırdan daha az dönen bir veri erişim katmanındaki yansımayı kaldırmak için fark edilir performans iyileştirmeleri sağlamadığıdır.

Doldurulmuş varlık sayısına (x) göre süre (y) grafiği

Yukarıdaki grafik benim küçük karşılaştırmamın çıktısını gösterir ve yansımadan daha iyi performans gösteren mekanizmaların bunu ancak 100.000 döngü işaretinden sonra fark edilir bir şekilde yaptığını gösterir. Çoğu DAL, aynı anda sadece birkaç yüz veya binlerce satır döndürür ve bu düzeylerde yansıma iyi sonuç verir.


9
Şart değil. DAL dönüşümleriniz yalnızca birkaç bin öğede olabilir, ancak uygulamanızı kullanan eşzamanlı kullanıcılar tarafından (web ise) çoğalır ve tıpkı milyon öğeyi dönüştürür gibi toplanabilir. Belirli bir yöntem 100 kat daha yavaşsa, küçük ve büyük setlerde çok daha yavaş olacaktır. Yavaş yavaştır.
Robert Koritnik

@RobertKoritnik Bu, sunucunuzdaki web yöntemlerinin Asenkron olmadığını varsayar
Kurren

@kurren zaman uyumsuzluğu yansımayı değil, sunucu kaynaklarını etkiler. Eşzamansız Web yöntemleri elbette daha fazla kullanıcıya hizmet verebilir, ancak yansıma yine de yavaş olacaktır. Ve AFAIK tek başına yansıma zaten eşzamanlı bir süreçtir. Öte yandan veri alma, eşzamansız tasarımla güzel oynayacak tek parça olacaktır.
Robert Koritnik

3
Grafikteki Hyper yöntemi nedir? Reflektörden farkı nedir?
Bryan Legend

Ben bu @ yalnızCoder başvurmak gerekirdi: codeproject.com/Articles/18450/… tarafından stackoverflow.com/users/23354/marc-gravell
bombası


12

Benim en uygun deneyimim, özellik olarak büyük bir nesne modelinde aynı türdeki iki veri varlığını karşılaştırmak için kod yazmaktı. Çalıştı, denedi, köpek gibi koştu, tabii ki.

Ben umutsuzdum, sonra bir gecede mantığı değiştirmeden, karşılaştırmayı yapmak için ancak otomatik olarak özelliklere erişmek için yöntemleri otomatik olarak oluşturmak için aynı algoritmayı kullanabileceğimi fark ettim. Bu amaçla kodu uyarlamak için hiç zaman aldı ve nesne modeli her değiştiğinde bir düğmeyi tıklatarak güncelleştirilebilir statik kod ile varlıkların derin özellik-akıllı karşılaştırma yapmak için yeteneği vardı.

Demek istediğim: Birkaç kez beri meslektaşları ile görüşmelerde yansıma kullanımları çalışma zamanı işlemleri yerine derlemek için kod otomatik oluşturmak olabilir ve bu genellikle dikkate değer olduğunu işaret etti.


Visual Studio'nun böyle mükemmel bir şablon desteğine sahip olduğu düşünüldüğünde, kod oluşturma kullanmak için pratik bir yoldur
Sebastian

12

Büyük değil. Martin'in belirttiği gibi, aptalca bir yerde kullanmadığınız sürece, masaüstü geliştirmede hiç bir sorun yaşamadım. Bir çok insanın masaüstü geliştirmedeki performansı hakkında tamamen mantıksız korku duyduğunu duydum.

In Compact Framework (genellikle olduğum) olsa da, hemen hemen bu aforoz ve çoğu durumda veba gibi kaçınılmalıdır. Yine de nadiren kullanmaktan kurtulabilirim, ancak daha az eğlenceli olan uygulamasına gerçekten dikkat etmeliyim. :(


5
Bana yeni bir kelime öğrettiğin için +1: anatema. Ayrıca irrasyonel korkulardan bahsetmek için. Mantıksız bir şekilde korkan programcılardan korkuyorum - bu onların ne yaptığını gerçekten bilmediklerini ve sadece yaptıklarını diğer insanların söylediklerine dayandırdıklarını gösteriyor. öksürük kargo kült öksürük
bsneeze

1
Ahhhh Kargo Kült. Şimdi meraklı insan davranışının güzel bir örneği var.
18'de Quibblesome

10

Performans açısından kritik kod için .NET kitaplıkları tarafından dahili olarak yapılan yansıma konusunda bile endişelenmeniz yeterli.

Aşağıdaki örnek eski (2008) için geçerlidir, ancak uzun zaman önce daha yeni CLR sürümlerinde düzeltilmiştir. Genel olarak yansıma hala biraz maliyetli bir şey!

Burada örnek: Yüksek performanslı kodda bir lock (C #) / SyncLock (VB.NET) deyiminde "Object" olarak bildirilmiş bir üyeyi asla kullanmamalısınız. Neden? CLR bir değer türüne kilitlenemediğinden, Nesnenizin gerçekte bir referans türü yerine bir değer türü olup olmadığını görmek için çalışma zamanı yansıma türü denetimi yapmak zorunda olduğu anlamına gelir.


13
adil olmak gerekirse, bir yansıma türü denetimi hızlıdır.
Jimmy

1
Böyle bir 'performans kritik kodu' için gerçekten başlamak için .NET kullanıyor musunuz?
Seph

1
@Seph: .NET'in dinamik / yansıma bölümleri, no. Ama her zamanki C # /. NET, neden olmasın? C ++ ve C # hızlandırmaları uygulama katmanında marjinaldir (C ++ yoğun matematik rutinlerinde hala% birkaç daha hızlıdır). Ve sanırım montaj
önermiyorsun

Kutulu bir değer türü (yani nesne) kilitlenebilir. @BryceWagner doğru.
Fowl

1
Adil olmak gerekirse (bana göre), cevabın "düz saçmalık" değil, "eski" olduğunu söylemek daha doğru olur. Kilidin (obj) davranışı hakkındaki düşüncelerim yazıldığı sırada doğru OLDU, ancak CLR'nin uygulamaya özgü davranışı çoktan gitti.
McKenzieG1

5

Programlamadaki her şeyde olduğu gibi, performans maliyetini kazanılan herhangi bir fayda ile dengelemeniz gerekir. Yansıma dikkatle kullanıldığında paha biçilmez bir araçtır. Bağlamaları yapmak için yansıma kullanılan C # bir O / R eşleme kitaplığı oluşturdum. Bu fevkalade iyi çalıştı. Yansıma kodunun çoğu sadece bir kez yürütüldü, bu yüzden herhangi bir performans isabeti oldukça küçüktü, ancak faydaları harikaydı. Yeni bir fandangled sıralama algoritması yazsaydım, muhtemelen kötü kullanmaz, çünkü muhtemelen yansıma kullanmazdım.

Sorunuzu burada tam olarak yanıtlamadığım için teşekkür ederim. Demek istediğim, gerçekten önemli değil. Uygun olduğunda yansımayı kullanın. Nasıl ve ne zaman kullanılacağını öğrenmek için ihtiyacınız olan başka bir dil özelliğidir.


3

Sık sık nesne oluşturmak için kullanırsanız yansıma performans üzerinde belirgin bir etkiye sahip olabilir. Kompozit UI Uygulama Bloğuna dayalı uygulama geliştirdim yoğun yansımasına dayanarak . Yansıma yoluyla nesnelerin yaratılmasıyla ilgili belirgin bir performans düşüşü olmuştur.

Ancak çoğu durumda yansıma kullanımıyla ilgili herhangi bir sorun yoktur. Tek ihtiyacınız olan bazı montajları incelemekse , çok hafif ve hızlı olan Mono.Cecil'i tavsiye ederim


3

Parametre listesiyle eşleşen bir yöntem için istek yaptığınızda çalışma zamanının yapması gereken birçok denetim nedeniyle yansıma maliyetlidir. İçeride derin bir yerde, bir tür için tüm yöntemlerin üzerinden geçen, görünürlüğünü doğrulayan, dönüş türünü ve ayrıca her parametrenin türünü kontrol eden kod vardır. Bütün bunlar zamana mal oluyor.

Bu yöntemi dahili olarak yürüttüğünüzde, gerçek hedef yöntemi uygulamadan önce uyumlu bir parametre listesini geçtiğinizi kontrol etmek gibi şeyler yapan bir kod vardır.

Mümkünse, gelecekte sürekli olarak yeniden kullanılacaksa, yöntem tutamaçını önbelleğe alması önerilir. Tüm iyi programlama ipuçları gibi, kendini tekrar etmekten kaçınmak genellikle mantıklıdır. Bu durumda, yöntemi belirli parametrelerle sürekli olarak aramak ve ardından her seferinde uygulamak boşa gider.

Kaynağın etrafında konuşun ve neler yapıldığına bir bakın.


3

Her şeyde olduğu gibi, her şey durumu değerlendirmekle ilgilidir. Gelen DotNetNuke olarak adlandırılan, oldukça çekirdek bileşeni varFillObject kullanımları yansıma datarows nesneleri doldurmak için bu.

Bu oldukça yaygın bir senaryodur ve MSDN'de İş Nesnelerini ASP.NET Form Denetimlerine Bağlamak için Yansımayı Kullanma başlıklı bir makale vardır performans sorunlarını kapsayan .

Performans bir yana, o senaryoda yansıma kullanmaktan hoşlanmadığım bir şey, derleme kodunu kaybettiğinizi düşündüğünüzde benim için çabaya değmeyecek hızlı bir bakışta kodu anlama yeteneğini azaltma eğiliminde olmasıdır. güçlü yazılan veri kümelerinin veya LINQ to SQL gibi bir şeyin aksine zaman güvenliği .


2

Yansıma, uygulamanızın performansını önemli ölçüde yavaşlatmaz. Yansımayı kullanmadan belirli şeyleri daha hızlı yapabilirsiniz, ancak Yansıma bazı işlevlere ulaşmanın en kolay yoluysa, o zaman onu kullanın. Eğer mükemmel bir sorun haline gelirse, kodlamayı Yansımadan uzaklaştırarak her zaman yeniden düzenleyebilirsiniz.


1

Sanırım cevabın buna bağlı olduğunu göreceksiniz. Görev listesi uygulamanıza koymak istiyorsanız büyük bir sorun değil. Facebook'un kalıcılık kütüphanesine koymak istiyorsanız bu çok önemli.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.