Modüler programlama hesaplama süresini etkiler mi?


19

Herkes kodumu modüler yapmam gerektiğini söylüyor, ancak daha az ama daha büyük yöntemler yerine daha fazla yöntem çağrısı kullanırsam daha az verimli değil mi? Bu konu için Java, C veya C ++ 'daki fark nedir?

Özellikle bir grupta düzenlemek, okumak ve anlamak daha kolay olur. Peki hesaplama zamanı kaybı kod düzenlilik yararlarına göre önemsiz midir?


2
Soru, daha zor bakım için harcanan süreyi geçirdiğiniz işlem süresi için ne kadar zaman alacağıdır. Bunun cevabı tamamen başvurunuza bağlıdır.
Blrfl

2
Birçok iyi soru, uzman deneyimine dayalı olarak bir dereceye kadar fikir üretmektedir, ancak bu sorunun cevapları gerçekler, referanslar veya spesifik uzmanlıktan ziyade neredeyse tamamen görüşlere dayanma eğilimindedir.
gnat

10
Ayrıca, bir işlev veya yöntem çağrısı için hesaplama cezasının o kadar küçük olduğunu da belirtmek gerekir ki, çok sayıda işlev ve yöntem çağrısı içeren çok büyük bir programda bile, bu çağrıları yapmak grafikte bile sıralanmaz.
greyfade

1
@greyfade: Bu doğrudan sıçramalar için doğrudur, ancak dolaylı tahmin edilen atlama, örneğin programın toplam çalışma süresinin ~% 3'üne mal olabilir (sadece yakın zamanda kontrol ettiğim programdan bir sayı - yine de temsili olmayabilir). Bölgenize bağlı olarak önemli olabilir veya olmayabilir, ancak grafikte kayıt yaptı (ve elbette modülerliğe en azından kısmen dik).
Maciej Piechotka

4
Erken optimizasyon tüm kötülüklerin köküdür. Doğrusal kod, modüler koddan biraz daha hızlıdır. Modüler kod spagetti kodundan çok daha hızlıdır. Her şeyin çok (çok) kapsamlı bir projesi olmadan doğrusal kodu hedeflerseniz, spagetti kodu ile sonuçlanacaksınız, bunu garanti ederim.
SF.

Yanıtlar:


46

Evet, alakasız.

Bilgisayarlar, beyinlerle kıyaslanamayan hızlarda çalışan yorulmak bilmeyen, neredeyse mükemmel yürütme motorlarıdır. Bir fonksiyon çağrısının bir programın yürütme süresine eklenmesi ölçülebilir bir süre olsa da, bu okunamayan rutini çözmek zorunda kaldıklarında kodla ilgili bir sonraki kişinin beyninin ihtiyaç duyduğu ek zamana kıyasla hiçbir şey değildir. onunla nasıl çalışılacağını bile anlamaya başlamak . Bir şaka için hesaplama deneyebilir - senin kod yalnızca muhafaza edilmesi olduğunu varsayalım kez ve sadece kod ile uzlaşmak birisinin gereken süre için yarım saat ekler. İşlemci saat hızınızı alın ve hesaplayın: kodun bunu dengelemeyi hayal etmek için kaç kez çalışması gerekir ?

Kısacası, CPU'ya acımak tamamen zamanın% 99.99'unu tamamen yanlış yönlendirdi. Kalan nadir durumlarda profiler kullanın. Do not Eğer bu davaları nokta olabilir varsayalım - yapamazsın.


2
Çoğu zaman bunun erken optimizasyon olduğunu kabul etsem de, zamanla olan argümanınızın kötü olduğunu düşünüyorum. Zaman farklı durumlarda görecelidir ve yaptığınız gibi hesaplayamazsınız.
Honza Brabec

28
+1 sadece "CPU'ya acıma" ifadesi için, çünkü erken optimizasyonda yanlış olanı çok güzel vurgular.
Michael Borgwardt

4
Son derece ilgili: Bilgisayarlar günlük olarak ne kadar hızlı? "Hız" için birkaç işlev çağrısından kaçınmak için kendi yolunuzdan çıkmak, hayatları boyunca birini toplamda bir dakika kurtarmak için kendi yolunuzdan çıkmak gibidir . Kısacası: dikkate alınması gereken zamana değmez.
BlueRaja - Danny Pflughoeft

7
Birçoğunun eksik olanlarını çok iyi sattığınız için +1, ancak CPU'ya acımayı daha da ağırlaştıran dengeye en önemli ağırlığı eklemeyi unuttunuz: Bir kerelik bakım için harcanan para ve zaman kaybını göz ardı etmek; 1 saniye sürdüyse, hala çok daha sinsi bir lavabo var. Hata riski . Daha sonra bakım yapan kişinin kodunuzu değiştirmesi ne kadar karmaşık ve zorsa, içindeki hataları uygulamada o kadar önemli risk oluşturur; bu da kullanıcılara riskten inanılmaz derecede kaçınılmaz maliyetlere neden olabilir ve herhangi bir hata takip bakımına neden olabilir (bu da neden olabilir) böcek ...)
Jimmy Hoffa

