Neden mikro performansı ve etkinliği önemsemeliyim?


71

C / C ++ sayfalarındaki birçok soru ve cevap, özellikle veya dolaylı olarak mikro performans sorunlarını tartışır (dolaylı veya doğrudan veya satır içi işlevinin tepegözüdür) veya üzerinde bir O (N 2 ) vs O (N log N) algoritması kullanarak 100 öğe listesi.

Her zaman mikro performans konusunda endişe duymadığım ve makro performans konusunda çok az endişe duyduğumda, bakımı kolay, güvenilir kodlar üzerinde odaklanıyorum;

Sorum şu ki, çok sayıda programcının bu kadar umursadığı neden? Gerçekten çoğu geliştirici için bir sorun mu var, bu konuda çok fazla endişelenmenize gerek kalmayacak kadar şanslı mıydım, yoksa kötü bir programcı mıyım?


5
+1, iyi bir genel soru.
iammilind

+1 iyi soru .. Ben 2 etiket ekledi .. umarım sakıncası yoktur.

2
Ben iki harika alıntı yapıyorum 1) "Erken Optimizasyon tüm kötülüklerin kökenidir." 2) Zamanınızın% 80'i kodunuzun% 20'sini harcayacaktır (80/20 kuralı).
James Khoury

2
O (n * n) örneğim hakkında birkaç yanıtın konuştuğunu fark ettim. Açıkça 100 maddelik bir liste belirledim, ancak yine de, O'nun (nlogn) daha iyi olduğuna dair ısrar ediyorlar, eğer daha doğrusu liste 1000'lere veya milyonlara giderse, performans iyileştirmelerini açıkça belirtiyorlar. Bu mikro optimizasyon takıntısı, programcılar gelecekteki gerçek gereksinimlere değil, gerçek geçerli gereksinimlere göre programlama yapıyorlar mı? (Bunu daha önce nerede duymuştum ...)
mattnz

5
@James Donald Knuth'un teklifinin tamamı "Küçük verimleri unutmalıyız, zamanın% 97'sini söylüyoruz: erken optimizasyon tüm kötülüklerin kaynağıdır" dır. Bu konudaki geri kalan% 3 hakkında iyi cevaplar verilecek.
StuperUser

Yanıtlar:


14

Uygulamada, performans nadiren bu ayrıntı düzeyinde yönetilmesi gereken bir konudur. Büyük miktarda veriyi depolayacağınızı ve değiştireceğinizi biliyorsanız, durumu göz önünde bulundurmaya değer, ancak aksi halde haklı ve daha iyi durumdasınız, işleri basit tutacaksınız.

Düşmesi en kolay tuzaklardan biri - özellikle bu kadar ince taneli kontrolün olduğu C ve C ++ 'ta çok erken ve çok iyi seviyede bir optimizasyon yapıyor. Genel olarak kural şudur: A) bir sorununuz olduğunu bulana kadar optimize etmeyin ve B) bir profiler kullanarak sorunlu olduğunu kanıtlamadığınız hiçbir şeyi optimize etmeyin.

B) 'nin bir sonucu olarak şudur: programcılar, performans darboğazlarının nerede olduğunu bilerek bile olsa, bunda iyi olduklarını düşündüklerinde kötüdürler. Bir profilleyici kullanın ve yavaş olan parçaları optimize edin veya bir bölüm kodun çok fazla çağrılması durumunda algoritmaları değiştirin, böylece bir soruna neden olur.


6
Bir diğeri: bir kez çalıştırılan başlatma kodu genellikle optimizasyona ihtiyaç duymaz, bu nedenle başka bir yere bakın.
Mike DeSimone

3
"Bir kez" ne sıklıkta olduğuna bağlı olarak değişir. Çalıştırırken ./configure, ben çalışma süresi% 75'e varan komut çalıştırır programlarında "başlatma" kod harcanan olabilir söylemek girişim olacaktır. % 25-50, dinamik bağlantılara bile harcanabilir.
R.,

12
Kural A, korkunç bir kuraldır. Bir sistemin mimarisi, performansta bir rol oynar ve daha sonra öğrenirseniz, mimariniz, temelde işinize yaramadığınız performans gereksinimlerinizi destekleyemez. Bu yüzden, ince detayları aktarabilmenize rağmen, bunu başlangıçta tamamen görmezden gelmek tamamen yanlış.
edA-qa mort-ora-y

3
@ edA-qa: Ben de öyle düşünürdüm, ancak yıllar geçtikçe, herhangi bir performans kaygısı kaygılanmadan önce birçok projeyi sarsıldı veya başarısız oldu. Performans kaygılarım oldu her zaman, düzeltme karşılaştırmalı olarak düşük maliyetli, günler veya birkaç hafta oldu, başka bir "hata" dan daha fazla endişe geliştirme aşamasında bir d tespit tespit etti. Bununla birlikte, herhangi bir risk unsuru gibi, performans konektörlerinin projenin başlarında tanımlanması ve azaltılması gerekmektedir.
mattnz

5
OP neden bu kadar önemli olduğunu sordu ve OP'nin birisinin "endişelenme!" Dediğini duymakla daha fazla ilgilenmediği sürece, bu cevabın soruyu gerçekten nasıl cevapladığını göremedim.
kırmızı-kir

54

Bence listenizdeki her şey mikro-optimizasyon, genel olarak bakılmaması gerekenler dışında

100 madde listesinde O (n * n) vs O (NlogN) algoritması kullanılması

bence bakmalıyım. Elbette, bu liste şu anda 100 öğe ve her şey küçük n için hızlı , ama yakında aynı kodun birkaç milyon satırlık liste için tekrar kullanılacağına ve hala kodun da sahip olacağına bahse girerim. makul çalışmak.

