Neden çok erken optimizasyon yapmak bu kadar kötü?


168

Optimizasyona biraz baktıktan sonra, bir oyunu çok erken optimize etmek için evrensel olarak kabul edilmiş bir günah gibi göründüğünü keşfettim (tam anlamıyla her yerde).

Bunu gerçekten anlamıyorum, akılda performans ile ilk kez onları geliştirmek yerine, oyunun çekirdek yapılarının bazılarını değiştirmek inanılmaz derecede zor olmaz mıydı?

Oyun bitene kadar beklememin size optimizasyona ihtiyacınız olup olmadığını söyleyeceğim, ama yine de yapmamalı mıydınız, sonuçta oyunun çalıştığı cihaz çeşitliliğini artırabilir, bu da potansiyel sayısını artırabilir oyuncular.

Birisi bana neden bu kadar erken optimizasyon yapmanın bu kadar kötü bir fikir olduğunu açıklayabilir mi?


Yorumlar uzun tartışmalar için değildir; bu konuşma sohbete taşındı .
Josh

3
Buna cevap vermek daha kolay olamazdı: "zaman harcıyor". "Alışveriş yaparken neden para biriktirmeyi denesin?" Diye sorabilirsiniz.
Fattie

27
Bunun tersine, birçok mühendisin sadece "çok yakında optimizasyon yapmayın" cümlesinin kesinlikle yanlış olduğunu söylediklerini unutmayın . Cümle, basitçe, "neyi optimize edeceğinizi bilene kadar optimize etmeyin" olmalıdır. Yani, basitçe, eğer üç A, B ve C sistemi varsa, A, herhangi bir şekilde bir darboğaz olmadığında ve C aslında darboğaz ise, tamamen anlamsız bir şekilde A'yı optimize eder. Bu örnekte, açıkça, A'nın optimizasyonu çok zaman kaybı olabilirdi. Yani - oldukça basit - optimize etmek için A, BC hangisini öğrenene kadar optimize etmeyin : hepsi bu, bu kadar basit.
Fattie

2
Geliştirme sırasında uygulamanızın zaman sınıfını optimize etmek, genellikle sabit zaman olan bir döngüden birkaç talimatı traş etmeye çalışmaktan çok farklıdır. Odaklanma yerine O (n) - O (n log n) yerine "bu şekilde bir for döngüsü yazmak bir CPU komutunu kaydeder".

1
@phyrfox Aslında, yükleme süresini azaltmak benim için daha etkileyici görünüyor. Üç saniye yükleme süresi göze çarpıyor. 55fps ile 60fps arasında bir fark olup olmadığından emin değilim.
immibis

Yanıtlar:


237

Önsöz:

Yorumlarda bazı itirazlar gündeme geldi ve bence büyük ölçüde “erken optimizasyon” dediğimizde ne demek istediğimizin yanlış anlaşılmasından kaynaklanıyor - bu yüzden biraz açıklama yapmak istedim.

Yok "zamanından önce optimize etmeyin" değil "Knuth sonuna kadar bunu temizlemek izin yok diyor çünkü, biliyorsunuz yazma kodu kötü" demek

"Programınızın hangi bölümlerinin daha hızlı olması için gerçekten yardıma ihtiyacı olduğunu bilene kadar optimizasyon için zaman ve okunaklılıktan ödün vermeyin." Tipik bir program zamanının çoğunu birkaç darboğazda geçirdiğinden, "her şeyi" optimize etmeye yatırım yapmak, aynı darboğaza sadece bu darboğaz koduna odaklanmakla aynı hızda artış getiremez.

Bu, şüphe durumunda , biz yapmalıyız:

  • Yazması kolay, anlaşılması kolay ve yeni başlayanlar için değiştirmesi kolay kodu tercih edin

  • Daha fazla optimizasyonun gerekip gerekmediğini kontrol edin (genellikle çalışan programı profilleyerek, aşağıdaki yorumlardan biri matematiksel analiz yapıldığını not eder - buradaki tek risk aynı zamanda matematiğinizin doğru olup olmadığını kontrol etmenizdir)

Bir erken optimizasyon değil :

  • Kodunuzu gereksinimlerinize göre ölçeklendirecek şekilde yapılandırmaya yönelik mimari kararlar - uygun modülleri / sorumlulukları / arayüzleri / iletişim sistemlerini dikkate alarak seçin.

  • Ekstra zaman almayan veya kodunuzu okumayı zorlaştıran basit verimlilik. Güçlü yazmayı kullanmak gibi şeyler hem verimli olabilir hem de amacınızı daha net hale getirebilir. Bir başvuruyu art arda aramak yerine önbelleğe almak başka bir örnektir (durumunuz karmaşık önbellek geçersiz kılma mantığı gerektirmediği sürece - belki de önce basit yolu ilk seçene kadar yazmaya devam edebilirsiniz).

  • İş için doğru algoritmayı kullanmak. A * ayrıntılı bir yol bulma grafiği aramaktan daha uygun ve daha karmaşıktır. Aynı zamanda bir endüstri standardı. Temayı tekrarlamak, bunun gibi denenmiş ve doğru yöntemlere bağlı kalmak, kodunuzu anlaşılması daha kolay bir şey yapmaktan ziyade bilinen en iyi uygulamalara karşı koymaktan daha kolay hale getirebilir. Önceki bir projede X oyun özelliğini uygulayan darboğazlara girme konusunda deneyiminiz varsa, bunun gerçek olduğunu bilmek için bu projede aynı tıkanıklığa tekrar basmanız gerekmez - geçmiş için çalışmış olan çözümleri tekrar kullanabilirsiniz oyunlar.

Tüm bu tür optimizasyonlar haklı çıkmıştır ve genellikle "erken" olarak etiketlenmezler (8x8 satranç tahtası haritanız için en son yol bulma özelliğini kullanan bir tavşan deliğinden aşağıya inmezseniz ...)

Öyleyse şimdi, bu politikayı neden oyunlarda özellikle yararlı bulabileceğimizi açıkladı :


Özellikle gamedevde, yineleme hızı en değerli şeydir. Genellikle "eğlenceyi bulmaya" çalışırken bitmiş oyunla birlikte gönderilenden çok daha fazla fikri uygular ve yeniden uygularız.

