Basit vs Karmaşık (ancak performans etkin) çözümü - hangisini ve ne zaman seçmelisiniz?


28

Birkaç yıldır programlama yapıyorum ve sık sık kendimi ikilemde buldum.

İki çözüm var -

  • bunlardan biri basit olanı, yani basit bir yaklaşım, anlaşılması ve bakımı kolay. Fazlalık, bazı ekstra işler (ekstra G / Ç, ekstra işleme) içerir ve bu nedenle en uygun çözüm değildir.
  • ancak diğerleri, çoğu modül arasında etkileşimi içeren ve uygulaması zor, karmaşık bir yaklaşım kullanır ve performans açısından verimli bir çözümdür.

Karşılamak için zor performans SLA'sım olmadığında ve basit çözüm bile performans SLA'sını karşılayabildiğinde hangi çözüm için çaba göstermeliyim? Basit bir çözüm için diğer geliştiriciler arasında küçümseyebildiğimi hissettim.

Performans SLA'nız basit bir çözümle karşılanabilirse, en uygun karmaşık çözümü bulmak iyi bir uygulama mıdır?


10
bkz: “Geliştiricinin Kötü Optimizasyon Sezgisini” nasıl önleyebilirim? “Ne yazık ki, geliştiriciler genellikle bir uygulamadaki performans sorunlarının gerçekte nerede olacağı konusunda korkunç bir sezgiye sahipler …”
gnat

1
"En uygun olmayan" hala "yeterince iyi" olacak mı? O zaman onunla kal.

8
Evet. " Le mieux est l'ennemi du bien. " Voltaire. ("Mükemmel, iyinin düşmanıdır.") Yeterince iyi, performans testi aksini söyleyene kadar.
David Hammen

Bunun (genel olarak) basit, etkili olduğu anlamına gelir. Bu yüzden sıklıkla uzlaşmaya gerek yoktur.
Dan,

2
“Görünüşe göre, mükemmellik ekleyecek başka bir şey olmadığında değil, kaldırılacak başka bir şey olmadığında da elde edilmiş görünüyor.” - Antoine de Saint-Exupery
keuleJ

Yanıtlar:


58

Karşılamak için zor performans SLA'sım olmadığında ve basit çözüm bile performans SLA'sını karşılayabildiğinde hangi çözüm için çaba göstermeliyim?

Basit olanı. Spesifik özellikleri karşılıyor, anlaşılması daha kolay, bakımı daha kolay ve muhtemelen çok daha az bir sorunlu.

Performans etkin çözümün savunuculuğunu yapmakta olduğunuz şey, kodunuza spekülatif genellik ve erken optimizasyon sağlamaktır. Yapma! Performans, var olan diğer tüm yazılım mühendisliği 'ility'lerinin temeline ters düşüyor (güvenilirlik, bakım kolaylığı, okunabilirlik, test edilebilirlik, anlaşılabilirlik, ...). Test sırasında performansı kovalamak, performanstan sonra gerçekten kovalamanın bir gereği olduğunu gösterir.

Performans önemli değilken performansı takip etmeyin. Önemli olsa bile, yalnızca performansın bir performans darboğazının bulunduğunu gösterdiği alanlarda performansı izlemelisiniz. simple_but_slow_method_to_do_X()Bu basit sürümün bir darboğaz olarak görünmemesi durumunda performans sorunlarının daha hızlı bir sürümle değiştirilmesinin bahanesi olmasına izin vermeyin .

Geliştirilmiş performans, kaçınılmaz bir şekilde bir dizi kod kokusu sorunu ile kaplanmıştır. Soruda birkaç kişiden bahsettiniz: Uygulaması zor, daha yüksek eşleşme karmaşık bir yaklaşım. Bunlar gerçekten sürüklenmeye değer mi?


Cevabınız çok yararlıdır
MoveFast

1
Mümkün olduğu kadar basit, ancak daha basit değil; Mümkün olduğunca hızlı, ancak daha hızlı değil; etc
user606723 14:12

2
"Şüphe
duyduğunuzda

Koddaki yorumlar burada hem katartik hem de yardımcı olabilir. Karmaşık + hızlı çözümü ve neden kullanmadığınızı gösteren küçük bir yorum, optimal algoritmayı görmezden geldiğiniz gibi hissetmenize izin vermez. Ayrıca, daha sonra optimizasyona ihtiyaç duyulursa, bakımcıların seçiminizi anlamalarına ve doğru yönde yönlendirmelerine yardımcı olabilir.
TheAtomicOption

12

Kısa Cevap: Basit çözümleri karmaşık yerine tercih edin, KISS ve YAGNI prensiplerini hatırlayın

