“Geliştiricinin Kötü Optimizasyon Sezgisini” nasıl önleyebilirim?


22

Bu ifadeyi ortaya koyan bir yazı gördüm :

Geliştiriciler, kodu optimize etmeyi ve iyi sebeplerle sevmeyi severler. Çok tatmin edici ve eğlenceli. Ancak ne zaman optimize edileceğini bilmek çok daha önemlidir. Ne yazık ki, geliştiriciler genellikle bir uygulamadaki performans sorunlarının gerçekte nerede olacağı konusunda korkunç bir sezgiye sahiptir.

Bir geliştirici bu kötü sezgiyi nasıl önleyebilir? Kodunuzun hangi bölümlerinin gerçekten optimizasyona ihtiyacı olduğunu bulmak için iyi araçlar var mı (Java için)? Bu konuyla ilgili bazı makaleler, ipuçları veya iyi okumalar biliyor musunuz?


1
Bu, "karar alırken] sezgilere [güvenmekten] nasıl kaçınırım?" Basit: Gerçekleri ve verileri doğrularsınız. Bu yüzden, optimizasyon durumunda, geliştiricinin bakış açısından: kıyaslama yapıyorsunuz.
haylem

Yanıtlar:


44
  • Pahalı yöntemleri belirlemek için iyi bir profilleyici kullanın.
  • Sıcak noktaların gerçekte ne kadar sürdüğünü belgeleyin.
  • Sıcak noktaların daha hızlı uygulanmasını sağlayın
  • Sıcak noktaların ne kadar sürdüğünü belgeleyin, umarım artık onları sıcak nokta yapmaz.

Temel olarak, sorunun nerede olduğunu ve bu değişikliğin ortadan kalktığını başkalarına kanıtlayabilmeniz gerekir.

Edememek kanıtlamak benim kişisel görüşüme göre - - derhal geri alma için orijinal sürüme bir gelişme, bunun yeterli olduğunu.


51
Veya daha da basitleştirmek gerekirse: "Kötü optimizasyon sezgisini önlemek için sezgiyi kullanmayın. Ölçün."
Kyralessa

6
Bu yüzden sizinki bir cevap ve benimki sadece bir yorum. : P
Kyralessa

2
@ Tommas, eğer okunabilirlik ve bakımla uğraşırsanız, performans sorunlarına tam olarak bakmıyorsunuz, değil mi?

3
@Tomas, katılmıyorum. Spesifikasyonlarda bile, yeni kodu iyice yeniden test etmeniz gerekir. Bu eski kod için gerekli değildir. Geri Döndür.

2
@ Thorbjørn Performans ayarladıktan sonra, yeni kodu da tamamen tekrar test etmeniz gerekir. Bir arıza çıkarırsanız zamandan veya hafızadan tasarruf etmek anlamsızdır.
Thomas Owens

10

Nerede optimize edeceğinizi bilmenin tek yolu kodunuzu belirlemektir. Bir fayda sağlayacağını düşündüğünüz değişiklikler yapmak yerine, en kötü performans gösteren kodun nerede olduğunu kesin olarak öğrenin ve buradan başlayın.

Java , Java Development Kit'in (JDK) son sürümleriyle birlikte gelen VisualVM aracıyla bunu oldukça kolaylaştırıyor . Fikir, hangi kodlara en çok ve hangi yöntemlerle zamanınızın çoğunu harcadığınızı bulmaktır; hem kodunuzda hem de harici kütüphanelerde. Çöp toplama işleminde performans verilerini de alabilirsiniz, böylece toplayıcıyı ayarlayabilir ve uygulamanızın gerektirdiği minimum / maksimum yığın alanını ayarlayabilirsiniz.


VisualVM JRE'de değil, yalnızca JDK'da.

1
@ Thorbjørn Ravn Andersen İyi arama. Aydınlatmalıyım. Ancak, Java geliştirme yapıyorsanız, genellikle JDK'yı yüklüyorsunuz (OpenJDK veya benzerini çalıştırıyor olsanız da - Bunların VisualVM ile gelip gelmediğini bilmiyorum).
Thomas Owens