Eski bir öğretmenim derdi "Eğer erken optimizasyon yapıp yapmadığınızı düşünüyorsan, tam burada dur. Bu doğru seçim olsaydı, biliyordun."
Ven

22

Değişir.

Her şeyin insan hızlarında gerçekleştiği Web programlama olan buzul yavaşlığında, yöntem çağrısının maliyetinin yöntem tarafından yapılan işlemin maliyetiyle karşılaştırılabilir veya aşıldığı yöntem ağır programlama, muhtemelen önemli değil .

Gömülü sistemler dünyasında, yüksek oranlı kesmeler için kesme ve kesme işleyicileri dünyasında, kesinlikle önemlidir. Bu ortamda, "bellek erişimi ucuz" ve "işlemci sonsuz hızlı" modelleri bozulur. Bir ana bilgisayar nesnesi yönelimli programcı ilk yüksek hızlı kesme işleyicisini yazdığında ne olduğunu gördüm. Güzel değildi.

Birkaç yıl önce, gerçek zamanlı FLIR görüntülerinde, o zaman iyi bir işlemci olan yinelemesiz 8 yönlü bağlantı blob renklendirme yapıyordum. İlk denemede bir altyordam çağrısı kullanıldı ve altyordam çağrısı yükü işlemciyi canlı olarak yedi. (4 PİKSEL BAŞINA x kare başına 64K piksel x saniyede 30 kare = anlarsınız). İkinci girişim, alt rutini, okunabilirlik kaybı olmadan bir C makrosuna dönüştürdü ve her şey güllerdi.

Yaptığınız şeye ve yapacağınız ortama ZOR bakmak zorundasınız.


Modern programlama sorunlarının çoğunun en iyi nesne yönelimli, yöntem mutlu kodla ele alındığını unutmayın. Gömülü bir sistem ortamında olduğunuzu bileceksiniz.
Kevin - Monica'yı eski

4
+1, ancak bir uyarı ile: genellikle optimize edici bir derleyici genellikle bir kişiden daha fazla satır içi, döngü çözme ve skaler ve vektör optimizasyonu yapma işi yapar. Programcı, bundan yararlanmak için dili, derleyiciyi ve makineyi hala çok iyi bilmelidir, bu yüzden sihir değildir.
resly

2
Bu doğru, ancak mantığı yazdıktan ve algoritmanızdaki sorunlu kısmı bulmak için profil oluşturduktan sonra kodunuzu optimize ettiniz. Performans için değil, okunabilirlik için kod yazmaya başladınız. Ve makrolar, kodunuzu okunabilir tutmanıza yardımcı olur.
Uwe Plonus

2
Gömülü sistem programlamasında bile, net doğru kod yazarak başlayın ve yalnızca gerektiğinde ve profil oluşturmada yönlendirildiği şekilde optimizasyona başlayın . Aksi takdirde, performans / kod boyutu üzerinde gerçek bir etkisi olmayan ve kaynağın anlaşılmasını zorlaştıran çok fazla iş koymak çok kolaydır.
Donal Fellows

1
@detly: Evet ve hayır. Modern derleyiciler DİLİN ETKİLEYEN SINIRLARI İLE GENEL daha iyi bir iş yapabilir. İnsan programcısı, dilin getirdiği sınırların eldeki özel durumda uygulanabilir olup olmadığını bilir. Örneğin, Cn ve C ++ derleyicileri, programcının belirli çok patolojik bir şey yapmasına ve yine de çalışan kod üretmesine izin vermek için dil standartları tarafından gereklidir. Programcı, bu şeyleri yapacak kadar çılgın, aptal ya da maceracı olmadığını bilebilir ve aksi takdirde güvenli olmayacak optimizasyonlar yapabilir, çünkü bu durumda güvende olduklarını bilir.
John R. Strohm

11

Her şeyden önce: Yüksek dilde programlar makineler tarafından değil insanlar tarafından okunmak içindir.

Öyle ki programlar yazmak sen onları anlamak. Performans hakkında düşünmeyin (ciddi performans sorunları yaşıyorsanız uygulamanızı profille ve gerektiğinde performansı artırın).

Bir yöntemin veya fonksiyonun çağrılmasının biraz ek yük aldığı doğru olsa bile, bu önemli değildir. Günümüzde derleyiciler kodunuzu verimli makine dilinde derleyebilmeli, böylece üretilen kod hedef mimari için verimli olmalıdır. Verimli kodu almak için derleyicinizin optimizasyon anahtarlarını kullanın.