Doğru algoritmayı seçmek asla bir mikro-optimizasyon değildir. İki ay veya iki yıl sonra aynı kodun hangi tür verileri kullanacağını asla bilemezsiniz. Bir profilleyicinin rehberliğinde kullanımı kolay olan "mikro optimizasyonlar" dan farklı olarak, algoritma değişikliklerinde yeni algoritmaların etkin kullanımı için sıklıkla önemli bir yeniden tasarım gerekir. (Bazı algoritmalar, giriş verilerinin zaten sıralanmasını gerektirir; bu, verilerin düzenli kalmasını sağlamak için uygulamalarınızın önemli bölümlerini değiştirmeye zorlayabilir)


36
"Doğru algoritmayı seçmek asla bir mikro-optimizasyon değildir."

9
Ben de + 1'ledim, ancak veri boyutlarınız küçük olduğundan emin olduğunda big-O-optimal algoritmasının seçilmesinin geliştirme süresi, program boyutu ve hatta hafıza kullanımı için zararlı olabileceğini unutmayın. Poker eli sıralıyorsanız, gerçekten bir hızlı yazım, smoothsort veya birleştirmeortu yazmak ister misiniz? Basit ekleme sıralama ile başlar veya bir sıralama ağı kullanırdım.
R. ..

8
Bu komik. Mikro-optimizasyon hakkında bir başlıkta, birçok yorumcu cevapları mikro-optimize eder. ;)
Güvenli

5
“Yakında bahse girerim ki aynı kod birkaç milyon satırlık bir liste için tekrar kullanılacaktır”: Bu tamamen problem alanına bağlıdır. Örnekler: Eğer bir satranç algoritması yazıyorsanız, tahta boyutunun değişmeyeceğinden emin olabilirsiniz. Özerk bir araç programladığınızda, tekerlek sayısı da o kadar hızlı artmaz.
nikie

3
"Doğru algoritmayı seçmek asla bir mikro-optimizasyon değildir" çünkü "doğru" kelimesinin doğası gereği kesinlikle doğru. Bununla birlikte, ima edeceğiniz şeyin gerçekten "en hızlı veya en verimli" algoritma olduğunu hissediyorum. Uygulanması çok zaman alıyorsa ve bu bölümün hızı veya alanı ne olursa olsun, en etkili algoritmayı seçmek yanlış seçimdir.
Casey Patton

18

Uzun zaman önce bir looooooo, ilk işimde gömülü sistemler için kod yazdım. Bu sistemler 8086 mikroişlemci kullandılar ve hafızası sınırlıydı. Intel C derleyicisini kullandık. Yaptığım bir sistem 3 boyutlu yapılara erişmek için gerekli. Kitabın bana söylediği gibi yaptım: 3 boyut için malloc çağırın, sonra bir sonraki boyut için satırlar tahsis edin, ardından bitiş düğümleri için calloc.

Oldukça karmaşıktı (o zamanlar için), eğri uydurma, ANOVA proses kontrolü ve Ki-kare analizi yapmak zorunda kaldım. Bunu bizim için yapan hiçbir kütüphane yoktu; hepsini yazmalı ve 8086'ya sığdırmalıydık.

Sistem bir köpek gibi koştu. Hızlı bir profilden sonra, en büyük sorunlardan birinin tahsis edici olduğunu keşfettim. Sorunu çözmek için malloc'a yapılan tüm çağrıları bıraktım ve büyük bir hafıza bloğunun kendi hafıza yönetimini yaptım.


Aynı işte bir başka durumda, müşteri istatistiksel süreç kontrol sistemindeki tepki süresinden şikayetçi olmuştur. Benden önceki ekip, operatörlerin sinyalleri ve açma düğmelerini birleştirmek için bir mantıksal mantık kullanabilecekleri "yazılım PLC" sistemini tasarladı. Günümüzde "etki alanına özgü dil" dediğimiz şeyi basitleştirilmiş bir dille yazdılar. hatırladığım kadarıyla ((A1 + B1) > 4) AND (C1 > C2)ve benzeri görünüyordu .

Özgün tasarım, değerlendirildiği her zaman bu dizgiyi çözümledi ve yorumladı. Kızamık işlemcimizde bu çok zaman harcadı ve işlem denetleyicisinin işlem çalıştığı kadar hızlı bir şekilde güncellenemediği anlamına geliyordu.

Ona yeni bir göz attım ve çalışma zamanında bu mantığı montaj koduna çevirebileceğime karar verdim. Bir kez ve sonra her çalıştırıldığında, uygulamayı dinamik olarak oluşturulmuş bir işleve çağırdı. Bugün bazı virüslerin yaptığı gibi, sanırım (ama bilmiyorum; gerçekten bilmiyorum). Sonuç, müşteriyi ve patronumu gerçekten çok mutlu eden performansta 100 kat artış oldu.

Yeni kod neredeyse hiç bakımsız değildi, çünkü özel bir derleyici hazırlamıştım . Ancak performans avantajı bakım dezavantajından ağır basmıştır.


Daha yakın bir zamanda, bir XML sineğini dinamik olarak ayrıştırmak için gereken bir sistem üzerinde çalışıyordum. Büyük dosyalar çok daha fazla zaman alacaktır. Bu çok performans duyarlıydı; ayrıştırmanın çok yavaş olması, kullanıcı arayüzünün tamamen kullanılamaz hale gelmesine neden olur.

Bu tür şeyler her zaman ortaya çıkar.