1
Eclipse'deki çalışma alanlarını çok sık değiştiriyorum, sonra varsayılan olarak Eclipse'i başlatan JRE'ye geçiyorum. JRE'leri yüklemek JDK'lerden çok daha kolay olduğu için, Eclipse derleyicisini içeren ve bu nedenle düz JRE'de çalışabilen bir karınca oluşturma işlemine yavaşça geçtik. Dolayısıyla, bu gün sen yapabilirsiniz aslında JDK olmadan gerçek işler yapmak. VisualVM, Windows 64-bit JVM'lerin 32-bit JVM'lere bağlanamadığı gibi, belirli bir Java versino ile kullanımını kolaylaştırmak için ayrı olarak indirilebilir.

9

Buradaki herhangi biri profilcilerden bahsettiği için sorunun bu bölümüne odaklanacağım.

Bir geliştirici bu kötü sezgiyi nasıl önleyebilir?

Sen. yap. değil. Bunun yerine hiçbir zaman erken optimizasyon yapmazsınız .
Dini bir mantra olduğu gibi tekrar tekrar tekrarlayın.

Bunu yaparken kendinizi bulacaksınız ve yapmamanız gerektiğini keşfedeceksiniz.
Ve sonra tekrar.
Ve yeniden.

Erken Optimizasyon , programcıların sermaye günahlarından biridir .

Araçlar ve malzeme parçası olan sonradan optimizasyonu bir olduğunu kurulan zanaat .


İlk "kıvrılmış kod" optimizasyonu, kesin. Chjoosing algoritmaları ve / veya probleminize uyan veri yapıları ve (beklenen işlem yükünüzle) iyi performans özelliklerine sahip olmak, kod yazmaya başlamadan önce yapılması gereken bir şeydir.
Vatine

@Vatine Evet, orada bulundum. Hayır, yapma Elinizdeki sorunun zihin haritanıza uygun olanı yapın. Bu olabilir olmak etkili ve verimli algoritma ve sana diliyorum, bu zorunlu değildir.
ZJR

bana YAGNI prensibi olarak geliyor - İhtiyacınız olmayacak!
EL Yusubov

7

Bu araçlara profilciler denir . Bunları, programınızın hangi bölümünün / bölümlerinin yürütülmesi için en çok zaman harcadığını, böylece ayarlama çabalarınızı nereye odaklayacağınızı ölçmek için kullanabilirsiniz.

Değişikliklerinizin amaçlanan etkiye sahip olduğunu doğrulamak için değişikliklerden sonra tekrar ölçüm yapmak aynı derecede önemlidir .


5

Programınızın yalnızca hızına veya çalışma zamanına değil, ne kadar bellek kullandığına da bakın.

Java gibi çöp toplayan dillerle çalışan kodlayıcıların çoğu, çöp toplamanın bellek sızıntısını önlediği izlenimini uyandırıyor. Durum böyle değil. Artık ihtiyaç duymadığınız bir nesneye referans tutarsanız, toplanmaz ve böylece sızıntı yapar.

Java web uygulamalarını o kadar sızdıran sunucularını takas alanlarının dışına çıkaracaklarını gördüm!

Hem bir çalışma zamanı profili oluşturucusu hem de bir tür bellek profili oluşturucu kullanıyorsanız, sezgisel olarak daha hızlı ve daha zayıf kod yazmayı öğreneceksiniz. Bu, ilk denemede kodunuzun daha hızlı çalışmasının daha muhtemel bir etkiye sahiptir.


1

Benim çözümüm iki soruya net cevaplar alarak başlamaktır:

  1. performansın nasıl ölçüleceği (örn. veri yükleme süresinin ölçülmesi )
  2. hedef değer nedir (örn. veri% 95 güvenle% 3 saniye veya daha kısa sürede yüklenir )

