Vakitsiz/Erken Optimizasyon (“Premature Optimization”) Karşıt Örüntüsü

Evet sevgili yazılımperver dostlarım bu ve sonraki birkaç yazımda, farkında olmanız gereken karşıt-örüntülerden (“anti-pattern”)’lerden bahsetmeye çalışacağım. Kısacası, kaçınmanız gereken hususlar. Bunların bir kısmına, daha önceki yazılarımda değinmiş olmam muhtemel, bu yazılarda, bu hususlara daha yakında bakıyor olacağız.
İlk bakacağımız husus, “Premature Optimization”, bir diğer ifade ile, Vakitsiz/Erken Optimizasyon durumu. Hemen, bu konu ile ilgili bir söz ile başlayalım 🙂

The first rule of program optimization: Don’t do it. The second rule of program optimization (for experts only!): Don’t do it yet. (Program optimizasyonun ilk kuralı: Yapmayın. İkinci kuralı ise (sadece uzmanlar için): Şimdi yapmayın!)

Her ne kadar bu duruma ilk değinen Randall Hyde olsa da, bunu göz önünde tutan Donald Knuth olmuştur. Konu başlığında da yer verdiğimiz sözlerin (“Premature optimization is the root of all evil”) tamamı aslında aşağıdaki gibidir:

The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times; premature optimization is the root of all evil (or at least most of it) in programming. (Asıl sorun, programcıların yanlış yerlerde ve yanlış zamanlarda verimlilik konusunda endişelenerek çok fazla zaman harcamasıdır; erken optimizasyon, programlamadaki tüm kötülüklerin (veya en azından çoğunun) kaynağıdır.)

Bu söz, yazımızın temel motivasyonunu ve içeriğini çok güzel özetliyor.

Tabi burada ele alacağımız durumu, hiç optimizasyon yapmayalım olarak da ele almamamız lazım, duruma göre değerlendirmek ve bunu yaparken de, belirli kriterleri göz önünde bulundurmak çok önemli. Bu sebeple, probleme farklı çerçevelerden bakıyor olacağız. Kısaca, vakitsiz optimizasyon yapmayacağız diye, aşikar veya bilindik bir takım hususları da göz ardı etmemeliyiz.

Peki “Premature Optimization” nedir?

Bu başlığa da, Knuth’ın bu konuya ilişkin başka bir sözü ile başlamak istiyorum:

Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%. (Programcılar, programlarının kritik olmayan bölümlerinin hızı hakkında düşünmek veya bunlarla ilgili endişe duymak için çok zaman harcarlar ve bu verimlilik girişimleri, hata ayıklama ve bakım düşünüldüğünde aslında ciddi bir olumsuz etkiye sahiptir. Küçük verimlilik girişimlerini unutmalıyız, örneğin, zamanın yaklaşık %97’sinde: erken optimizasyon tüm kötülüklerin kaynağıdır. Yine de, kalan %3’lük kritik performans iyileştirme fırsatlarımızı kaçırmamalıyız.)

Geliştirdiğiniz yazılımlara ilişkin, hangi noktalarda ve nasıl optimizasyon yapabileceğinize ilişkin elinizde yeterli bilgi bulunmadan, yapılan optimizasyonları, Vakitsiz/Erken Optimizasyon olarak isimlendirebiliriz.
Peki bu durum nasıl karşımıza çıkıyor ya da bunu yaptığımızı nasıl anlayabiliriz diye soracak olursanız, bunu anlamanıza yardımcı olabilecek birkaç örneği sıralamak istiyorum:

  • İhtiyaçlar netleşmeden hangi veri yapısı ya da algoritmayı kullanacağınıza karar vermeye dalmışsanız,
  • Nasıl kullanılacağı hatta kullanılıp/kullanılmayacağı netleşmemiş bir fonksiyon ya da veri yapısı için gereğinden fazla uğraşıyorsanız,
  • Henüz elinizde çalışır durumda bir yazılım yokken, performansını arttırmaya yönelik kendinizi uğraşır buluyorsanız,
  • Benzer şekilde, çalışır yazılımınız var ama doğru çalışıp/çalışmadığından emin değilken, performansını arttırmaya yönelik kendinizi uğraşır durumda buluyorsanız

oturup düşünmenizde fayda var.

Elbette, bu durumlar dışında, elinizde yeterli bilgi olduğu durumlarda ya da çok kısıtlı kaynaklara sahip sistemler için yazılım geliştirme durumundaysanız, optimizasyon gerekli de olabilir.

Bu probleme benzer bir diğer karşıt örüntü de “bikeshedding“‘tir. Bu örüntü de, insanların, nispeten önemsiz konulara gereğinden fazla zaman harcaması durumunu adresler. Bu örüntüye de ayrı bir yazımda değineceğim.

Peki bu neden kötü?