Yani .... bazen korunabilir, yazması kolay bir kod istersiniz. Bazen hızlı çalışan bir kod istersiniz. Tradeoff, her projede vermeniz gereken mühendislik kararıdır.


9
Tüm örneklerde, daha sonraları optimize etmenin maliyeti, hızlı kodu baştan yazmaktan daha yüksek değildi. Bu nedenle, daha önce daha yavaş kodlar yazmak ve ardından gerektiğinde optimizasyon yapmak, hepsinde iyi çalıştı.
CodesInChaos

6
@CodeInChaos: Cevap aksini iddia etmez. OP'nin “Neden mikro performans ve verimlilikle ilgilenmeliyim?” Sorusuyla konuşuyor. Optimizasyon öncesi konular sadece diğer cevaplayıcılar tarafından çıkarıldı.
webbiedave

12

Büyük görüntüleri işliyor ve her piksele yineleniyorsanız, performans ayarlaması kritik olabilir.


2
+1 - ayrıca, yüksek frekanslı finansman, her türlü ses / video kodlayıcı / kod çözücü, simülasyonlar ve modelleme (örneğin oyunlar), CPU zamanlayıcılar ve bellek yöneticileri gibi sistem çapında bitler
Billy ONeal

3
CAN kritik olabilir, ama IS bunu olmasını ispat ettik sonra sadece kritik ve size sorun olduğunu düşünüyorum nerede olmasını profilli ettik. (İpucu: Muhtemelen orada değil.)
SADECE

2
@Sadece MY doğru görüş: aslında, görüntü işleme için veri işleme genellikle ikinci en büyük zaman tüketicisidir (I / O hala en büyüğüdür). Ancak, G / Ç için optimizasyon yapmak birçok sıradışı / çılgın tasarım ve diğer programcılar tarafından kabul edilmelerini gerektirir ve bazen iyileştirilmesi tamamen imkansızdır. Bununla birlikte, işleme bölümü genellikle paralel olarak paralelleştirilebilirdir, bu nedenle kolayca yeniden elde edilebilir faydaları vardır. (Birinin
çırpması

12

Size kültürün arkasındaki neden hakkında biraz bilgi vereyim .

40 yaşından 20'ye yaklaşıyorsanız ve yetişkinlik yıllarınız boyunca yaşamak için programlama yapıyorsanız, o zaman C ++ gerçekten şehirdeki tek oyun olduğunda, masaüstü uygulamalarının normal olduğu ve donanımın hala çalıştığı bir zamanda bant genişliği / performans yetenekleri açısından büyük ölçüde gecikmeli yazılım.

  • Büyük (> 2G) dosyaları okuyabilmek için aptalca programlama hileleri yapardık ...
  • Çalıştırılabilir büyüklük için endişeleniyorduk ...
  • Programlarımızın ne kadar hafıza kullandığı konusunda endişeliydik ...
  • Uzay takas kararlarına karşı düzenli olarak algoritmik zaman ayırdık ...
  • Hatta arka uçta, biz vardı iyi bir hayır işlemek için herhangi bir şey için CGI C programları veya C ++ yazmak için. RPS ... Daha hızlı birkaç büyüklük emri vardı .
  • Delphi / c ++ / vb arasında performans esası üzerinde testler kullanılırdı!

Bugün çok az insan bu şeyler için endişelenmek zorunda.

Ancak, 10 yıl önce hala 56kb modem üzerinden indirdiğiniz ve 5 yaşında bir PC'de çalıştırılan yazılımınızla ilgili endişeleriniz vardı ... 1996'da ne kadar berbat olduklarını hatırlıyor musunuz? 4GB'lık bir sabit disk, 200MHz işlemci ve 128Mb RAM ...

Ve 10 yıl önceki sunucular? Dell'in "yeni nesil" sunucusu 2000 dolara mal oldu ve 2 (!) 1Ghz pentium işlemci, 2Gb veya Ram ve 20Gb sabit diskle geldi.

Bu sadece farklı bir ballgame idi ve 10 yıllık deneyime sahip (sorularınızı yanıtlama olasılığı olan çocuklar) tüm bu "kıdemli" mühendisler o ortamda dişlerini kesti .


1
Ayrıca, 20 yıllık ek deneyim, birçok kez optimizasyon sürecinden geçen yanık izlerine sahip olduğumuz ve daha sonra ihtiyaç duyabilecek şeyleri yapmaktan kaçındığımız anlamına gelir. Aynı sebepten çekiç kullanırken parmağımı (çok) şapırdatmam.
Blrfl

1
Gevşetme döngü <shudder>
kırmızı-kir

5
ve bugün bant genişliği, işlemci ve bellek sınırsız olduğunu düşünen tüm çocuklar mobil uygulamalarının çok iyi çalışmadığını buluyorlar.
gbjbaanb

9

Burada zaten 10 cevap var ve bazıları gerçekten iyi, ama bu benim kişisel evcil hayvanlarımdan biri ...

a) basit bir çözümden çok daha fazla zaman alan b) optimizasyonu, b) basit çözümün yarı büyüklükte olduğu ve karmaşıklığın yarısı olacağı ve c) daha az okunabilir hale geldiği daha fazla kod ortaya çıkarır. Bununla birlikte, bir geliştirici std :: map veya std :: vector kullanmak arasında bir seçeneğe sahipse ve erken optimizasyondan daha kötü olmasa bile performans için saf cehaletten yanlış bir koleksiyon seçer. Bugün kodunuzu biraz değiştirebilir, okunabilirliği koruyabilir, aynı karmaşıklığı koruyabilir, ancak daha verimli hale getirebilirseniz ne yapardınız? Yoksa buna "erken optimizasyon" mu diyorsun? Bir çok insanın böyle bir düşünceyi bir şekilde vermeyeceğini biliyorum.