Bir zamanlar ürünümüzün kırılmasını önlemek için bir kez davet edilen kaplan ekibinden aldığımız hünerle öğrenildi . Bu sürüm performans nedenleriyle bozuldu, şirketin kaplan adamlarının katılımını haklı kılan stratejik müşterilerini kaybedebilir (oldukça pahalı btw). Proje detaylarını açıklamada onlara yardım etmem için görevlendirildim; Bunu da performans hakkında bir iki bilgi edinmek için bir fırsat olarak kullandık.


1

Bulduğum şey, erken optimizasyon için en iyi panzehir bu yöntem .

Bazı kodları hızlandırmak için kullandıktan sonra ( bu örnekte olduğu gibi ), kendi başına bir bağımlılık haline gelir ve performans ayarının ilk prensibinin kod düzenlemesi olmadığını anlarsınız , sorunu bulur .

Gerçek optimizasyon erken optimizasyon yapmaktır, ailenizi beslemek için avlamak teneke kutu çekmektir. Hepsi taş ocağı bulmakla ilgili.


1
Ve ne yazık ki, ailenize sadece 200 kilo taşıyabilir, bu yüzden bütün gün sincap vurmayın.
Ürdün

1

Eski soru, fakat diğerlerinden oldukça farklı olan bu cevabı sunacağım.

Performans kazanımları için büyük fırsatlar paralel işlemden geliyor. Birden fazla iş parçacığından yararlanmak için kodunuzu tasarlamaya çalışın. (Basitlik için bile olsa, sürüm 1'de yapmazsınız). Küçük tahminler veya sezgiler gerekli.

Her şey erken optimizasyondur ve genellikle yanlış olan sezgilerinizi gerektirir.


Gerçekten iyi bir nokta. Günün geri kalanında, işlemcilerin birkaç yılda bir daha hızlı olmalarına güvenebilirsiniz. Şimdi sadece daha fazla işlemci olacağını beklemelisiniz.
JimmyJames

0

Sizin sezgi olabilir zamanla geliştirmek. Belki biraz tartışmalı, bunu atardım ama uzun yıllar boyunca VTune ve CodeAnalyst ve şimdi CodeXL kullanıyorum, sezgilerimde sıcak noktaların nerede olacağı konusunda olduğundan daha doğru olduğumu söyleyebilirim. bazı kodları çıkardığımda artık tam anlamıyla dikkatsizliği yakalamadığım nokta. Bu, işleri kör olarak optimize etmeye çalıştığım anlamına gelmez.

Profil oluşturma aslında profilleyicilere olan bağımlılığımı artırdı, azaltmadı. Sadece, profilleme sonuçlarının bir dereceye kadar ne olacağını tahmin edebileceğimi daha kolay tahmin edebileceğimi, sıcak noktaları başarıyla ortadan kaldırdığımı ve karanlıkta ve bıçaklarda kör bıçaklar olmadan kullanıcı-uç işleminin tamamlanması için gereken süreyi iyileştirebileceğimi söylüyorum (bir şey) Sadece bir sıcak noktanın ne olduğunu anlamaya başlayana kadar bir profilleyici kullanırken bile yapabilir, aynı zamanda neden önbellek özlüyorsa, tam olarak neden sıcak noktalar olduklarını bile yapabilirsiniz).

Ancak, bu sezgiyi geliştirmeye başladığım profilleri kullanmaya başlayana kadar değildi. Sebeplerden biri, kodunuza aşina olmanız durumunda, önsezileriniz en büyük ve en belirgin sıcak noktalara göre doğru olabilir, ancak aradaki tüm incelikleri değil. Doğal olarak, tamamlanması bir saat süren bir kullanıcı sonu işleminiz varsa ve yüz bin öğeyi kapsayan bir girdiyi işleyen tek bir aralıklı kuadratik karmaşıklık algoritması varsa, muhtemelen tüm kar tasarrufunun kuadratik karmaşıklık olduğu fikri üzerine kumar oynayarak zenginleşebilirsiniz. burada hatalı algoritma. Ancak bu size ayrıntılı bir fikir vermez veya zamana tam olarak neyin katkıda bulunmadığını tam olarak bildirir .