Bir tamirciyi basit ve belki de biraz saf bir şekilde prototip edebilir ve ertesi gün tekrar deneyimleyebilirsiniz, bir haftayı en iyi halini almak için ilk haftaya ayırdığınızdan çok daha iyi bir durumdasınız demektir. Özellikle emmek için çıkıyor ve sonunda bu özelliği atıyorsanız. Erken test edebilmeniz için basit bir şekilde yapmak, saklamadığınız bir sürü boşa harcanan iş optimizasyon kodundan tasarruf etmenizi sağlar.

Optimize edilmemiş kodun değiştirilmesi ve farklı değişkenlerin denenmesi genellikle daha kolaydır, bu özellik, en iyi şekilde kesin bir şekilde yapılması için ince ayarlanmış olan koddan farklıdır; bu, kırılmadan, hata vermeden veya yavaşlatılmadan değiştirilmesinin zor ve kırılgan olma eğilimindedir. Bu nedenle, kodu basit ve değiştirmesi kolay tutmak, çoğu geliştirme aşamasında (genellikle hedef spesifikasyonun üzerindeki makineler üzerinde çalışıyoruz, bu nedenle ek yükü absorbe edip önce hedef deneyimi edinmeye odaklanabiliyoruz), çalışma süresinin yetersiz olmasına değiyor. Bu özellikten ihtiyacımız olanı kilitledim ve artık bildiğimiz parçaları yavaşlatabiliriz.

Evet, yavaş noktaları en iyi duruma getirmek için projenin geç dönemlerinde yeniden yapılanma çalışmaları zor olabilir. Ancak bu, gelişim boyunca sürekli yenileniyor, çünkü geçen ay yaptığınız optimizasyonlar oyunun o zamandan beri gelişen yönüyle uyumlu değildi veya daha fazla özellik ve içeriğe sahip olduğunuzda gerçek darboğaz olmadığı ortaya çıkan bir şeyi düzeltti. içinde.

Oyunlar tuhaf ve deneyseldir - bir oyun projesinin ve teknik gereksinimlerinin nasıl gelişeceğini ve performansın en sıkı nerede olacağını tahmin etmek zordur. Uygulamada, çoğu zaman yanlış şeyler hakkında endişelenmeye başlıyoruz - buradaki performans sorularını araştırın ve muhtemelen bir sorun olmayan kağıttaki şeylerin dikkatinin dağılmasıyla ortaya çıkan ortak bir tema göreceksiniz.

Dramatik bir örnek almak gerekirse: Oyununuz GPU'ya bağlıysa (nadir değildir), o zaman hiper optimizasyon ve işlem yapmak için harcanan zamanın tamamı CPU çalışmasını somutlaştırır. Tüm bu dev saatler, daha iyi bir oyuncu deneyimi için oyun özelliklerini uygulamak ve parlatmak için harcanmış olabilir.

Genel olarak, bir oyunda çalışmak için harcadığınız zamanın çoğu, tıkanıklık haline gelen kod için harcanmaz. Özellikle mevcut bir motor üzerinde çalışırken, renderleme ve fizik sistemlerindeki süper pahalı iç döngü malzemesi büyük ölçüde elinizin altında. Bu noktada, oyun senaryolarındaki işiniz temelde motorun yolundan uzak durmaktır - oraya bir İngiliz anahtarı atmadığınız sürece, ilk inşa için muhtemelen oldukça iyi bir şekilde çıkacaksınız.

Bu nedenle, bir miktar kod hijyeni ve bütçelemesinin dışında (örneğin, tekrar tekrar kullanabiliyorsanız, bunları tekrar aramayın / yapmayın, yol bulma / fizik sorgularınızı veya GPU geri okumalarını mütevazı tutun), bitmemeyi alışkanlık haline getirin - gerçek sorunların nerede olduğunu bilmeden önce verimliliği arttırmak için en iyi duruma getirme - yanlış şeyleri optimize etmek için zaman kaybetmemize ve genel olarak kodumuzu daha basit ve kolay tutmamıza yardımcı olur.


38
Burada StackOverflow ile ilgili daha fazla tartışma var , kodda okunabilirlik ve açıklığın önemini ve zamanından önce optimizasyon yaparak kodun anlaşılmasını zorlaştırmanın (ve bunun içine böceklerin sokulmasını kolaylaştırmanın) zorlaştırılması tehlikesi vurgulandı.
DMGregory

8
Büyük cevabım, " ilk kez akılda tutularak ilk kez geliştirmek yerine, oyunun çekirdek yapılarının bazılarını değiştirmek inanılmaz derecede zor olmaz mıydı? " Diye de eklemek isterim . Tabii ki, her şeyden önce verimlilik için tasarım yapmaya çalışıyorsunuz. İki seçenekle sunulduğunda, daha verimli olanı seçersiniz. Bunu başaramazsanız, oyunu iyi tanımlanmış arayüzlerle mümkün olduğunca modüler olarak yazarsınız. Kod modülünün tamamını yeniden yapılandırmadan her modülün içindeki mekanizmaları değiştirebilirsiniz.
Baldrickk

1
@Baldrickk Ek bir cevap olarak paylaşmaya değeceğini söyleyebilirim. (Ben bunu affederim!) Cevabım, her şeyden önce büyük sorunlar yaratmamak için mimarlığın ve planlamanın önemine değiniyor. Gizmo'nun “genel olarak program geliştirme” konusuna gelince, bu erken optimizasyon kavramının geldiği yer burasıdır. Yukarıda belirtildiği gibi, yanlış optimizasyon, eksik bir optimizasyon kadar kolay bir şekilde teknik borç haline gelebilir. Ancak, işleri asla kasten yavaş bir şekilde yapmadığımızı vurgulamalıyız, asıl meseleleri belirleyene ve bulana kadar basitliği ve okunaklılığı tercih ediyoruz
DMGregory