Bir zamanlar çok az değişiklik gerektiren "mikro-optimizasyon" öneren bir adam oldum ve bana "Çok erken optimizasyon yapmamanız gerektiğini söylediğin cevabı verdim. Sadece işe koyulalım ve değiştirelim" Daha sonra performans sorunu varsa ". Düzeltmeden önce birkaç sürüm aldı. Ve evet, bu bir performans sorunuydu.

Erken optimizasyon iyi olmasa da, insanların bu kodun ne yapacağını anlayarak kod yazması ve “O” (x) gösterimi ile sonuçlanan herhangi bir soruyu "optimizasyon" olarak göz ardı etmemesinin çok faydalı olacağını düşünüyorum. Şu anda yazabileceğiniz birçok kod var ve performans hakkında biraz düşünerek yolun aşağısında sorunların% 80'ini önlüyorsunuz.

Ayrıca, çevrenizde pek çok performans sorununun yaşanmayacağını ve hemen gerçekleşmeyeceğini göz önünde bulundurun. Bazı zamanlarda limiti zorlayan bir müşteriniz olur veya başka bir geliştirici çerçevenizin üstüne çıkmaya ve nesne sayısını 10 kat artırmaya karar verir. Şimdi performans hakkında bir miktar düşünceyle, daha sonra çok pahalı bir şekilde yeniden tasarlamayı önleyebilirsiniz. Ve eğer yazılım resmi olarak yayınlandıktan sonra sorun tespit edilirse, basit bir düzeltme bile uygulanması 20 kat daha pahalı hale gelir.

Sonuç olarak, performansı her zaman akılda tutmak iyi alışkanlıklar geliştirmeye yardımcı olur. Bu kadar temiz, mümkün olduğunca basit ve düzenli kod yazmak için önemlidir.


+1: Bu, Shrinkwrap yazılımı ve Ticari web siteleri geliştirmek için kiralananlar için istihdam edilebilirlik faktörlerinden biridir . Önleme, müşterinin lanetinden daha az maliyetlidir.
rwong

6

Gördüğünüzün çoğunun basit örnekleme hatası olduğundan şüpheleniyorum. İnsanlar basit durumlarla uğraşırken, kod yazarlar ve bu işlerin sonu. İyileştirme ihtiyacı gibi, özellikle de optimizasyona ihtiyaç duyulmasının zorunlu olmadığı açık bir durumda olduğu gibi, nispeten zor bir şeyle uğraşırken sorular soruyorlar.

Bu, şüphesiz de dahil olan bazı erken optimizasyonlar olduğunu söyledi. Doğru ya da başka türlü, C ve C ++, gerçekten de ihtiyaç duydukları kadar zevk almak için optimizasyon yapabilenler de dahil olmak üzere, performansı önemseyen insanları cezbetme eğiliminde olan bir performans ününe sahiptir.


1
+1 - Not: "performans" etiketli çoğu SO sorusu muhtemelen bu örnekleme hatasının bir parçası: P
Billy ONeal 11:11

3
Emin bkz lanet şey o hobisi programcılar bir çok oyun yazımında fikri ile başlamak olmasından kaynaklanır ve saçma büyük korpus var sanırım ... Burada erken optimizasyon sorulardan "optimizasyonu" kitap ve Yeni başlayanların kafalarına kötü fikirler getiren oyun geliştirme ile ilgili web siteleri. :-)
R ..

4
i++++i
Zor bir

@ Carson63000: evet, örnekleri tamamen yamurabilir. Ya da neden operator ++derlemediğime dair soruları yanıtlamak için zaman harcıyorlar .
rwong

4

Diğer yanıtların bir kısmı gömülü sistemlerden bahsediyor ve bu konuda genişlemek istiyorum.

Örneğin, düşük kaliteli işlemcileri içeren birçok cihaz var, örneğin: evinizdeki kazan kumandası veya basit bir cep hesap makinesi veya modern bir otomobilin içindeki düzinelerce cips.

Paradan tasarruf etmek için, bunlar yalnızca PC veya akıllı telefonlar için kod yazanlar için küçük görünen flaş (kodları saklamak) ve RAM olabilir. Güçten tasarruf etmek için nispeten düşük saat hızlarında çalışabilirler.

Örnek vermek gerekirse, STM32 mikrodenetleyici ailesi 24 MHz, 16 KB flaş ve 4 KB RAM , 120 MHz, 1 MB flaş ve 128 KB RAM'e kadar uzanır .

Bu gibi çipler için kod yazarken, kodunuzu elbette mümkün olduğu kadar verimli hale getirmeyi amaçlıyorsanız, çok zaman kazandırır. Açıkçası, erken optimizasyon kötü bir fikir olmaya devam ediyor; ancak pratikte, ortak sorunların hızlı ve / veya minimum kaynaklarla nasıl çözülebileceğini öğrenir ve buna göre kodlar.


1
gömülü sistemler için göz önünde bulundurulması gereken iyi noktalar, kendimde çalıştığım bir alan. Bunu akılda tuttuğum halde, yıllar boyunca edindiğim deneyimler yanlış yönlendirilmiş optimizasyonun her zaman zaman kaybı olduğudur. Bize rehberlik edecek araçlar olmadan sorunlu alanları nadiren buluruz
Jeff

2