Profil oluşturmaya başladığınızda ve zamanın daha büyük bir katkısı olabileceğini düşündüğünüz her şeyin fazla zaman katkısı olmadığını görmek için sahip olunacak çok fazla değer var; Ağrısız açık eksiklik kaynakları değil, şüphelendiğiniz şeyler biraz verimsiz olabilir, ancak profil oluşturduktan sonra, herhangi bir zamanda zar zor katkı sağladıklarını fark etmek. Ve bu, potansiyel olarak en sezgisel içgörüyü edindiğiniz yerde, kendinizi ne kadar zaman harcadığının açıkça belli olmadığı tüm ince alanlarda yanlış göründüğünüzü bulmaktır.

Belirgin algoritmik karmaşıklığın ötesindeki insan sezgisi çoğu zaman yanlış başlayacaktır çünkü makine için verimli olan ve insan zihni için verimli olan çok farklıdır. Kayıtlardan CPU önbelleğine ve DRAM'den diske giden bellek hiyerarşileri hakkında düşünmek ilk başta sezgisel olarak gelmedi. Yedekli aritmetiğin, bazı işlem çalışmalarını atlamak için bir arama tablasının daha fazla dallanma veya hafıza erişiminden daha hızlı olabileceğini düşünmek sezgisel bir şekilde gelmedi. Karar verme, hafıza yükleme ve depolama maliyetleri gibi şeyleri indirirken ne kadar iş yapılması gerektiğini düşünmeye meyilliyiz. Donanım için verimli olan, başlangıçta tüm insani varsayımlarınızı kıracak şekillerde oldukça sezgiseldir.

Sezginin iyileştirilmesinin yardımcı olabileceği, profil oluşturma yoluyla arayüz tasarımıdır . Arayüz tasarımları, yeniden görüşmelerde değişiklik yapmak için çok maliyetlidir, maliyetler bu arayüze bağlı olarak yer sayısıyla orantılı olarak artar. Sezginizi iyileştirmeye başladığınızda, pahalı tasarım değişiklikleri olmadan gelecek optimizasyon için solunum odasını bırakacak şekilde ilk kez ara yüzleri tasarlamaya başlayabilirsiniz. Yine de, bu sezgi genel olarak geliştirdiğiniz bir şeydir ve süresiz olarak, bu profili her zaman elinizde tutarak geliştirmeye devam edin.


0

Profilciler, kod söz konusu olduğunda hatalı sezgileri gidermeye yardımcı olur. Bugünlerde ne kadar donanım öngördüğü göz önüne alındığında, kodunuzun performansını tahmin etmek insanca pratik değildir ancak bu, profilleyicilerin bu sorunu gidermek için geliştirme için standart araçların bir parçası olarak dahil edilmesi gerektiğini savunan Knuth'un on yıllarından beri geçerliydi. geliştiricilerin "pennywise-ve-pound aptal" doğası. Ancak, cevapların başka açılardan ne kadar kapsamlı olduğu ve kullanıcı sonu anlayışının diğer "düzeltme" olduğunu söyleyerek verilen bu cevapla çok farklı bir rota izleyeceğim.