1
Muhtemelen burada sizlerden en deneyimsiz biri olduğum halde, şunu söylemeliyim ki, bu "tüm kötülüklerin erken optimizasyon kökü" biraz garip. İki yıl önce Unity3D'de bir şeyler yapmaya çalışıyordum. Her biri öncekini kullanan birkaç LINQ sorgusu yazdım. Koduma baktım ve güçlü şüpheler almaya başladım. Hesaplama karmaşıklığının korkunç olduğunu düşündüm. Bir kağıt tuttum ve bu sorguları beklenen veri boyutunda işlemenin saatler alacağını hesapladım. Bu yüzden orada ve orada biraz önbellekleme ekledi. Ve sorgular iyi gidiyordu.
gaazkam

3
Bu nedenle, titizlik gösterdiniz ve kodunuzu başlangıçta sizin için en net ve en sezgisel olandan değiştirmeden önce sorunun gerçek olduğunu doğruladınız. Bu, optimizasyonunuzun erken olmadığı anlamına gelir. ;) "Erken doğmaktan kaçınmaktan kaçınmak", "gereksiz yere pahalı kod yazmak" anlamına gelmez - yalnızca basitlik, okunaklılık, kesin bir performans sorunu belirleninceye kadar değişiklik kolaylığı için kullanılır. Yorumlar tartışma amaçlı değildir, bu nedenle daha fazla konuşmak isterseniz sohbete geçebiliriz.
DMGregory

42

not: bu cevap DMGregory'nin cevabı üzerine bir yorum olarak başladı ve bu yüzden yaptığı çok iyi noktaları kopyalamıyor.

“Oyunun temel yapılarının bazılarını, akılda tutulacak performans ile ilk kez geliştirmek yerine sonunda değiştirmek inanılmaz derecede zor olmaz mıydı?”

Bu, bana göre, sorunun özüdür.

Orijinal tasarım oluştururken, gereken verimlilik için dizayn deneyin - Üst düzeyde. Bu daha az optimizasyon ve yapı hakkında daha fazla.

Örnek:
Bir nehri geçmek için bir sistem yaratmanız gerekiyor. Açık tasarımları bir köprü veya feribottur, hangisini seçersin?
Elbette cevabı, geçişin büyüklüğüne ve trafik hacmine bağlıdır. Bu bir optimizasyon değil, bunun yerine sorununuza uygun bir tasarımla başlamak.

Tasarım seçenekleri ile sunulduğunda, yapmak istediklerinize en uygun olanı seçersiniz.

Yani, trafik hacmimizin oldukça düşük olduğunu söyleyelim, bu yüzden iki terminal inşa etmeye ve trafiği idare etmek için bir feribot satın almaya karar veriyoruz. Güzel ve basit bir uygulama
Ne yazık ki, bir kez çalıştırıp çalıştırdıktan sonra, beklenenden daha fazla trafik gördüğünü görüyoruz. Vapuru optimize etmeliyiz! (çünkü işe yarıyor ve şimdi bir köprü inşa etmek iyi bir plan değil)

Seçenekler:

  • İkinci bir feribot satın al (paralel işleme)
  • Feribotlara başka bir araç güvertesi ekle (trafiğin sıkıştırılması)
  • Daha hızlı hale getirmek için feribotun motorunu yükseltin (yeniden işleme algoritmaları)

Orijinal tasarımınızı mümkün olduğunca modüler hale getirmeye çalışmanız gereken yer burasıdır.
Yukarıdakilerin hepsi olası optimizasyonlardır ve üçünü de yapabilirsiniz.
Peki bu değişiklikleri büyük yapısal değişiklikler olmadan nasıl yapıyorsunuz?

Açıkça tanımlanmış arayüzleri olan modüler bir tasarıma sahipseniz, bu değişiklikleri uygulamak basit olmalıdır .
Eğer kodunuz sıkı sıkıya bağlı değilse, modüllerde yapılan değişiklikler çevreleyen yapıyı etkilemez.

Ekstra feribot eklemeye bir göz atalım.
Tek bir feribot fikri etrafında 'kötü' bir program oluşturulabilir ve rıhtım devletlerine ve feribot eyaletine ve bir araya getirme ve paylaşma durumuna sahip olmaları sağlanabilir. Bu, sisteme fazladan bir feribot eklenmesini sağlamak için değiştirilmesi zor olacaktır.
Daha iyi bir tasarım, ayrı varlıklar olarak rıhtımlara ve feribotlara sahip olmak olacaktır. Aralarında sıkı bir bağlantı yoktur, ancak bir feribotun ulaşabileceği, yolcuları boşaltabileceği, yenilerini alabileceği ve gidebileceği bir ara yüzleri vardır. İskele ve feribot yalnızca bu arayüzü paylaşır ve bu, ikinci bir feribot ekleyerek sistemde değişiklik yapmayı kolaylaştırır. İskelede gerçekte var olan feribotların umrunda değil, ilgilendiği tek şey bir şeyin (herhangi bir şeyin) arayüzünü kullanmasıdır.

tl; dr:

  • Her şeyden önce verimlilik için tasarım yapmaya çalışın.
  • İki seçenekle sunulduğunda, daha verimli olanı seçersiniz.
  • Kodunuzu, iyi tanımlanmış arayüzlerle mümkün olduğunca modüler olarak yazın.

Daha sonra, optimize etmek istediğinizde tüm kod tabanını yeniden yapılandırmadan her modülün içindeki mekanizmaları değiştirebilirsiniz.


16
Başlangıçta feribotunuzu da uygulayabilirsiniz ve feribotlar IRiverCrossingiçin trafiğin çok fazla olduğu netleştiğinde köprüyü olduğu gibi uygulayıp IRiverCrossingbırakabilirsiniz. ve Ortak işlevsellik köprüsüne, aynı arayüzle gösterilebilmeleri için.
Bay

2
Bu modüler arayüzler için otomatik testler bile yapmış olabilirsiniz, böylece dokunduğunuz modülün dışından herhangi bir şeyi kırma konusunda endişelenmeden hızlıca yeniden ateş açabilirsiniz.
user3067860

2
Bugünlerde OOP'nin neden bu kadar önemli olduğuna dair çok güzel bir örnek.
Jaime Gallego

1
Doğru nedeni vurdun. Donald Knuth'un mantra yalnızca hız temel gereksinimlerden biri olmadığı zaman doğrudur ve optimizasyona odaklanmak ana tasarımı tehlikeye atar. Ne yazık ki, oyunlar genellikle hız içinde olduğu özünde ve dolayısıyla erken tasarım hesaba katılmalıdır. OP'nin endişesi (ve cevabınız) tamamen haklı.
Peter A. Schneider