Bir zamanlar% 99 fark olmaz bir detay neden olan patolojik bir performans kasanın içine çalıştırdığında Bunlar, esasen düşük seviyeli dilleri olmak darboğaz, bir gerçek doğrudan diğer birçok farklı olarak (soruna geçici fırsatına sahip Diller); ama elbette, çoğu zaman, en etkili şekilde nasıl yapılacağı hemen belli değil. Bu yüzden garip / ilginç mikro-optimizasyon sorularının yarısı burada sordu.

Diğer yarısı metale ne kadar yaklaşabileceklerini merak edenlerden geliyor. Sonuçta bunlar aslında düşük seviyeli diller ...


+1: Dil veya platformdan bağımsız olarak, "patolojik performans" ın dünyadaki herhangi birinin başına gelebileceğini göstermeye değer. Sökme testi ve okunması için daha düşük seviyeli bir dilde yeniden uygulama yeteneği daha fazla fikir verebilir , ancak her zaman uygulanabilir bir çözüm sunmaz. Örnek: "Montajda yapabileceğimi biliyorum - ancak kısmi güven ortamında çalışması gerekiyor!"
rwong

2

C ve C ++ ile uğraşırken performans her zaman sıcak bir konudur. Kişinin ne kadar ileri gitmesi gerektiğine ilişkin olarak, ASM'yi satır içi noktaya kadar çıldırtabilir veya daha hızlı yineleme için işaretçi aritmetik kullanabilirsiniz. Ancak, genel programın geliştirilmesi üzerinde çalışmanın durma noktasına geldiği için optimizasyonun çok zaman harcadığı bir nokta var.

Bu konularla uğraşırken, programcının performansı ve kod performansı var. Bunlardan hangisine odaklanacağınız her zaman ilginç sorular getirir. Sonunda en önemli soru, kullanıcıya ne kadar belirgin olduğu. Kullanıcı yüzlerce veya binlerce öğeden oluşan diziler oluşturan verilerle çalışacak mı? Bu durumda işleri hızlı bir şekilde yapmak için kodlama yapmak, kullanıcının programın standart işlemlerinin yavaş olduğundan şikayet etmesine neden olabilir.

Sonra az miktarda veriyle çalışacak olan kullanıcı var. Sıralama ve dosya işlemleri gibi şeyleri yapmak, bazı performansların maliyetini korumanızı kolaylaştıran daha yüksek seviyeli fonksiyonlar kullanıyorsanız, kullanıcı için farkedilmez.

Bu, karşılaşacağınız sorunların sadece küçük bir örneğidir. Diğer konular, hedef kullanıcının donanımını içerir. Gömülü sistemlerle uğraşırsanız performans hakkında daha fazla endişe duymanız gerekecek, o zaman kullanıcılarınız koçluk içeren çift çekirdekli makinelere sahiplerse.


Hmm .. Daha hızlı yineleme için işaretçi aritmetik kullanmıyorum - endeks tabanlı mı yoksa işaretçi tabanlı yineleme mi kullanıyorsanız döngü başına komut ekleyin. Yine de kullanıyorum, çünkü genellikle dizin tabanlı yinelemeden daha açıktır.
Billy ONeal

imleç aritmetiği w / e'den daha hızlı değildir.

2

Programcılar neden bu kadar önemsiyorlar? Başlarını doldurmak gibi aptalca fikirler vardır, örneğin performans problemlerini kendilerinin olduğunu bilmeden önce çözmek ve ne zaman tahmin ettiklerini anlamak gibi .

Bu çok zor, çünkü deneyimlerime göre, vaktinden önce düşünülmesi gereken bazı performans sorunları var . Ne olduklarını bilmek deneyim gerektirir.

Bu, kullandığım yöntem seninkine benzer, ancak aynı olmadığını söyledi:

  1. Mümkün olan en basit tasarımla başlayın. Özellikle, veri yapısı mümkün olduğunca normal ve minimal olmalıdır. Kaçınılmaz fazlalık olması durumunda, tutarlılığı sağlamanın bir yolu olarak bildirimlerden utangaç olmalıdır. Geçici tutarsızlığa tahammül etmek ve periyodik bir süreçle tamir etmek daha iyidir.

  2. Program geliştirilme aşamasındayken, periyodik olarak performans ayarlaması yapın, çünkü performans sorunlarının sessizce sürünmesini sağlar. Kullandığım yöntem rastgele duraklatmadır , çünkü bunun en iyisi olduğunu düşünüyorum.

İşte ne demek istediğimin bir blow-by-blow örneği .


1

Dürüst olmak gerekirse, amacınız ne olduğuna ve profesyonelce mi yoksa hobi olarak mı programladığınıza bağlıdır.

Günümüzde modern bilgisayarlar gerçekten güçlü makinelerdir. Hangi temel işlemleri yapmaya karar verdiğinize bakmaksızın, mikro optimizasyon yapmaya çalışsanız da yapmasanız da, işlerini oldukça hızlı bir şekilde yapabilirler. Ancak elbette, başka bir şey yapıyorsanız (örneğin, fizik veya kimya gibi alanlar için süper hesaplama), istediğiniz kadar optimize etmek isteyebilirsiniz.

İlk MIT programcıları harika şeyler yapmak için doğmamışlardı; Mevcut algoritmaları basitleştirmeye ve güçlendirmeye başladılar. Gururları 2 + 2'yi mevcut algoritmadan iki saniyede dörde vermekti (bu sadece bir örnek, fikrin var). Performans için TI-83 makinelerinde sürekli olarak daha az deliksiz kart kullanmaya çalıştılar.

Ayrıca, gömülü sistemler için programlama yapıyorsanız, o zaman kesinlikle mikro performansa göz kulak olmanız gerekir. Başka bir dijital saatten daha erken bir ikinci 5 nanosaniyeyi işaretleyen yavaş bir dijital saat istemezsiniz.