5
Programları, başkalarının anlayacağı şekilde yazmamız gerektiğini söyleyebilirim .
Bartlomiej Lewandowski

Bir programı okumak zorunda olan ilk kişi geliştiricinin kendisidir. Ben yazdım nedeni de budur sizi . Eğer başkaları da programı okuyabiliyorsa, güzel ama (benim gözümde) gerekli değildir (ilk etapta). Eğer bir takımda çalışıyorsanız, o zaman diğer insanlar da programı anlamalıdır ama niyetim o kişinin bilgisayarları değil bir programı okuması gerektiğiydi.
Uwe Plonus

5

Tipik olarak büyük bir işleve sahip olacağınız ve onu çok daha küçük olanlara böldüğünüzde, bu küçük olanlar satır içine alınacaktır, çünkü satır içi tek dezavantajı (aynı talimatları çok fazla tekrarlamak) bu durumda geçerli değildir. Bu, kodunuzun büyük bir işlev yazmış gibi davranacağı anlamına gelir.

Herhangi bir nedenden dolayı satır içi değilse ve bu bir performans sorunu haline gelirse, manuel satırlamayı düşünmelisiniz. Tüm uygulamalar büyük içsel gecikmeleri olan ağ bağlantılı CRUD formları değildir.


2

Muhtemelen hesaplama maliyeti yoktur. Genellikle son 10-20 yıl için derleyiciler / JIT'ler mükemmel ince çizgi fonksiyonu ile ilgilenir. C / C ++ için genellikle 'inlinable' fonksiyonlarla sınırlıdır (yani derleme sırasında fonksiyonun tanımı derleyici için kullanılabilir - yani aynı dosyanın başlığındadır) ancak mevcut LTO teknikleri bunun üstesinden gelir.

Optimizasyon için zaman harcamalısınız, üzerinde çalıştığınız alana bağlıdır. Çoğu zaman girişte bekleyen 'normal' uygulama ile uğraşıyorsanız - muhtemelen uygulama 'yavaş' hissetmedikçe optimizasyonlar için endişelenmemelisiniz.

Bu gibi durumlarda bile mikro optimizasyon yapmadan önce birçok şeye konsantre olmalısınız:

  • Sorunlar nerede? Kaynak kodunu farklı okuduğumuzda genellikle insanlar sıcak noktaları bulmakta zorlanırlar. Biz operasyon farklı zaman oranına sahip ve ederken sırayla bunları gerçekleştirmek Modern işlemciler yok .
  • Her seferinde hesaplama yapmak gerekli mi? Örneğin, tek bir parametreyi binlerce olarak değiştirirseniz, modelin tamamı yerine sadece etkilenen bir kısmı hesaplamak isteyebilirsiniz.
  • Optimal algoritma kullanıyor musunuz? Değiştirin O(n)için O(log n)daha sonra her şey mikro-optimizasyon tarafından elde edebiliriz çok daha büyük bir etkiye sahip olabilir.
  • Uygun yapılar kullanıyor musunuz? ListGereksinim duyduğunuzda bir kullandığınızı ve HashSetböylece ne zaman O(n)arayabileceğinizi varsayalım O(1).
  • Paralelliği verimli kullanıyor musunuz? Şu anda cep telefonları bile 4 çekirdeğe veya daha fazlasına sahip olabilir. Bununla birlikte, senkronizasyon maliyetine sahip oldukları için gümüş bir mermi değildirler (problem hafızaya bağlıysa zaten bir anlam ifade etmediklerinden bahsetmiyorum).