3
@AlexandreVaillancourt, soru başlığına cevap vermek yerine, sorunun gerçekten cevaplandırılmasının anahtar kısmı olduğunu düşündüğümüzü yanıtlamaya çalıştım; yani, "tasarımım sabitlendiğinden sonra optimizasyon çok daha fazla işe yarayacaksa neden erken optimizasyon yapmamalıyım?" dır . Bu cevap ayrıca DMGregory'nin cevabı üzerine bir yorum olarak da başladı ve buna ek olarak, cevabını çoğaltmanın pek bir anlamı yok.
Baldrickk

24

"Erken optimizasyon yapmayın", "işleri yapmak için mümkün olan en kötü yolu seçme" anlamına gelmez. Yine de performans sonuçlarını göz önünde bulundurmanız gerekir (sadece prototip olmadıkça). Mesele şu ki gelişimdeki o noktada diğer, daha önemli şeyleri sakatlamak değil - esneklik, güvenilirlik vb. maliyetleri takip edin. Güçlü yazarak mı kullanmalısınız? Çoğu oyun iyi sonuç verdi; Oyun oynamak için esnekliğin ilginç kullanımlarını bulursanız, bunu kaldırmanız ne kadara mal olur?

Optimize edilmiş kodu, özellikle "akıllı" kodu değiştirmek çok daha zor. Her zaman bazı şeyleri daha iyi yapan, diğerleri ise daha kötü olan bir seçimdir (örneğin, bellek kullanımı için CPU zamanı değişiyor olabilirsiniz). Bu seçimi yaparken, tüm sonuçların farkında olmanız gerekir - felaket olabilirler ancak yardımcı olabilirler.

Örneğin, Komutan Keen, Wolfenstein ve Doom, optimize edilmiş bir işleme motorunun üzerine inşa edildi. Her biri, oyunun ilk etapta var olmasını sağlayan "numaralarına" sahipti (her biri zaman içinde daha da geliştirildi ancak bu önemli değil). Bu iyi . Oyunun özünü, oyunu mümkün kılan düşüncesini yoğun bir şekilde optimize etmek sorun değil; Özellikle, bu optimize edilmiş özelliğin çok fazla keşfedilmemiş oyun tasarımlarını düşünmenize izin verdiği yeni bölgeleri keşfediyorsanız. Optimizasyonun getirdiği sınırlamalar size ilginç bir oyun sunabilir (örneğin, RTS oyunlarındaki birim sayım limitleri performansı arttırmanın bir yolu olarak başlamış olabilir, fakat aynı zamanda bir oyun efekti de vardır).

Ancak bu örneklerin her birinde, oyunun optimizasyon olmadan var olamayacağına dikkat edin. “Tamamen optimize edilmiş” bir motorla başlamadılar - çıplak bir zorunlulukla başladılar ve çalışmaya başladılar. Yeni teknolojiler geliştiriyorlardı ve onları eğlenceli oyunlar yapmak için kullanıyorlardı. Motor hileleri kod tabanının mümkün olduğu kadar küçük bir kısmı ile sınırlıydı - daha ağır optimizasyonlar yalnızca oyun çoğunlukla yapıldığında ya da ilginç bir yeni özelliğin ortaya çıkmasına izin verildiğinde ortaya çıktı.

Şimdi yapmak isteyebileceğiniz bir oyun düşünün. Bu oyunu yapan ya da bozan gerçekten teknolojik bir mucize var mı? Belki de sonsuz bir dünyada açık bir dünya oyunu hayal ediyorsundur. Bu gerçekten oyunun merkezi parçası mı? Oyun sadece onsuz işe yaramaz mıydı? Belki de arazinin sınırsız, gerçekçi jeoloji ile deforme olduğu bir oyun düşünüyorsunuz; daha küçük bir kapsamla çalışmasını sağlayabilir misiniz? 3B yerine 2B olarak çalışır mı? En kısa zamanda eğlenceli bir şeyler alın - optimizasyonlar mevcut kodunuzun çok büyük bir bölümünü elden geçirmenizi gerektiriyor olsa bile, buna değer olabilir; ve işleri daha büyük yapmanın oyunu daha iyi hale getirmediğini bile fark edebilirsiniz.

Çok fazla optimizasyona sahip yeni bir oyuna örnek olarak, Factorio'ya işaret ediyorum. Oyunun kritik bir parçası da kayışlar - binlerce insan var ve fabrikanızın her yerinde birçok bireysel malzeme parçası taşıyorlar. Oyun yoğun olarak optimize edilmiş kayış motoru ile başladı mı? Hayır! Aslında, orijinal kemer tasarımını optimize etmek neredeyse imkansızdı - kemerin üzerindeki eşyaların fiziksel bir simülasyonunu yaptı, bu yapabileceğiniz bazı ilginç şeyler yarattı (bu, “ortaya çıkan” oyun şeklini aldı - oyun şaşırtıcı. Tasarımcı), ama kemerdeki her bir eşyayı simüle etmek zorunda kaldın. Binlerce kayışla, on binlerce fiziksel olarak simüle edilmiş öğe elde edersiniz - yalnızca bunu kaldırarak ve kayışların işi yapmasına izin vermek, ilişkili CPU zamanını% 95-99 oranında azaltmanıza izin verir, hafıza yeri gibi şeyleri düşünmeden bile. Ancak, yalnızca bu sınırlara ulaştığınızda bunu yapmak faydalı olacaktır.

Kemerlerle ilgisi olan her şey, kemerlerin optimize edilmesine izin vermek için yeniden yapılmak zorunda kaldı. Kemerlerin optimize edilmesi gerekiyordu, çünkü büyük bir fabrika için çok sayıda kemere ihtiyacınız vardı ve büyük fabrikalar oyunun bir cazibesi. Sonuçta, eğer büyük fabrikalara sahip olamıyorsanız, neden sonsuz bir dünyaya sahipsiniz? Komik, sormalısın - erken sürümler yoktu :) Oyun, şu anda bulundukları yeri bulmak için defalarca elden geçirildi ve yeniden şekillendirildi - Java'nın bir yolun olmadığının farkına vardığında% 100 sıfırlama dahil oyun böyle ve C ++ 'a geçti. Ve Factorio için çok işe yaradı (hala iyi bir şey olsa da başlangıçtan itibaren optimize edilmedi - özellikle de bu, ilgisizlikten dolayı başarısızlıkla sonuçlanabilecek bir hobi projesi olduğu için).