Son olarak, eğer bir hobi programcısıysanız, programınız hızlı olsa bile en küçük ayrıntıların optimize edilmesinde kesinlikle bir zararı yoktur. Gerek yok, ama kesinlikle üzerinde çalışabileceğiniz ve daha fazla bilgi edinme şansını yakalayabileceğiniz bir şey. Bir yazılımda profesyonelce çalışıyorsanız, fazlasıyla ihtiyaç duyulmadıkça bu lüksü alamazsınız.


1
Hobisi olan bir programcı olmanın bununla bir ilgisi olduğunu sanmıyorum. Sırf profesyonelce bir şey yapmamanız, dünyada harcayacağınız her zaman olduğu anlamına gelmez. Dahası, çoğu hobi uzmanı, yanlış algoritmaları seçmek gibi çoğu gerçek profesyonelin yapabileceğinden daha büyük hatalar yapacak. Dahası, profesyonel muhtemelen hobiden önemli ölçüde daha fazla veri işleyen (bu nedenle daha hızlı olması gereken) ve müşterilerin uygulamanın performansından memnun kalması gereken bir ürün üzerinde çalışıyor. Hobilerin bu gibi kısıtlamaları yoktur.
Billy ONeal

Olmazlar, ancak kesinlikle isterlerse üzerinde çalışacak daha çok zamanları vardır.

3
Ben tam tersini tartışırdım. Bir profesyonel olarak çalışmak için günde 8 saat veya daha fazla zamanım var. Hobilerim için günde 1, belki 2 saat alıyorum.
Billy ONeal

1

100 madde listesinde bir O (N2) vs O (NlogN) algoritması kullanılmıştır.

Son zamanlarda benzer bir durumdaydım. Bir dizi öğem vardı. Beklenen durumda, listede iki (!) Madde vardı ve en kötü durumda bile dört veya sekizden fazla beklemiyorum.

Bu listeyi sıralamam gerekiyordu. Yerine çıkıyor std::sortbir sıralama ağı (iç içe esasen bir çok ile ifçalışma süresi (ı numarayı hatırlamıyorum ama% 10-20 gibi bir şey oldu) büyük bir yüzdesini tıraş s). Bu, bir mikro optimizasyonun büyük bir avantajı ve kod kesinlikle performans açısından kritik.

Tabii ki, sadece profilden sonra yaptım . Fakat mesele şu ki, C ++ kadar uygunsuz ve anlaşılır bir dil kullanırsam (aşırı yüklenme çözümünde çılgınca karmaşık kurallarından bahsetmiyorum), o zaman tam olarak faydalanmak isterim.


1

Birikimli enerji kullanımı

Bu tartışmadan her zaman eksik olduğunu düşündüğüm ve beni biraz kümülatif enerji kullanımı için rahatsız eden bir cevap var .

Tabii, belki de programınızı yüksek düzeyde yorumlanmış bir dilde yazmanız ve birkaç kat dolaylı tarayıcıya sahip bir tarayıcıda çalışmasına izin vermeniz ya da döngünüzün 0,001 saniye yerine 0,01 saniye sürmesi önemli değildir. Kimse farketmeyecek, yani bireysel kullanıcılar farketmeyecek.

Ancak, bazı durumlarda on binlerce, hatta milyonlarca kullanıcı kodunuzu kullandığında, tüm bu ekstra verimsizlik ekler. Eğer aletiniz bir işlemcinin günde sadece on saniye uyku moduna girmesini engelliyorsa ve bir milyon kullanıcı bunu kullanıyorsa, verimsiz algoritmanız günde fazladan 140 kWh [1] harcadı .

Bu tartışılan nadiren görüyorum ve bunun üzücü olduğunu düşünüyorum. Firefox ve popüler interaktif web uygulamaları gibi popüler çerçeveler için rakamların çok daha kötü olduğundan şüpheliyim ve araştırmanın ilginç olacağını düşünüyorum.


[1] Daha yeni yaptım, 10 milyon saniye çarpı 50 Watt. Kesin rakam birçok şeye bağlıdır.


1
Hemen "mobil" kelimesini söyleyerek başlamalısın. Bir masaüstü platformunda çalışırken, saniyede 60 kez bir kare çizmek için 1 / 100sn CPU zaman alan bir uygulama "yeterince hızlı" olacaktır; performans on katının iyileştirilmesi, kullanıcı için sıfır fark yaratacaktır. Bununla birlikte, mobil bir platformda,% 90 CPU kullanımıyla çalışan bir uygulama, pilleri% 10'dan daha hızlı çalıştırabilir.
Supercat,

1

Bazen sadece, hala güçlü bir performans talebi olan doğrusal zamandan daha iyi olamaz algoritmaları vardır.

Bir örnek, bir görüntüyü / kareyi her piksele döngü yapmadan temel bir örnek olarak daha parlak yapamayacağınız video işlemedir (sanırım, sonuçta görüntü kiremitlerine inen çocuklar tarafından miras alınan özellikleri gösteren bir tür hiyerarşik yapıya sahip olabilirsiniz. yaprak düğümleri için, ancak daha sonra, her pikselin oluşturucuya çevrilmesi için daha yüksek bir döngü maliyeti ertelersiniz ve kod muhtemelen en mikro-optimize edilmiş görüntü filtresinden bile daha zor olacaktır).