Çünkü, bir önceki başlıkta belirttiğim gibi, elinizde yeterli bilgi olmadan, pratikte nerede hangi noktalarda, optimizasyona ihtiyaç olduğunu bilmek oldukça zor olabilir. Bunun ile birlikte, bu bilgiye sahip olmadan önce yapılacak olan optimizasyon girişimleri de genellikle, kodun karmaşıklığını arttırmaya, daha fazla hataya ve aslında çok da önemli olmayan iyileştirmelere yol açabilir. Bazı durumlarda, ilerleyişinizi de durdurabilir, durdurmasa bile ileride yapılabilecek ya da yapılması gereken güncellemelerin uygulanmasını oldukça zorlaştırabilir.

Sonuç olarak, bu tarz girişimler, çoğunlukla, zaman, kaynak ve elbette motivasyon kaybına yol açabilmektedir.

Peki bunu nasıl anlarız?

Önceliğiniz, her zaman için temiz, okunabilir ve tabi ki çalışan kod elde etmek olmalı. Bunu da yaparken, mevcut algoritma ve yaklaşımları muhakkak göz önünde bulundurmalıyız.

Ardından, çeşitli ölçüm (“profiling”) araçları kullanarak (o da ihtiyaç olursa), sıkıntılı ve optimizasyona ihtiyaç duyulan noktaları belirlemeliyiz. Daha önce de ifade edildiği üzere burada önemli olan, tahminler yerine, ölçümleri referans almaktır.

Bunlar yanında, yapılacak optimizasyonlara ilişkin, aşağıdaki soruları olabildiğince objektif bir şekilde yanıtlamak da sizlere yardımcı olacaktır:

  • Neden yapmak istiyorsunuz? (Şu an için, bu aşamada bu gerçekten gerekli mi?)
  • Beklentileriniz, kazancınız neler? (Ne kadarlık bir yavaşlık var, ya da ne kadarlık bir kazanç bekliyoruz?)
  • Maliyeti ne olacak? (Yeterli vakit, kaynak var mı?)
  • Olası negatif sonuçları neler olabilir ya da bu optimizasyonun anlmasız olma olasılığı var mı? (Bunu görmek çok kolay olmayabilir ama buna kafa yormak kesinlikle sizler için faydalı olacaktır)
  • Bunu şu an yapmanızın ya da yapmamanızın sebep olabileceği sıkıntılar var mı? (Daha önemli olan kabiliyetleri geliştirmeniz gecikiyor mu? Ya da bunu yapmamamızın yazılım için bir tehlikesi var mı?)
  • Bunun üzerinde çalışmıyor olsanız, başka yapabileceğiniz bir şey var mı?

Bu sorular ışığında ilgili önceliklerinizi belirleyebilir, gereksiz optimizasyondan kaçınabilirsiniz.

Peki neleri bunun dışında tutmamız lazım?

Birkaç kere değindiğim üzere, erkenden optimizasyon yapmamamız, bazı aşikar hususları göz ardı edeceğimiz anlamına gelmiyor. Özellik kullanılacak veri yapıları ve algoritmalarda bunu göz önünde bulundurabilirsiniz. Örneğin, yığın kullanımının uygun olduğu yerlerde tutup farklı veri yapıları kullanmak da doğru olmayabilir. Burada yine temel veri yapıları ve algoritmalar ile başlayıp, daha sonra veri yapıları ve algoritmalarınızı probleminize özgü bir şekilde özelleştirebilirsiniz. BigO analizleri (yer ve çalışma zamanı) konusunda sizlere yardımcı olacaktır.

Dikkat edilmesi gereken konulardan birisi de, erken optimizasyonun daha doğrusu optimize kodun, kötü koda bir bahane olarak kullanılmasına da karşın uyanık olmamız lazım. Yani, optimize kodların, okunamaz olacağı diye bir durum söz konusu olmadığı gibi, okunabilir kodların da yavaş ya da performans anlamında kötü olur gibi bir kabul yapmak doğru değildir.

Her şey de olduğu gibi, bu durumu da kötüye kullanma ve yanlış kullanıma ilişkin durumlar da söz konusu olabilmektedir. Buna ilişkin de güzel bir kaynağı, kaynaklar kısmına ekliyorum, bir göz atmanızda fayda var. Bu kaynak içerisinde, bu karşıt-örüntüye uyarken nelere dikkat etmek gerektiği 9 temel gözlem ile aktarılmakta.

C++ özelinde, yazılım geliştirecek arkadaşlar için, benzer şekilde, her türlü uygulanabilecek bir takım optimizasyon tavsiyeleri için de ayrı bir yazı yazmayı planlıyorum 😉

Sonuç

Uzun lafın kısası, optimize etmeden önce, muhakkak ölçüm yapmalısınız ve çok özel bir sebebiniz olmadığı müddetçe, basitlik ve okunabilirlikten ödün vermemelisiniz.

Emin olamadığınız durumlarda, şu kısa üç adım size rehber olabilir:

  1. Çalışır hale getir,
  2. Doğru hale getir,
  3. Hızlandır.

Bir sonraki yazımda görüşmek dileğiyle, hepinize iyi bayramlar diliyorum.

Kaynaklar

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Bu site, istenmeyenleri azaltmak için Akismet kullanıyor. Yorum verilerinizin nasıl işlendiği hakkında daha fazla bilgi edinin.