Kişisel deneyimlerime göre, özellikle mükemmel bir geliştiriciye (ancak kullanıcıların gerçekte yazılımı nasıl kullandıklarına dair göz kamaştırıcı noktalara sahip) bir alt bölme algoritmasını eldeki profiler ile optimize ederek tanık oldum (çok iyi ve pahalı ve kapsamlı bir: Intel'in çağrı grafiğine sahip VTune kafesler için GPU profilleyicilerin üstünde örnekleme yapmak, 6 kafesli / giriş çokgenli küpler gibi basit ilkelleri alt bölümlere ayırırken GPU'daki milyarlarca faset ile şaşırtıcı sonuçlar elde eder. Gerçek dünyadaki herhangi bir kullanım durumuna benzemeyen test senaryosuna göre ayarlama ve ayarlama dışında (kullanıcılar milyarlarca farklı yüzeyleri mükemmel bir küreye benzemeye başlayan alt bölümlere ayrılmış bir küp istemiyorlar, alt bölüm girişleri karakter ve araçlar gibi şeyler olma eğiliminde. ve diğer karmaşık girdiler).

Yeterince komik, beyninin yarısı kadar işlevsel bir beyin daha var ve kariyerimdeki kredime hiçbir doktora sahip değildim, sadece kullanıcıların ne istediğini, hangi pazarlamanın ne istediğini, tasarımcıların ne istediğini anladım. Kendinizi, kullanıcının zihniyetine ve ayakkabısına sokmanın ve yazılımınıza ve gerçek çabalarınızdan ayırdığınız çabalardan kurtulmaya çalışırken gerçek kullanıcılarınız olarak ne yapması gerektiğine bakmanın ne kadar yararlı olduğunu gerçekten vurgulayamıyorum. inşa ettiğin şeyi inşa etmek ve ona taze gözlerle bakmak. Yukarıdaki geliştiriciden bile bunun imkansız bir şey olduğunu gördüm; teknik açıdan meraklı ama kullanıcılara açık olmayan geliştiricilerin sahip olduğu benzer bir egoya sahip olduğum için suçluluk duyduğumu düşünüyordu ve kullanıcılar ve tasarımcılar tam olarak ne yapacağımı konuşmak için bana akın ettiğinde sürekli yanıldığını kanıtladım. Kulağa çok bencil gelebilir ama feragat ediciyle, çok iyi bir kodlayıcı olmadığımı, ancak kullanıcıların ve tasarımcıların ne istediğini anlıyorum ve bu beni özellikle çok nadir görünen bir alanda tercih etti. nedense kalite. Programcılar olarak, sıradan, teknik olmayan insanlarla anlamak ve sosyalleşmekten ziyade testler yapmaya daha alışkınız.

Dolayısıyla profilleme ve doğru ölçüm var, ancak gerçek dünya kullanıcılarının gerçekten uygulamaya sağlayacağı girdi türleriyle bir işlemi ölçtüğünüzden emin olmanızın temel ihtiyacı da var. Aksi halde, geliştiriciye normal bir test senaryosu gibi görünebilecek şeylere karşı sıcak noktaları optimize etmeye çalışırken, ancak kullanıcılar için belirsiz olan durumlara karşı ortak bir kullanım durumunun kötüye kullanılmasıyla sonuçlanabilir Bazı belirsiz kullanım lehine, eğer varsa, az sayıda kullanıcının başvurmayı düşündüğü durumlarda kullanın.

Günün sonunda, geliştiriciler olarak taşıma eğiliminde olduğumuz tüm pratikler, kullanıcıları dünyadaki açlığı çözmeden gerçekten yeterince mutlu eden şeyin demir çekicisine karşı dengelenmiş olabilir ve kiracıyı ya da bira satın alabilmemiz için para kazanmamızın pratik gerekliliği çıplak bayanlara ya da ne yapmak / yapmak istediğinize bakın. Geriye kalan her şey potansiyel olarak bu temel iş ihtiyacına ve o kadar asil, o kadar kahramanca bir geliştiriciye karşı çalışmaktır ki, bunun para kazanma ve nihayetinde kullanıcıların para kazanmalarını sağlamak için tatmin edici olacağı unutulmamalıdır. ve sadece yiyecek için biraz para kazanmak ve almak için gerçek dünyaya ihtiyaç duyan sanal dünyalar yaratarak tanrı modunu kapatın. Yazılım metriklerinde ve uygulamalarında kaybolabiliriz ama temelde bu

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.