İlk proje gereklilikleri ve yazılımı hiçbir zaman mükemmel olmadığından, uygulama geliştirildikçe / kullanıldığında değişiklik yapılmasını gerektirir. Geliştirme aşamalarındaki yinelemeli yaklaşım, işleri basitleştirmek ve gerektiği kadar genişletmek için çok iyi bir eşleşmedir. En basit çözümler esneklik için odalara sahiptir ve bakımı daha kolaydır.

Ek olarak, uygulamanızı oluştururken akıllı olmaya ve bazı ek optimizasyonlar yapmaya çalışmak iyi bir uygulama değildir ve çözümünüzü aşırı karmaşık hale getirebilir. Bilindiği gibi, "premature optimization is the root of all evil"- Knuth'un kitabından


1
@ManojGumber, sorun değil ve gerçekten de programcılar olarak ilk başta ne ummamız gerektiği esastır.
EL Yusubov 14:12

8

Burada Knuth'dan bir ders alın: "Küçük verimleri unutmalıyız, zamanın yaklaşık% 97'sini söyleyelim: erken optimizasyon tüm kötülüklerin kaynağıdır".

Çözümlerinizi şu sırayla düşünün: İlk, her zaman, doğruluk. İkincisi, netliği ve sadeliği arttırın. Üçüncüsü ve yalnızca ihtiyacı, etkinliği gösterebildiğiniz zaman.

Verimlilik eklemek neredeyse her zaman size önemli bir şeye mal olacak ve bu nedenle yalnızca ihtiyacınız olduğunu bildiğiniz zaman takip edilmelidir.


4
Bunun, her şeyden önce iyi bir uygulama yazmamanız gerektiği anlamına gelmediğine dikkat edin.

@ ThorbjørnRavnAndersen: Elbette, ilk iki nokta bununla ilgili.
simon

1
@simon alıntı sık sık özensiz seçmek için bir bahane olarak kullanılır,

İkinci konunuz hakkında: Sık sık doğru spagetti yapmadan önce yanlış yapılandırılmış ve temiz kodu tercih ettiğini söyleyen bir meslektaşım vardı.
Buhb,

@ ThorbjørnRavnAndersen beceriksiz insanlar bir bahane için her şeyi kullanır. Orijinal düşüncenin değeri üzerinde bir etkisi yoktur.
simon

7

Sadelik, güvenilirliğin ön şartıdır . Çalışan basit bir çözüm varsa, elbette bunun için gidin! Çalışan bir programı optimize etmek, optimize edilmiş bir programın çalışmasını sağlamaktan çok daha kolaydır. Ayrıca unutma Moore yasasına : performans hedefleri bugün basit bir çözüm buluştuğu eğer, muhtemelen onları ezecek 1 bir veya iki yıl içinde.


1 Orada hiçbir garanti yoktur, çünkü Jimmy Hoffa aşağıdaki yorumunda belirtildiği gibi, Moore yasasının sınırları vardır.


Moore'un belirttiği diğer yasayı unuttun, "Oops, ilk yasam hakkında." Üzgünüm patron, Moore yasası artık yok (pun pun). Meselenin geri kalanına katılmıyorum, en azından oradaki en son kısmı ben uyarırdım.
Jimmy Hoffa

2
Üzgünüm, ama bu sektördeki tüm deneyimlerime. "çalışma setleri" sürekli güncellenen donanım hızımızdan daha hızlı FAR'ı artırıyor. Gerçekten, sadece Moore'un kanun noktasını kaldırırdım.
user606723 14:12

@ user606723 "İş kümesi" noktasının büyümesi, "optimize edilmiş veya basit" sorusuna diktir: iş yükü, hangi çözümü uyguladıklarına bakılmaksızın onlarla yetinir. Moore kanununu karışıma dahil etmenin amacı, basit çözümün yazma sırasındaki performans baskısı altında olsa bile, donanımın daha hızlı bir donanım mevcut olduğunda baskının azalacağını belirtmesiydi.
dasblinkenlight 14:12

@dasblinkenlight, çalışma grubunun büyümesi sorusunun moore yasasından ziyade dik değil. Çalışma setini soruna dahil etmenin amacı, basit bir çözümün piyasaya sürüldüğü sırada bazı performans baskısı altında kalması durumunda, artan çalışma grubu gelişmiş donanımın sağladığı herhangi bir performans iyileştirmesini yıktığından, performansın yakın gelecekte yetersiz kalmasıdır. Tamamen basit, güvenilir ve sürdürülebilir bir yazılım için çalışsam da, piyasaya sürüldüğünde performans baskısı altında olan yazılımı piyasaya sürmek ve moore yasasını bile çıkarmasını beklemek berbat bir felsefedir.
user606723 14:12

3