Ama olay orada olması vardırSınırlı bir fabrikada yapabileceğiniz birçok şey - ve pek çok oyun bunu göstermiştir. Sınırlar eğlence için özgürlüklerden daha da güçlendirici olabilir; "Haritalar" sonsuz olsaydı, Spacechem daha mı eğlenceli olurdu? Yoğun şekilde optimize edilmiş "kayışlarla" başlarsanız, hemen hemen o yöne gitmek zorunda kalırsınız; ve diğer tasarım yönlerini keşfedemediniz (fizikle simüle edilmiş konveyör bantlarla ne ilginç şeyler yapabileceğinizi görmek gibi). Potansiyel tasarım alanınızı sınırlandırıyorsunuz. Öyle görünmüyor çünkü pek fazla bitmemiş oyun görmüyorsunuz, ancak zor kısmı eğlenceyi doğru yapmak - gördüğünüz her eğlenceli oyun için, muhtemelen orada bulunamayan ve hurdaya çıkmış yüzlerce kişi var (veya daha da kötüsü, korkunç mesajlar olarak serbest bırakıldı). Eğer optimizasyon bunu yapmanıza yardımcı olursa - devam edin. Olmazsa ... muhtemelen erken. Eğer bir oyun teknisyeni harika çalışıyor, ancak gerçekten parlamak için optimizasyonlara ihtiyaç duyduğunu düşünüyorsanız - devam edin. Eğer ilginç mekaniğiniz yoksa,onları optimize etme . Önce eğlenceyi bulun - çoğu optimizasyonun buna yardımcı olmadığını ve çoğu zaman zarar verici olduğunu göreceksiniz.

Sonunda harika, eğlenceli bir oyunun var. Şimdi optimizasyon yapmak mantıklı mı ? Ha! Hala düşündüğün kadar net değil. Eğlenceli bir şey var mıonun yerine yapabilir misin? Unutma, zamanın hala sınırlı. Her şey bir çaba ister ve bu çabayı en çok önem verdiği noktaya odaklamak istersiniz. Evet, "ücretsiz oyun" veya "açık kaynak" bir oyun yapıyor olsanız bile. Oyunun nasıl oynandığını izleyin; performansın bir darboğaz haline geldiğine dikkat edin. Bu yerleri optimize etmek daha eğlenceli hale getiriyor mu (daha büyük, daha da karışık fabrikalar inşa etmek gibi)? Daha fazla oyuncu çekmenize izin veriyor mu (örneğin daha zayıf bilgisayarlar ile veya farklı platformlarda)? Her zaman önceliklendirmeniz gerekir - oran verme çabasını araştırın. Muhtemelen oyununu oynamaktan ve başkalarının oyunu oynamasını izlemek için bol miktarda asılı meyve bulabilirsiniz. Ancak önemli kısmı not edin - oraya ulaşmak için bir oyuna ihtiyacınız var . Buna odaklan.

Üstte bir kiraz olarak, optimizasyonun asla bitmeyeceğini düşünün. Tamamladığınız ve başka görevlere geçtiğiniz küçük bir onay işaretine sahip bir görev değildir. Her zaman yapabileceğiniz "bir tane daha optimizasyon" vardır ve herhangi bir gelişimin büyük bir kısmı öncelikleri anlamaktır. İyileştirme uğruna optimizasyon yapmazsınız - bunu belirli bir hedefe ulaşmak için yaparsınız (örneğin, "333 MHz Pentium'da bir kerede ekranda 200 ünite" harika bir amaçtır). Terminal hedefinin izini kaybetmeyin, çünkü artık terminal hedefi için ön koşul olmayabilecek ara hedeflere çok fazla odaklanıyorsunuz.


Faktör geliştiricilerin artık bantları tekrar optimize ettiklerini düşünüyorum, böylece sadece periyodik olarak eşyaları simüle etmeleri gerekiyor ve diğer zamanlarda sadece onlara bakarken konumlarını enterpolasyon yapıyor. Ama sadece o yapıyoruz şimdi tüm oyun etkili bir kemer (ve robotlar) uzun süre etrafında dayalı olarak ne zaman ve kadar olmaz insanlar fark ve performansla ilgili şikayet başladı.
immibis

2
@ immibis Tam olarak. İnsanlar gerçekten sınırlara ulaşmadan daha iyi performans göstermesi, başka yerlerde daha iyi harcanan bir kaynak israfı olacaktır. En son optimizasyonlarla bile, normal oyun kapsamının çok ötesinde (roketi fırlatma) sadece megafonlar için problemle karşılaşıyorsunuz. Ancak, çok daha ağır lojistik gerektiren yeni Marathon oyun ayarlarını etkinleştirdi. Ve yine, oyun oynayan insanlardan istatistik alarak, darboğazları belirlediler - darboğazların yaklaşık yarısı onlar için büyük bir sürprizdi.
Luaan

@Fattie Yani soruyu anlıyorsun ama cevabı değil mi? Daha basit bir cevabın mümkün olduğunu söylemeye mi çalışıyorsun (örneğin, "Ekonomi")? Yorumunuzun nasıl yapıcı olduğunu sanmıyorum.
Luaan

2
@Fattie Eğer cevabın "tıkanıklığın ne olduğunu öğrendikten sonra sadece bir kez optimize et" olduğunu düşünüyorsanız, cevap olarak gönderin. Zaten iyi bir cevap için gerekenden çok daha fazla kelime harcadın, o yüzden devam et. Ne tür bir optimizasyon işleri daha iyi ve daha kötü yapmaz? Kesinlikle hiç görmedim. Yinelemeye devam ettiğim en temel şey, her zaman başka yerlerde daha iyi harcanabilecek takas zamanı, esnekliğinizi sınırlayan karmaşıklık ... Örnekler "erken" nin mutlak bir terim olmadığını; Bazıları optimizasyon ilk günden itibaren, bazıları ise zarar verici olmakla yükümlüdür.
Luaan