Alanımda bunun gibi birçok dava var. Her türlü dokunmaya ya da her türlü karmaşık veri yapısından ya da algoritmasından yararlananlara göre her şeyi okumak zorunda olan daha fazla doğrusal-karmaşıklık döngüsüne girme eğilimindeyim. Her şeye dokunulması gerektiğinde atlanabilecek bir iş yok. Bu noktada, kaçınılmaz olarak doğrusal karmaşıklıkla uğraşıyorsanız, yineleme başına yapılan işi daha ucuz ve daha ucuz hale getirmelisiniz.

Bu nedenle benim durumumda en önemli ve ortak optimizasyonlar genellikle veri sunumları ve hafıza düzenleri, çoklu okuma ve SIMD'dir (tipik olarak bu sırayla, ikincisini yapma yeteneğini etkilediği için veri sunumları en önemlisidir). Ağaçlar, karma tablolar, sıralama algoritmaları ve bu tür şeylerle çözülen birçok problemle karşılaşmıyorum. Günlük kodum daha çok “her şey için bir şeyler yap” damarındadır .

Elbette, optimizasyonların ne zaman yapılması gerektiğinden (ve daha önemlisi, ne zaman olmadıklarından), mikro veya algoritmik olarak konuşmak başka bir durumdur . Ancak özel durumumda, kritik bir yürütme yolunun optimizasyona ihtiyacı varsa, 10x + hız kazanımları, çok iş parçacıklı, SIMD ve yeniden düzenlenmiş bellek düzenleri ve gelişmiş referans yeri için erişim düzenleri gibi mikro düzeyli optimizasyonlarla elde edilir. Sıcak / soğuk alan bölmesinden faydalanabilecek sıcak noktalar bulmak kadar, bir kabarcık türünü introsort veya radix türüyle veya kuadratik karmaşıklık çarpışma algılamasıyla değiştirmem pek sık değildir.

Şimdi benim durumumda o kadar çok kritik bir alan var (ışın izleme, fizik motorları, vb.), Bir görüntüyü oluşturmak için 10 saat süren yavaş ama tam olarak doğru bir ışın izleyici genellikle tamamen etkileşimli olandan daha hızlı veya yararsız olarak kabul edilir. su geçirmez ışın / tri kesişme eksikliğinden dolayı her yere sızıntı yapan ışınlarla en çirkin görüntüleri çıkarır. Hız, tartışmasız, bu tür bir yazılımın birincil kalite ölçüsüdür, tartışmasız bir noktaya doğruluktan daha da fazladır (çünkü "doğruluk" her şey yaklaşmakta olduğu için çarpışma ya da benzeri bir şey olmadığından ışınlanma ile bulanık bir fikirdir). Durum böyle olunca, verimliliği önceden düşünmezsem, daha verimli tasarımlarla başa çıkmak için kodu en pahalı tasarım düzeyinde değiştirmek zorunda olduğumu fark ettim. Yani eğer yapmazsam

Oyun benimkine benzer başka bir alandır. Oyun mantığınızın ne kadar doğru olduğu veya kod temanızın ne kadar bakımlı ve zekice tasarlandığı önemli değil. Bazı alanlarda hız eksikliği, uygulamayı kullanıcıları için işe yaramaz hale getirebilir. Oyunlardan farklı olarak, ışın çekme gibi alanlarda "yeterince iyi" bir ölçüm yoktur. Kullanıcılar her zaman daha fazla hız ister ve endüstriyel rekabet ağırlıklı olarak daha hızlı çözümler aramaktadır. Gerçek zamanlı olana kadar hiçbir zaman yeterince iyi olmayacak, hangi noktada oyunların yol izleyicileri kullanacağı. Ve sonra muhtemelen VFX için yeterince iyi olmayacak, çünkü o zaman sanatçılar milyarlarca poligon yüklemek ve 30 + FPS'de milyarlarca parçacık arasında kendi kendine çarpışan parçacık simülasyonlarına sahip olmak isteyebilir.

Şimdi, eğer herhangi bir rahatlık varsa, buna rağmen kodun yaklaşık% 90'ını kodlama dilinde (Lua) yazmaya devam ediyorum. Ancak, milyonlarca şeyden milyarlarca şeye geçmesi gereken olağandışı derecede büyük miktarda bir koda sahibim ve milyonlarcadan milyarlarca şeye geçerken, tek iş parçacıklı saf kod arasındaki epik bir farkı fark etmeye başlarsınız. Her yinelemeyle özlenen bir önbellek çağırır; örneğin, alakasız verilerin önbellek satırına yüklenmediği bitişik bloklara paralel olarak çalışan vektörleştirilmiş kod.


0

Bahsettiğiniz gibi, bu sorunlardan gerçekten kaynaklanan bazı problemleri hesaba katmadan önce mikro performans konularına özen göstermek değersizdir


0

Bu soruyu genel olarak cevaplamak gerçekten imkansızdır. Bugün inşa edilen çoğu yazılım dahili web siteleri ve LOB uygulamalarıdır ve bu tür bir programlama için nedenleriniz oldukça doğru. Diğer taraftan, bir aygıt sürücüsü veya oyun motoru gibi bir şey yazıyorsanız, optimizasyon "erken" değildir; Şüphesiz, yazılımınız farklı donanım kısıtlamaları olan çok farklı sistemlerde çalışacaktır. Bu durumda performans için tasarım yapmalı ve alt-optimal bir algoritma seçmemelisiniz.


Aynen söylemek istediğim şeyi. Her yazılım parçası kendi uygulama alanına sahiptir ve bunun dışında en iyi şekilde davranması beklenmemelidir. Bu anlamda, erken optimizasyon yanlış yönlendirilmiş mükemmeliyetçiliğin bir örneğidir.
K.Steff

0