Mikro optimizasyon yapmaya karar verseniz bile (bu, yazılımınızın HPC'de kullanıldığı, katıştırıldığı veya sadece çok sayıda kişi tarafından kullanıldığı anlamına gelir - aksi takdirde ek bakım maliyeti bilgisayar zaman maliyetlerinin üstesinden gelir) hızlandırmak istediğiniz sıcak noktaları (çekirdekleri) belirlemek için. Ama sonra muhtemelen:

  1. Üzerinde çalıştığınız platformu tam olarak bilin
  2. Üzerinde çalıştığınız derleyiciyi ve hangi optimizasyonu yapabileceğini ve bu optimizasyonu etkinleştirmek için deyimsel kodun nasıl yazılacağını tam olarak bilin
  3. Bellek erişim kalıplarını ve önbelleğe ne kadar sığabileceğinizi düşünün (tam boyutu 1. noktadan bildiğiniz).
  4. Eğer hesaplama bağlı iseniz hesaplamayı kaydetmek için hesaplamayı yeniden organize etmeyi düşünün

Son bir açıklama olarak. Genellikle yöntem çağrılarıyla ilgili tek sorun, şube öngörücüsü tarafından tahmin edilmeyen dolaylı atlamalardır (sanal yöntemler) (ne yazık ki dolaylı atlama bunun için zor bir durumdur). Ancak:

  • Java, birçok durumda sınıf türünü ve dolayısıyla önceden atlama hedefini tahmin edebilen bir JIT'e sahiptir ve bu nedenle sıcak noktalarda çok fazla sorun yaşamamanız gerekir.
  • C ++ derleyicileri genellikle bir program analizi yapar ve en azından bazı durumlarda hedefi derleme zamanında tahmin edebilir.
  • Her iki durumda da hedef tahmin edildiğinde, satır içi çizgi çalışmalıdır. Derleyici satır içi şansı gerçekleştiremezse biz de yapamadık.

0

Cevabım muhtemelen mevcut cevaplarda çok fazla genişlemeyecek, ancak iki sentimin yardımcı olabileceğini hissediyorum.

İlki; evet, modülerlik için genellikle bir miktar yürütme süresinden vazgeçersiniz. Montaj kodunda her şeyi yazmak size en iyi hızı verecektir. Bahsedilen...

YouTube'u biliyor musunuz? Muhtemelen var olan en yüksek bant genişliği sitesi mi, yoksa Netflix'in ikincisi mi? Kodlarının büyük bir bölümünü, birinci sınıf performans için oldukça inşa edilmemiş oldukça modüler bir dil olan Python'a yazıyorlar.

Mesele şu ki, bir şeyler ters gittiğinde ve kullanıcılar videoların yavaş yüklenmesinden şikayet ettiğinde, bu yavaşlığın nihayetinde Python'un yavaş yürütme hızıyla ilişkilendirileceği pek çok senaryo yoktur. Bununla birlikte, Python'un hızlı yeniden derlemesi ve tür denetlemeden yeni şeyler denemeye yönelik modüler yeteneği muhtemelen mühendislerin neyin yanlış gittiğini hızlı bir şekilde hata ayıklamasına izin verecektir ("Vay canına. Yeni stajyerimiz yeni bir SQL alt sorgusu yapan bir döngü yazdı HER sonuç için. ") veya (" Oh, Firefox bu eski önbellek başlığı biçimini kullanımdan kaldırmıştır ve yenisini kolayca ayarlamak için bir Python kütüphanesi oluşturdular ")

Bu anlamda, yürütme süresi açısından bile, modüler bir dil daha hızlı düşünülebilir, çünkü darboğazlarınızın ne olduğunu bulduktan sonra, kodunuzun en iyi şekilde çalışmasını sağlamak için kodunuzu yeniden düzenlemek daha kolay olacaktır. Pek çok mühendis, ağır performans vuruşlarının olacağını düşündükleri yerde olmadığını söyleyecek (ve aslında optimize ettikleri şeylere çok ihtiyaç duyulmadı; ya da bekledikleri şekilde çalışmadı!)


0

Evet ve hayır. Diğerlerinin belirttiği gibi önce okunabilirlik için, sonra verimlilik için program. Bununla birlikte, hem okunabilir hem de verimlilik olan standart uygulamalar vardır. Çoğu kod oldukça seyrek çalışır ve yine de onu optimize etmekten fazla avantaj elde edemezsiniz.

Java daha küçük işlev çağrılarını satır içine alabilir, bu nedenle işlevlerin yazılmasını önlemek için çok az neden vardır. Optimize ediciler daha kolay okunan kodlarla daha iyi çalışma eğilimindedir. Teorik olarak daha hızlı çalışması gereken, aslında daha uzun sürmesi gereken kısayolları gösteren çalışmalar var. JIT derleyicisi daha iyi çalışır büyük olasılıkla kod küçüktür ve sık çalışma parçaları tanımlanabilir ve optimize edilebilir. Ben denemedim ama nispeten nadiren derlenmemesi denilen büyük bir fonksiyon beklenir.

Bu muhtemelen Java için geçerli değildir, ancak bir çalışma daha büyük işlevlerin farklı bir bellek referans modeli gerektirdiği için daha yavaş çalıştığını buldu. Bu donanıma ve optimize ediciye özgüdür. Daha küçük modüller için bir bellek sayfasında çalışan talimatlar kullanılmıştır. Bunlar, işlev bir sayfaya sığmadığında gereken talimatlardan daha hızlı ve daha küçüktü.

Kodu optimize etmenin değerli olduğu durumlar vardır, ancak genellikle bunun nerede olduğunu belirlemek için kodu profillemeniz gerekir. Sık sık beklediğim kod değil buluyorum.

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.