1
@Fattie "Darboğazın ne olduğunu öğrendikten sonra, yalnızca" optimize et "ifadesi" Ne zaman optimize etmeliyim? " ve olduğu değil "Neden bu kadar kötü çok erken optimize etmektir?" bir cevap.
immibis

10

Yanıtların birçoğu, "optimizasyonun" performans yönüne çok fazla odaklanıyor gibi gözükse de ben daha çok soyut bir seviyede optimizasyona ve optimizasyonun tüm sıkıntısına bakmayı seviyorum.

Polyomino'ların yardımıyla bakış açımı geliştirmeye çalışırken, beni mizah haline getirin.

Birlikte çalıştığımız çerçeve veya motor tarafından belirlenen bazı sabit sınırlarımız olduğunu varsayalım.

görüntü tanımını buraya girin

Daha sonra oyunun ilk katmanını / modülünü oluşturmaya devam ediyoruz.

görüntü tanımını buraya girin

Devam ederek ikinci katman / modülümüzü oluşturuyoruz.

görüntü tanımını buraya girin

Bu noktada, iki modül arasında bir miktar boşluk olduğunu fark edebiliriz ve bize tahsis edilen sınırları tam olarak kullanabilmek için optimize etmek için cazip olabiliriz.

görüntü tanımını buraya girin

Mükemmel, şimdi uygulama tamamen bizim için mevcut kaynakları kullanıyor, uygulama daha iyi, iyi değil mi?

Uygulamamızın üçüncü katmanını / modülünü oluşturmaya devam ediyoruz ve aniden (ilk planlama sırasında tahmin edemediğimiz bir tane bile) 3. katmanın / modülün bizim için çalışmadığını fark ettik.

Bir alternatif ararız, birini buluruz ve sonunda, bu da yeni seçilen 3. modülümüzle uyumsuz olduğu için başvurumuzun 2. modülünü değiştirmemizi gerektirir. (Neyse ki 1. modülümüzle biraz uyumlu, bu yüzden her şeyi sıfırdan tekrar yazmak zorunda değiliz.)

Yani hepsini bir araya getirdik ...

görüntü tanımını buraya girin

Hmm, ne olduğunu görebiliyor musun?

Çok erken optimizasyon yaparak, işleri optimize etmeyi daha da kötüleştirdik, çünkü en iyi duruma getirdiğimiz şey, sonuçta ortaya çıkan şey değil.

Ve sonradan bazı ek modüller veya ilave çerezler eklemek isteseydik, artık bu noktada bunları yapma kapasitemiz olmayabilir.

görüntü tanımını buraya girin

Sistemimizin en düşük seviyesini ayarlamak, diğer tüm katmanların altına gömüldüğü için artık mümkün değildir.

Bununla birlikte, onu hemen optimize etmek için dürtü ile beklemeyi seçmiş olsaydık, şöyle bir şey olurdu:

görüntü tanımını buraya girin

Ve şimdi optimizasyonu bu noktada gerçekleştirirsek, bakmak için tatmin edici bir şey elde ederiz.

görüntü tanımını buraya girin

Umarım en azından bazılarınız bunu okurken çok eğlendi :) :) ve şimdi konuyu daha iyi anlıyormuş gibi hissediyorsanız - daha iyisi.


3
Reklamı kaldırıyorum. Görüntüleri nasıl yaptığınız umrumda değil; tek önemli kısım, onları gönderme hakkına sahip olduğunuz varsayımıdır.
Gnemlock

2
@Gememlock yeterince adil, niyetim reklamlara yönelik olmasa da, nasıl kolayca yanlış yorumlanabileceğini de görebiliyorum ve cevabına hiçbir şey eklemeyeceği konusunda katılıyorum.
Tavan Gecko

2
Bu görsel metaforun çok etkili olduğunu düşünüyorum. Soruyu cevaplamak için harika bir yaklaşım! :)
DMGregory

8

Para.

Bu aşağı gelir. Para. Zaman para olduğu için *, daha fazla para üretme garantisi olmayan faaliyetler için ne kadar zaman harcarsanız (yani, bu faaliyetleri yatırım olarak düşünemezsiniz ), daha fazla para harcamayı riske atarsınız ve daha az para kazanırsınız. oyun.

İyileştirmenin çok erken zamanda bazı daha olası yan etkileri ve bundan kaçınmanız için nedenler:

  • Meslektaşlarınız sizden nefret ediyor, çünkü özelliklerin elde edilmesi için çok çalışırken, kum havuzunuzda oyuncaklarınızla oynuyorsunuz.
  • Gecikmeler daha yüksek yönetimi engeller ve ekibin teslimat tarihlerini kaçırmasına neden olur; bu da oyunun tatil sezonundan önce ilkbaharda yayınlanmasına neden olur ve bu da oyunun yeterince satmamasına neden olur. Bu nedenle, merkez ofis sizi etkili bir şekilde işsiz hale getirecek şekilde stüdyoyu kapatmaya karar verir. Ve iş yok, para yok demektir. (Kimse sizi sevmediği için erken optimizasyon yapmak için çok fazla zaman harcadığınız için, kimse LinkedIn'deki işinizle ilgili olumlu bir inceleme yazmak istemez, bu da sizi daha uzun süre paradan uzak tutacaktır.)

* Diğer cevaplar, 'zaman' bölümünü yeterince iyi vurguladı.


Genel bir not olarak , deneyim, erken optimizasyonun neyin neyin ve neyin olmadığını ve iş için neyin değerli olup olmadığını belirlemeye yardımcı olur.

Örneğin, A oyunu üzerinde çalıştıysanız ve projenin sonunda XYZ özelliğinin oyun döngünüzde özellikle ağır olduğunu fark ettiyseniz ve en sonunda aynı özelliğe sahip olan B oyunu üzerinde çalışmaya karar verdiniz. özelliği yeniden yazmak ve siz baştan optimize gerçekten erken optimizasyon değil biliyorum birşey yapılmayacak olursa bu bir darboğaz olacak.


1
@JBentley bu geçerli bir nokta. Bununla birlikte, toplanan deneyimin doğrudan bir sonucu olarak "neden" in sonuç olarak ortaya çıkan bir cevabı vardır. Bu nedenle, 1) erken optimizasyon, kodun ortalama çalışma zamanını etkilemeyen bölümlerinde boşa zaman harcayabilir (deneyim verildiğinde, hangi kod yapılarının optimizasyon için en iyi uygulamalar için aday olduğunu bilmelisiniz ) 2) erken optimizasyon yapmak, kodu zorlaştırabilir Bazı sistemlere uygulanan tasarım kısıtlamaları nedeniyle sürdürmek. Böylece daha uzun geliştirme döngüleri / hantal kodun korunması karşılığında çok az kazanabilirsiniz.
teodron