Bence performansla ilgili çok fazla önem veren programcının problemi, bazen hayatında mikro-performans kodunu, belki de çok acilen kod yazması gerektiğini ve sonunda öğrendiğini, öğrendiğini, öğrendiğini ve sonunda bildiğini çok şey ve püf noktaları.

Ve şimdi unutmak zordur ve önceden bir ölçüm yapmadan endişelenmeye ihtiyacı olmadığını, hızlı kod kullanarak güvenli tarafta olduğunu gösterir.

Derin bilginizi, yeteneklerinizi ve bazı püf noktalarını göstermek ve öğrendiğiniz bir şeyi tekrar kullanmak her zaman güzeldir. Kendinizi değerli hissettirir ve zaman harcamak, harcadığınız paraya değer.

Bazen hayatımda, önek artışının daha hızlı olduğunu öğrendim ...

for (int i = 0; i < MAX; ++i)

... postfix artışından daha:

for (int i = 0; i < MAX; i++)

Şimdi eğer MAX düşükse, farketmez ve döngüde gerçek bir iş varsa, bunun da önemi olmaz. Ancak bugünün derleyicisi kodu kendi başlarına optimize etse bile postfix sürümünü kullanmak için bir neden yoktur.

Belki de performans arayanlar, büyük seçenekler denizinde bir rehbere sahip olmak için 'çalışma kodu' gibi 'çalışma ve okunabilir kod' gibi bir ek hedefe ihtiyaç duyarlar.


0

Çok fazla endişelenmek zorunda kalmayacak kadar şanslı mıydım, yoksa kötü bir programcı mıyım?

Gereksinimlerinizi önemsiyor musunuz? Performans bir gereklilik değilse, endişelenmeyin. Bunun üzerinde önemli bir zaman harcamak, işvereninizin kötüye kullanılmasıdır.

Bir dereceye kadar performans her zaman bir gerekliliktir. Düşünmeden vurabilirsen, düşünmemeye haklısın.

Şahsen, testlerimin uzun sürmesi uzun sürdüğü zaman, çoğunlukla performanstan etkileniyorum. Bir test seti geçerken 5 dakika beklemek için sabırsızlanıyorum. Ancak bu genellikle testlerle uğraşarak çözülür.

Sorum şu ki, çok sayıda programcının bu kadar umursadığı neden? Gerçekten çoğu geliştirici için bir sorun mu var?

Ne kadar önem verdikleri konusunda haklı olan çok sayıda programcı var. Olmayan çok sayıda var. Kim olmayanlar hakkında konuşalım.

Programcıların okulda öğrendikleri ilk şeylerden biri, bir şeylerin gerçekten çalışmasını sağladıktan sonra, büyük O gösterimidir. Birçoğu, dersi düzgün bir şekilde öğrenir ve bu nedenle n'nin dramatik olarak etkilediği şeylere odaklanır. Diğerleri matematiği almaz ve yalnızca işe yaradığında hızlı olması gereken dersi alır. Daha da kötüsü, bu öğrencilerin bazıları, çalışmasını sağlamak ve hızlı çalışmasını sağlamakla birlikte, kodunuzla yapılması gerekenler hakkında hiçbir şey öğrenmez. Kaçırılan dersler: okunabilir hale getirin, iyi tasarlayın, sebepsiz yere oynamayın.

Knuth haklıydı: erken optimizasyon tüm kötülüklerin köküdür. Fakat işe yaradığında bir sonraki adım nedir? Hızlı değil mi? HAYIR! Bir sonraki adım okunabilir. Okunabilir, ilk, sonraki, orta ve son adımdır. Gereksiz performans optimizasyonları yaparken bulduğum insanların çoğu otobüsün altında okunabilirlik atıyor.

Hatta bazıları kodlarının okunaksız olmasından sapık bir heyecan duyuyorlar. Başkaları tarafından oluşturulan kodu anlamak için çok uğraşmak zorunda kaldılar, bu yüzden artık geri dönüşleri sırayla.

Bunu biliyorum çünkü bunu yapardım. Bir zamanlar yapılamaz bir satır boolean ifade yapılamazsa ve bu kadar küçük ve korkutucu bir şey yaratabildiğim için etkilemek için beklediğim profesöre gururla gönderirseniz, mükemmel bir şekilde okunabilir 5 satır yeniden kırdım. Umduğum övgüyü alamadım.

Kod okunabilir kalırsa, daha sonra hızlı yapmak kolaydır. Bu yüzden Knuth, “gereksiz” olmayan “erken” vurguyu vurgulamaktadır. Çünkü tabi ki daha hızlı iyidir. Ama daha iyisi, bunun için feda ettiğinize bağlı olarak daha iyidir. Bu yüzden, gerçekten fedakarlık yapmadan önce hangi performansın gerekli olduğunu öğrenene kadar bekleyin. Okunabilirliği gönülsüzce feda edin çünkü bir kez gittiğinde geri dönmek zordur.

Okunabilirliğin ötesinde, yazılım tasarımının bütün dünyasıdır. Bu site neyle ilgili. Bazılarının tasarım kadarıyla ne yapılacağına dair hiçbir fikri yoktur. Bu yüzden, tasarımları etkileyemedikleri için çözülemez bir karışıklık yaratırlar, böylece insanlar hiçbir ipucu olmadığını söyleyemezler. Hiç kimse kodunu düzelttiği için iyi bir kod olmalı mı?

Bazıları için performans, istediklerini yapmak için tüm bahaneleri yakalamaktır. Programcılar çok fazla güç ve özerkliğe sahiptir. Onlara güven verilmiştir. Güveni kötüye kullanma.

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.