Performans SLA'nız basit bir çözümle karşılanabilirse, en uygun karmaşık çözümü bulmak iyi bir uygulama mıdır?

Optimal belirsiz bir kelimedir!

Sonuçta, karmaşık olanı korumak zorunda olma riski çok yüksekse ve basit olanı "yeterince iyi" ise, her zaman basit olanın yanında kalırdım.

Karmaşık olanın yeterince iyi olmama riskini de ekleyin, o zaman KISS muhtemelen doğru cevaptır.


2

Basit olanı tercih ederim. Bence erken optimizasyonlar çözdükleri kadar sorun yaratıyor. Pek çok durumda, iyi tasarım, tıkanıklık hallerinde, gelecekte verilen uygulamaları değiştirmenize olanak sağlar.

Sonuç olarak, mümkün olduğunca esnek tasarlayacağım, ancak esneklik için basitliği çok fazla ödün vermeyeceğim.


2

Hangisi daha ucuza mal oluyor?

Çoğu zaman, biraz daha yavaş olan basit bir çözüm, performans açısından mükemmel bir şekilde kabul edilebilir olacaktır ve basitlik, geliştirmeyi, sürdürmeyi ve nihayetinde yerini almayı daha ucuz hale getirir.

Öte yandan, bazen hız gerçekten önemlidir ve küçük hız iyileştirmelerinden bile gelen finansal kazanç, daha karmaşık bir çözümün artan maliyetinden çok daha büyük olabilir. Örneğin, bir işlemi tamamlamak için zamanın 0.01 saniyesini tıraş etmek bir menkul kıymet alım satım sistemini çok daha karlı hale getirebilir. Birkaç milyon kullanıcıyı destekleyen bir sistemin verimliliğinde% 10'luk bir gelişme sunucu maliyetlerinde önemli bir düşüş anlamına gelebilir.

Öyleyse, kendinize sormanız gereken soru şudur: Karmaşık çözümü kullanmak, ek maliyetini ödemek için sonuçta yeterince etkiye sahip midir? Aslında, müşterinizden faturalarını ödediklerinden ve potansiyel faydaları elde ettiklerinden karar vermelerini istemeniz gerekir. İyi bir seçenek, önce basit çözümle devam etmek ve daha karmaşık bir çözümü mümkün bir iyileştirme olarak sunmaktır. Bu, sisteminizi çalıştırmanıza ve çalıştırmanıza izin verir ve müşterinize teste başlaması için bir şeyler verir ve bu deneyim daha karmaşık bir çözümü uygulamaya (ya da uygulamamaya) karar verebilir.


2

İki yaklaşımı değerlendirirken, biri daha basit ancak daha az verimli iken, diğeri daha karmaşık ve daha verimli iken, birinin sorunu ve proje alanını göz önünde bulundurması gerekir.

15 yıldan fazla bakım ve +20 yıl kullanım ömrünü planlayan sağlık sektörü için multi-milyar bir yazılım projesi düşünün. Böyle bir projede performans kesinlikle bir sorun olmayacak, ancak proje karmaşıklığı ve yapısı, en az 15 yıl süren projenin bakımı için büyük sorunlara neden olabilir. Bakım ve basitlik her şeyden önce gelir.

Sonra başka bir örnek düşünün. Gelecek 5+ yıl boyunca şirketin gelecek oyunlarına güç vermesi beklenen bir konsol oyun motoru. Oyunlar son derece kaynak kısıtlı programlar olduğundan, birçok durumda verimlilik sürdürülebilmektedir. Bazı görevler için kendinize özgü, çok spesifik veri yapıları ve algoritmalar yazmak, yazılım geliştirmenin herhangi bir "en iyi uygulamasına" karşı olsa bile çok önemli olabilir. Buna güzel bir örnek, verilerinizi gerçek nesneler yerine benzer veri dizilerinde sakladığınız Veri Yönelimli Tasarım olabilir . Bu, konum referansını artırmak ve böylece CPU önbellek verimliliğini arttırmak içindir. Pratik değil, ancak verilen alanda çok önemlidir.


1

Bu her zaman zor bir sorudur ve cevapların bir yönde sallandığını görüyorum, bu yüzden diğer taraf için de oyunu oynayacağım, her iki cevabın doğru olduğunu iddia etmeme rağmen, bu çok yumuşak ve duruma göre bir konu.

Karmaşık ancak yüksek performanslı bir çözüm hakkında bir şey, her zaman sadece yaşayan haltını belgeleyebilirsiniz. Genelde kendi kendini belgeleyen kodun hayranıyım ancak aynı zamanda beni yavaşlatmıyor gibi hissettiren bir süre içinde yanıt veren bir yazılım hayranıyım. Karmaşık ancak yüksek performanslı bir çözüme giderseniz, o kadar da kötü olmamak için neler yapabileceğinizi düşünün:

Arayüze sarın, kendi başına bir düzene koyun, muhtemelen kendi başına bir işlem. Sızıntıları önlemek için mümkün olduğu kadar kalın bir soyutlama duvarıyla mümkün olduğunca gevşek bir şekilde bağlanmasını sağlayın . Gelecekteki gerilemeleri korumak için birçok birim sınama yazın.

Kodda belgeleyin, hatta bazı gerçek belgeler yazmayı düşünün. Karmaşık veri yapılarını ve nasıl belgelendiğini düşünün, açıklamak için bir veri yapıları kitabı / wikipedia makalesi olmadan kodlardan birinin uygulanmasını anlamaya çalışmayı hayal edin. Yine de hepimiz bu karmaşık veri yapılarının aslında iyi şeyler olduğunu kabul ediyoruz ve birisinin onları kendi dillerimizde uygulamasının faydası var.

Unutmayın ki hepimiz bir TCP / IP yığınında, herhangi birimizin bakması durumunda kodun alabileceği kadar harcanması muhtemel mesajlar gönderdiğimizi, açık bir şekilde hepimizin ihtiyaç duyduğu şekilde çalışacağını unutmayın. Belki de senin problemin bu optimizasyon seviyesini gerektirmiyor, belki de öyle, ama zaman zaman hepimizin yapması gerektiği gibi bu soruyla uğraşırken dikkatli olun: Orada ejderhalar var.


0

Bu çalışmaya, SLA'nın performans göstermediği alanlarda geliyorum. Bilgisayar grafiklerinde çevrimdışı oluşturucular söz konusu olduğunda, kullanıcılar için "tatmin edici bir performans" söz konusu değildir, çünkü kullanıcılar bilgisayarları bulutlara dağıtmak ve en gelişmiş üreticilerle bile çiftlikler oluşturmak için muazzam miktarda para harcıyorlar. Filmler için üretim kalitesinde görüntüler ve çerçeveler üretmek, örneğin

Ancak, bu alanda çalışan uzun yıllar boyunca çalışan biri olarak, sürdürülebilirliği verimlilik lehine önemli ölçüde azaltan herhangi bir çözümün aslında sürekli değişen performans gereksinimlerine karşı çalıştığını söylemeliyim. Çünkü işlerinizin ayağınızın altında kaymasıyla (hem çevre kodunda hem de rakiplerin birbirinden daha iyi performans göstermesini beklerken ne beklediği) yıllarca çözümünüzü etkin bir şekilde koruyamazsanız, o zaman çözümünüz zaten eskimiş ve toptan değiştirme ihtiyacı.

Kodumu daha hızlı çalıştırmanın bir yolu olarak VTune gibi profil oluşturucuların nihai amacını görmüyorum. Nihai değerleri, sürekli artan performans taleplerini karşılamak için verimliliğimi düşürmediğimden emin olmak. Kesinlikle brüt görünümlü bir mikro optimizasyon uygulamak zorunda kalırsam, o zaman gerçekleştirici kullanıcı davalarına karşı çalıştırma ile birleştirilen profilleyici (ve hayal ettiğim bazı test durumları önemli olmayabilir ), kaçınılmaz brüt görünümlü uygulama yaptığımdan emin oluyor optimizasyonlar çok, çok makul bir şekilde yalnızca en dikkat çekici görünen ve onları çok dikkatli bir şekilde belgeleyen görünen noktalardır.

Ve özellikle, optimize edilmiş çözümünüz daha fazla bağlantı içeriyorsa, o zaman kullanmakta isteksizimdir. Kod tabanının performans açısından en kritik alanlarında takdir ettiğim en değerli metrikler arasında ayrıştırma (bir şeyin çalışması gereken bilgi miktarını en aza indirgemek gibi, aynı şekilde doğrudan değişikliklere ihtiyaç duymadıkça değişiklik gerektirme olasılığını en aza indirir) Çünkü, bu kritik alanlar değişimlerin sebeplerini önemli ölçüde arttırıyor. Bu, bir şeyin çalışması için daha az bilginin, değişimin nedenlerinin azalmasının ve değişimin nedenlerinin en aza indirilmesinin, odak alanımdaki verimliliğin arttırılmasının çok büyük bir parçası olduğu anlamına gelir; çünkü işler yine de sürekli değişmek zorunda kalacak (biz Aksi takdirde bir yıl içinde modası geçmiş olur),

Bana göre bulduğum en büyük ve en etkili çözümler, verimlilik ve sürdürülebilirlik ile verimliliğin birbirine karşı çıkmadığı çözümler. Bana düşen görev, bu kavramları mümkün olduğu kadar uyumlu hale getirmeye çalışmak.

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.