3
@JBentley Bunu DMGregory'nin cevabına ek olarak kabul edin.
Alexandre Vaillancourt

1
Buradaki tek değerli cevap gibi görünüyor. Soru bir totolojidir. “Peki neden aslında bir oyunun uygulama mağazalarında daha az para kazanmak yerine daha fazla para kazanmasını istiyorsun?” Diye sorabilirsiniz. Buna nasıl cevap verebilirsin?
Fattie

@Fattie Bir cevapta bu tür bir perspektife sahip olmak iyidir. Ancak bunun tek değerli cevap olduğunu söylemek, sorunun kapsamını makul olmayan şekilde daraltmaktır. Örneğin, yapılan tek oyunun kar amacı gütmeyen kuruluşlar içinde olduğunu (açıkça doğru olmadığını) düşünüyorsunuz. Ayrıca, OP için erken optimizasyonun daha fazla zaman harcanmasına yol açtığını (ve dolayısıyla bir işletmeden söz ediyorsak daha fazla paraya) yol açtığını varsayıyorsunuz. Aslında OP'nin sorusu, bundan emin olmadığını gösteriyor.
JBentley

6

Optimizasyon, tanımı gereği, bir çözümün etkinliğini kaybettiği noktaya kadar verimliliğini artırma sürecidir. Bu işlem daha sonra çözüm alanının azaltılmasını gerektirir.

Yazılım geliştirmenin ilk aşamalarında hala "gizli gereksinimler" olabilir: çözümünüzün alanını çok fazla azaltırsanız, ortaya çıktığında "gizli gereksinimi" karşılayamayacağınız bir durumda olabilirsiniz daha sonraki bir gelişim aşamasında, sizi daha sonra mimariyi bu şekilde kararsızlığa ve istenmeyen bir dizi istenmeyen davranış biçimine eklemeye zorlar.

Bu durumda fikir, tüm çözümü işe almak ve ancak o zaman, tüm gereklilikler yerine getirildiğinde ve uygulandığında, kodu sıkın. O zaman göreceksiniz ki, kodlama sırasında bir kerede çok fazla uygulayacağınız bir çok optimizasyon artık geç gereksinimlerle olan etkileşim nedeniyle artık mümkün değildir.

Çözümün gerçek alanı her zaman başlangıçta beklediğimizden daha büyüktür çünkü çok karmaşık bir sistem hakkında mükemmel bir bilgiye sahip olamayız.

İlk önce çalışsın. Ardından ipleri sıkın.


2
Bence "etkinlik", gittiğiniz kelime değildir - "etki üretme gücü" anlamına gelir, yani bir anlamda, optimizasyon tamamen etkinliği arttırmakla ilgilidir . Belirli bir etkinlik sürümüne mi gidiyorsunuz? (Bununla bağlantı kurar mısın?) Esneklik gibi bir şey mi demek istiyorsun?
doppelgreener

2
@doppelgreener İstediğiniz efektleri üretmeyi bırakana kadar çözümü daha verimli hale getirdiğiniz anlamına gelir ...
immibis

1
"Önce çalışmasını sağlayın. Ardından halatları sıkın." - Cevabın kalan kısmı kadar değerli olmalı. Diğer şeylerin iyi olmadığını söyleme.
ebyrob

1
@ebyrob: Başka bir deyiş daha var: "Çalışmasını sağla, doğru yap, hızlı yap" wiki.c2.com/?MakeItWorkMakeItRightMakeItFast
ninjalj

@ ninjalj Bu da iyi. Elbette, patronum her zaman bana şöyle der: "Acele etme, doğru yap." Bu yüzden söylediklerinizin asıl posterin daha fazla ayrıntı talep ettiği müdür kadar evrensel olup olmadığını bilmiyorum.
ebyrob

2

Kısacası, daha sonraları değiştirmek istiyorsanız, genellikle erken optimizasyon boşa harcanır ve daha sonra kolayca değiştirilebilen kod yapılarını çok daha düşük bir seviyeye dönüştürdüğünüz ortaya çıkar ve şimdi tekrar yüksek bir seviyeye getirmeniz gerekir. seviye yaklaşımı ve sonucu bir kez daha optimize edin.

Bu, "işe yarar bir iş çıkmış" olmaktan zevk almaya odaklanmak isteyen, optimizasyon gibi, bunu yapmak için doğru zaman olup olmadığını düşünmekten kaçınan, yeni başlayan geliştiriciler için yaygın bir hatadır. Oyunlar gibi büyük projelerin programlanması konusunda deneyim kazandıkça, mevcut kod tabanını ne zaman optimize edeceğinizi ve ne zaman çok erken olduğunu öğreneceksiniz. Bu hatayı yapmaktan korkma, sadece ondan öğrenerek faydalanırsın.

Genel olarak, yalnızca bu andaki geliştirme oluşturma işlemiyle gerçekten çalışamıyorsanız optimize edin. Saniyede saniyede 60 kez milyonlarca nesne oluşturup siliyorsanız.

Dolayısıyla, öğrenme deneyimi açısından, birkaç kez erken optimize etmenin iyi olacağını söyleyebilirim: p


2

Optimizasyon, bilgisayarın kodda en iyi şekilde çalışmasına odaklanırken, geliştirme için programcının en iyi kod üzerinde çalışmasını gerektirir.

Optimizasyon, öngörüleri ortaya çıkarmaz. Bilgisayarın daha az çalışmasını ve programcının daha fazla çalışmasını sağlar.

