Sistemlerle çalışırken deneyimli insanlara Visual Studio ölçeğini sormak istiyorum: onları yavaşlatan nedir? Kod tabanını insan anlama yetenekleri içinde tutmak için gereken soyutlama katmanları üzerindeki katmanlar mıdır? Üzerinde çalışılması gereken kod miktarı çok mu? Bu, saat döngüleri / bellek kullanım departmanındaki (akıl almaz derecede büyük) masrafta programcı zamandan tasarruf yaklaşımlarına modern eğilim midir?
Ben bir dizi tahmin sanırım ama ben oldukça büyük bir kod tabanı üzerinde çalıştım (Visual Studio kadar büyük olup olmadığından emin değilim - milyonlarca kod satırında en büyük faktör olarak düşündüğümü sunmak istiyorum kategorisi ve yaklaşık bin eklenti) ve yaklaşık 10 yıl boyunca ve gözlem fenomenleri ortaya çıkar.
Ayrıca, API'lara veya dil özelliklerine veya bunun gibi bir şeye girmediği için biraz daha az tartışmalıdır. Bunlar "harcamalar" dan ziyade bir tartışma doğurabilecek "maliyetler" ile ilgilidir ve ben "harcamalar" üzerine odaklanmak istiyorum.
Gevşek Koordinasyon ve Miras
Gözlemlediğim şey, gevşek koordinasyon ve uzun bir mirasın çok miktarda birikmiş atığa yol açma eğiliminde olduğudur.
Örneğin, bu kod tabanında, birçoğu gereksiz olan yaklaşık yüz ivme yapısı buldum.
Bir fizik motorunu hızlandırmak için bir KD ağacımız olurdu, diğeri genellikle eskisine paralel olarak çalışan yeni bir fizik motoru için, çeşitli örgü algoritmaları için düzinelerce oktre uygulamamız olurdu, render için başka bir KD ağacı Bunların hepsi, aramaları hızlandırmak için kullanılan büyük, hantal ağaç yapılarıdır. Her biri çok ortalama boyutlu bir giriş için yüzlerce megabayttan gigabayt belleğe kadar sürebilir. Her zaman somutlaştırılmadılar ve her zaman kullanılmadılar, ancak herhangi bir zamanda, 4 veya 5'i aynı anda bellekte olabilir.
Şimdi bunların hepsi, aramaları hızlandırmak için aynı verileri saklıyordu. Tüm alanlarını aynı anda 20 farklı yedek harita / sözlük / B + ağacında saklayan, aynı anahtarlarla aynı şekilde düzenlenmiş ve her zaman araştıran analog eski veritabanı gibi düşünebilirsiniz. Şimdi hafızayı ve işlemeyi 20 kat alıyoruz.
Buna ek olarak, fazlalık nedeniyle, bunlardan herhangi birini bununla birlikte gelen bakım fiyat etiketi ile optimize etmek için çok az zaman var ve yapsak bile, ideal olarak yapacağı etkinin sadece% 5'i olurdu.
Bu fenomene ne sebep olur? Gevşek koordinasyon, gördüğüm bir numaralı nedendi. Birçok ekip üyesi genellikle ekosistemlerinde çalışır, üçüncü taraf veri yapıları geliştirir veya kullanır, ancak diğer ekip üyelerinin kullandıkları aynı yapıları kullanmasa bile, aynı endişelerin tamamen açık kopyaları olsa bile.
Bu fenomenlerin devam etmesine ne sebep olur? Eski ve uyumluluk, gördüğüm bir numaralı nedendi. Bu veri yapılarını uygulama maliyetini zaten ödediğimizden ve büyük miktarda kod bu çözümlere bağlı olduğundan, bunları daha az veri yapısına birleştirmeye çalışmak genellikle çok riskliydi. Bu veri yapılarının birçoğu kavramsal olarak çok fazla yedek olmasına rağmen, arayüz tasarımlarında her zaman aynı olanlara yakın değildi. Bu yüzden onları değiştirmek sadece hafıza ve işlem süresi kullanmalarına izin vermek yerine büyük, riskli bir değişiklik olurdu.
Bellek Verimliliği
Genellikle bellek kullanımı ve hızı, en azından yığın düzeyinde ilişkilendirilme eğilimindedir. Yavaş yazılımları genellikle belleği nasıl doldurarak tespit edebilirsiniz. Daha fazla belleğin yavaşlamaya yol açtığı her zaman doğru değildir , çünkü önemli olan "sıcak" bellek (her zaman hangi belleğe erişilir - eğer bir program tekne yükü belleği kullanıyorsa, ancak yalnızca 1 megabaytının tamamı kullanılıyorsa zaman, o kadar hızlı bir şekilde değil).
Böylece, bellek kullanımını temel alarak potansiyel domuzları çoğu zaman tespit edebilirsiniz. Bir uygulama başlangıçta yüzlerce megabayt bellek alırsa, muhtemelen çok verimli olmayacaktır. Bugünlerde gigabayt DRAM olduğunda onlarca megabayt küçük görünebilir, ancak en büyük ve en yavaş CPU önbellekleri hala ölçülü megabayt aralığındadır ve en hızlısı hala kilobayt aralığındadır. Sonuç olarak, sadece başlatmak ve hiçbir şey yapmak için 20 megabayt kullanan bir program, özellikle de bu belleğin 20 megabaytının tümüne tekrar tekrar erişilecekse, donanım CPU önbellek açısından oldukça "çok" bellek kullanıyor ve program çalışırken sık sık.
Çözüm
Bana göre çözüm, ürünleri oluşturmak için daha koordineli, daha küçük ekipler aramak, "harcamalarını" takip edebilecek ve aynı ürünleri tekrar tekrar "satın almaktan" kaçınabilecek olanlar.
Maliyet
Daha tartışmalı "maliyet" tarafına daldım, gözlemlediğim bir "harcama" fenomeni ile sadece ufacık bir bit. Bir dil, bir nesne için kaçınılmaz bir fiyat etiketi ile gelirse (çalışma zamanı yansıması sağlayan ve bir dizi nesne için bitişik ayırmayı zorlayamayan gibi), bu fiyat etiketi yalnızca çok ayrıntılı bir öğe bağlamında pahalıdır. tek Pixel
veya Boolean
.
Yine de, ağır bir yükü işleyen programlar için çok fazla kaynak kodu görüyorum (ör: yüz binlerce ila milyonlarca Pixel
veya Boolean
örnekle uğraşmak ) bu maliyeti ayrıntılı bir düzeyde ödeyerek.
Nesne yönelimli programlama bunu daha da kötüleştirebilir. Yine de bu, "nesnelerin" kendi başına, hatta hatalı bir şekilde OOP'un maliyeti değildir, basitçe bu maliyetlerin, milyonlarca insan tarafından somutlaştırılacak olan ufacık bir öğenin ayrıntılı bir düzeyinde ödenmesi.
Bu, gözlemlediğim diğer "maliyet" ve "harcama" olayları. Maliyet pennies, ancak toplu alım için bir üretici ile pazarlık yapmak yerine bireysel olarak bir milyon kutu soda satın alırsak pennies toplanır.
Burada bana çözüm "toplu" satın alma. Nesneler, bu maliyetin bir soda kutusunun ana eşdeğeri için milyonlarca kez tek tek ödenmemesi şartıyla, her birine bir miktar fiyat etiketi olan dillerde bile mükemmel para cezası.
Erken Optimizasyon
Knuth'un burada kullandığı ifadeyi hiç sevmedim, çünkü "erken optimizasyon" nadiren gerçek dünya üretim programlarını daha hızlı hale getirir. Bazıları, Knuth'un "yazılım üzerindeki gerçek etkisini bilmek için uygun bilgi / deneyim olmadan optimize etmek" anlamına geldiğinde "erken optimizasyon" olarak yorumlamaktadır. Herhangi bir şey varsa, gerçek erken optimizasyonun pratik etkisi genellikle yazılımı yavaşlatacaktır , çünkü sürdürülebilirlikteki bozulma gerçekten önemli olan kritik yolları optimize etmek için çok az zaman olduğu anlamına gelir .
Bu, gözlemlediğim son fenomen, geliştiricilerin bir daha asla satın alınamayacakları veya daha da kötüsü bir tek soda konservesi satın almak için peni kurtarmak için ulaşan, pennies (veya daha da kötüsü, hayali pennies) derleyicilerini veya donanım mimarisini anlayamamaları) başka bir yere milyarlarca dolar harcanırken.
Zaman sonludur, bu nedenle mutlak bağlamsal bilgiye sahip olmadan mutlakları optimize etmeye çalışmak genellikle bize gerçekten önemli olan yerleri optimize etme fırsatından mahrum kalır ve bu nedenle pratik etki açısından, "erken optimizasyon yazılımı çok daha yavaş hale getirir. "
Sorun, yukarıda nesneler hakkında yazdıklarımı alıp, nesne yönelimli programlamayı veya bu tür çılgınca bir şeyi yasaklayan bir kodlama standardı oluşturmaya çalışan geliştirici türleri olması. Etkili optimizasyon etkili önceliklendirmedir ve bir bakım problemleri denizinde boğuluysak kesinlikle değersizdir.