Elbette, bir araba tasarlamada olduğu gibi farklı kategoriler var. İlk kasanızı inşa etmeden önce motoru optimize etmenin yanlış bir tarafı yoktur, ancak motorun şeklini bilmeden kasayı optimize etmek zaman kaybına neden olabilir. Modülerlik ve teknik özellikler, ürün bir bütün olarak toplanmadan önce bile optimizasyon için uygun birçok yere sahip olabilir.


Bu, optimizasyonu tanımlamaktan başka bir şeye öncülük etmek ve arabalarla ilgili analojiler yapmaktan ziyade oyun geliştirmedeki pratik durum hakkında konuşarak geliştirilebilir.
doppelgreener

Tautolojik bir soruya mükemmel bir cevap.
Fattie

2

İlk aşamada kodun optimize edilmemesi gerektiği yönündeki ifadelere kesinlikle katılmıyorum. Hangi aşamada olduğunuza bağlı. Eğer bu MVP ise - prototip ve sadece 1 ila 2 hafta süren oyuna bakmaya çalışıyorsunuz, zaten yazdığınız her şeyi yeniden yazmaya hazırsınız. Evet, optimizasyon önemli değil. Ancak piyasaya sürüleceğini bildiğiniz bir oyun üzerinde çalışıyorsanız, kodun tamamını optimize etmesi gerekir. İnsanların yeni özellikler ve eklenebilecek şeyler hakkında söylediği hikayeler yanlış anlamadır. En iyi duruma getirilmiş kod yerine, kötü tasarlanmış kod mimarisi. Güzel kod tasarımınız varsa, yeni öğeler eklemek için hiçbir şeyi yeniden yazmanıza gerek yoktur.

Örneğin, bir A * yol bulma algoritmanız varsa, en uygun şekilde yazmanız daha iyi olmaz mı? Daha sonra kodunuzun yarısını değiştirmekten ziyade, algoritmada bazı değişiklikler yapmak zorunda kaldığınız için, çünkü şimdi başka bir yöntem çağrıları ve geri çağırmalar gerektiriyor. Baştan beri optimize edilmiş bir kodunuz varsa, bu size çok zaman kazandıracaktır. Çünkü kendinizi tonlarca yeni komut dosyası yapmak ve derhal tüm bağlantıları kurmak yerine, nesneler ile nasıl etkileşime girdiklerini ilişkilendirebilirsiniz - bu, net olmayan sphagetti koduna yol açar.

Eklemek istediğim son şey, daha sonra, artık oyunu yapmak istemeseniz bile, sonraki oyunlarınız için kullanabileceğiniz optimize edilmiş A * algoritmanıza sahip olmanızdır. Tekrar Kullanılabilirlik. Örneğin, birçok oyun envanter, yol bulma, prosedür oluşturma, npc, dövüş sistemi, AI, Arayüz etkileşimi, giriş yönetimi arasındaki etkileşimlere sahiptir. Şimdi kendinize sormalısınız - "Bu elemanları sıfırdan kaç kere yeniden yazdım?" Oyunun% 70-80'i. Gerçekten onları her zaman yeniden yazmaya gerek var mı? Peki ya onlar korunmuyorsa?


5
A * kodu optimize edilmeye başlamalıysa, "optimize edilmiş" ne kadar optimize edilmiş? Karşılaştırma yapmadan önce montajdaki işleri elle mi kodluyorsunuz? Genelde mikro optimizasyonlar üzerinde önemsiz olmayan çalışmaların, kıyaslamalar yapılıncaya kadar bırakılması gerektiğini düşünüyorum. Optimize derleyici olabilir mikro optimizasyonlar size daha iyi bir iş yapmak, ve çok daha ucuzdur.
17:17

@gmatht Well A *, kötü bir tasarıma sahip olduğunu ve gerçekten iyi çalışmadığını söylediğim gibi farklı olabilir. Ancak, Fibonacci yığınına dayanarak çok parçalı olabilir, bazı tahminler vardır, parçalara bölünür. Eğer yol bulma hakkında konuşuyorsak, A * ile karıştırılacak Akış Alanını ekleyebiliriz. Ayrıca yol yumuşatma, çoklu yükseklik. Belki A * en iyi örnek değildir, ancak dediğim gibi, optimizasyonların kodu değiştirmeyle hiçbir ilgisi yoktur, geliştirici kodu değiştirmiştir, çünkü kötü dizayn edilmiştir, örneğin SOLID'i 1 neden olarak takip etmedi. Bunu yazdım * iyi, artık yazmaya gerek yok.
Candid Moon _Max_

@gmatht mikro optimizasyonları aslında sorun değil. OP'nin AI davranışını veya gölgelendiriciyi veya başka herhangi bir şeyi hesaplamanın en iyi ve en etkili yolundan biri olduğunu düşünüyorum.
Candid Moon _Max_

Bunları verimli bir şekilde nasıl yazacağınızı biliyorsanız, bunu yaparken de sorun görmüyorum. Aynı miktarda zaman veya daha az sürer. Geliştiricilerin deneyimine daha fazla bağlıdır. Bir programcı olarak, daha iyi bir çözüm bilseydim, berbat bir şey yazmazdım. Fibonacci öbekini nasıl yazacağımı bilirsem, min veya maks değerlerini elde etmek için Liste ve sıralama kullanmayacağım. Elbette List.Sort () kullanmak yerine yazmak için biraz daha zaman ve çaba harcayacak; , peki ya zaten yeniden kullanılabilir bir tane varsa?
Candid Moon _Max_

2
@CandidMoon "Aynı zaman veya daha az zaman alacaktır" ile aynı fikirde değilim. Etkili kod yazmak için. Belki de açıkça verimsiz olmayan bir kod yazmak aynı zamanda zaman alır, ancak "efficienct" kavramınız önbellek çekmeyi düşünmek, çoklu okuma eklemek, yalnızca bazı CPU'larda mevcut olan işlemciye özgü intrinikleri kullanmak, O nedeniyle büyük N için algoritmalar değiştirmek anlamına gelir. (N log N) vs O (N) - bu tür bir şey zor ve hata eğilimli ve basit uygulamadan çok daha fazla zaman alır. Sadece nihai sonucu maddi olarak etkileyeceğini bildiğiniz zaman yaparsınız .
Michael Anderson,
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.