‘İyi kod’ nasıl yazılır?
İyi kod anlaşılabilirlik ve ölçülebilirlik özelliklerini taşıyan koddur. Anlaşılabilirlik kısmı başkaları tarafından okunduğunda akılda soru işaretleri kalmaması olarak açıklanabilir. Ölçülebilirlik kısmı ise Big O konusunu içeren kısımdır. Şimdi adım adım ölçülebilirlik ve big o konularına değineceğiz.
Aşağıda bir array girdisi alan gizembul() functionını oluşturduk ve gizemi bulmasını istedik.

Şimdide for döngüsünden önce ve sonra zaman ölçümü yaparak döngünün ne kadar sürede çalıştığını görelim.

Gördüğümüz gibi oldukça küçük bir süre ama daha büyük bir listede arama yapıldığında for döngüsü daha çok çalışacağı için çalışma süresi de artar. Şimdi 100 tane gizem içeren bir array oluşturalım ve çalışma süresine bakalım.

Görüldüğü gibi oldukça farklı, bu arrayi 1000 tane gizem içerecek yaparsanız sonuc daha da artacaktır.
2 farklı kişinin kendi bilgisayarlarında kod yazdığını düşünelim. Ayşe aynı işlevi yapan kodu 3.5 sn büyüklüğünde yazmış, Mine ise 1.5 sn. Mine daha iyi bir kod yazmış diyebilir miyiz? Tabi ki hayır. Bu da bir ölçüttür fakat kodun daha hızlı çalışması daha iyi diyebilmemiz için yeterli değildir. Bilgisayar hızı gibi diğer etkenler de göz önünde bulundurulmalıdır. Peki bunu nasıl anlarız?
Time Comlexity bir algoritmanın çalışması için gerekli süredir. Big O ise bir algoritmanın çalışması için geçen sürenin hesaplanması için kullanılan bir dildir. Big O kullanarak hangi algoritmanın daha iyi olduğuna karar verebiliriz. Burada yukarıdaki örnekte bahsettiğimiz sorunun yaşanmaması için geçen süreye değil kaç tane işlem yapıldığına bakılır. Big O ölçüm şeması aşağıdaki gibidir.

İlk baÅŸta oldukça karışık göründüğünün farkındayım fakat inceledikçe gayet anlaşılır hale gelecektir.:) Grafikte görüldüğü gibi elements sayısı artıp operations yani iÅŸlem azaldıkça kod iyidir diyebiliriz.(Big O ‘O(…)’ ÅŸeklinde ifade edilir.)
Peki gizembul fonksiyonunu big O ile ölçmek istersek nasıl ölçeriz?
Bu fonksiyonda her bir eleman için for döngüsü çalışır. Yani 100 elements içeren gizembul fonksiyonunun operations sayısı da 100 dür. Bu bir O(n) örneğidir. Linear Time olarak adlandırılır.
Peki fonksiyonumuz aşağıdaki gibi bir arraydeki ilk elemanı alan bir fonksiyon ise nasıl hesaplarız?
Bu fonksiyonda boxes arrayi 10 elamana yada 10000 elemana sahip olması bir ÅŸey deÄŸiÅŸtirmez. Bu bir O(1) – Constant Time ifadesidir. Çünkü array de sadece 1. eleman için iÅŸlem yapılır.



Peki Fonksiyonumuz yukarıdaki gibi olsaydı nasıl hesaplardık?
Her çektiğimiz eleman için bir tane O(1) hesaplanır. Bu fonksiyonda 2 eleman çekildiği için O(2), eğer 3 eleman çekilseydi O(3) olacaktı. Operations sayısı da doğru orantılı artacaktır.
Aşağıda bir fonksiyonun büyüklüğü her adımda yanlarına yorumlanarak gösterilmiştir.
Big O hakkında sorularınız için ‘https://www.quora.com/What-is-the-difference-between-big-oh-big-omega-and-big-theta-notations‘ sitesine göz gezdirebilirsiniz. Bu gibi siteleri aÅŸağıda paylaÅŸacağım.
Big O hesaplanırken temelde 4 kurala dikkat ederiz. Sırasıyla inceleyelim
1. Worst Case
Bir fonksiyon her zaman en kötü senaryoyu düşünerek yazılmalıdır. Örneğin ilk yaptığımız gizemiBul fonksiyonunda array list uzunluğu kadar for loopumuz dönecek. Listenin 10 elemanı varsa gizem in listenin kaçıncı sırasında olduğunun önemi yok. For döngüsü 10 defa çalışır.Gizem 4. sıradaysa if döngüsünün içerisinde console.log komutundan sonra break komutu kullanırız ki fazladan 6 defa daha dönmesin. Bunun gibi tüm worst case durumlarında en kötü senaryo düşünülerek kod yazılır ki big 0 büyümesin.

2. Remove Constants
Yukarıda Big O hesaplarken ‘O(3+4n)’ gibi bir deÄŸer bulmuÅŸtuk. Fakat normalde sonuç böyle olmaz. Big O grafiÄŸinden gösterdiÄŸimiz deÄŸerlere sahip olur. AÅŸağıdaki örnek kod parçasını hesapladığımızda Big O(1+n/2+100) gibi bir deÄŸer ortaya çıkar ama bu deÄŸer grafikte yer almıyor. O(1+n/2+100)>O(n/2+101) > O(n) ÅŸeklinde bir dönüşüm yaÅŸanır. n’nin çok büyük ve belirsiz bir deÄŸer olduÄŸunu düşürsek onun 2 ye bölünmesi de sayısal bir deÄŸerle toplanması da bizim için anlamsızdır.

Eğer bir kod parçasında 2 tane for döngümüz var ise büyüklük O(2n) dir. Buda O(n) e eşittir. Fakat bu büyüklük grafikteki O(n) aralığının daha yukarısında yer alır çünkü daha fazla operasyon içerir.
3. Different Terms for Inputs
Eğer bir fonksiyon 2 tane for döngüsü içeriyorsa yukarıda O(2n) büyüklüğündedir ve buda O(n) e eşittir demiştik. Peki bu fonksiyon 2 farklı inputa sahipse ve for döngüleri farklı inputlarla çalışıyorsa? Bu durumda maalesef yukarıdaki gibi O(n) olmaz. O(a+b) gibi bir değere sahip olur. Peki bu for döngüleri iç içeyse? Örneğin;

Her bir karakter için karakter sayısı kadar döngüyü çalıştırdı. Bu da O(n^2) ye eşittir. Grafikte bu değerin horrible bölgesinde olduğunu görürüz. Listedeki değer sayısı arttıkça, işlem arttıkça sonuç oldukça hızlı büyür. Bazen bu kırmızı bölgedeki değerleri nasıl sarı ve yeşil bölgeye çekeceğimize dair sorularla karşılaşabiliriz. Yukarıdaki gibi içiçe döngüler farklı inputlara sahip olsaydı sonuç O(a*b) olurdu.
4. Drop Non Dominants
Aşağıdaki örneği inceleyelim.

Burada O(n+n^2) değerini buluruz ve buda O(n^2) değerine eşit olur. 1. n değerini görmezden geliriz çünkü n^2 çok daha büyüktür ve her n değerini kapsar. O(n+100) deyinde n değerini seçiyoruz ya n değeri 100 den küçükse diye düşünebilirsinizz. Ama biz Big O hesaplarken çok büyük veriler üzerinde işlem yapıyoruz. Bu yüzden büyük aralığı n olarak görüyoruz.
NOT: Yukarıda sık sık arraylerden bahsettim, detaylı bilgi için; ‘https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array‘ .Object için; ‘https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object‘
Kısaca O(n!) konusuna da deÄŸinelim. Umarım hiç karşılaÅŸmazsınız. EÄŸer karşılaşırsanız bir hata yapıyorsunuz demektir, grafikteki en dik eÄŸri. Sahip olduÄŸumuz her deÄŸiÅŸken için iç içe bir döngü demektir. Yinelenen her öge için bir döngü ekleniyor. Daha detaylı görmek için; ‘https://stackoverflow.com/questions/3953244/example-of-on‘
Bir kodun iyi olmasını okunabilirliÄŸine ve ölçülebilirliÄŸine baÄŸlamıştık. ÖlçülebilirliÄŸini ise hızına ve belleÄŸe baÄŸlayabiliriz. Hız konusuna detaylıca deÄŸindik, hafize kısmı ise oldukça basit. Çok yer kaplıyor ise iyi deÄŸildir :). Hız konusu ‘Time Complexity’, hafıza konusu ise ‘Space Complexity’ olarak adlandırılır. Bazen kodar daha az yer kaplayacak hale getirilmeye çalışılır. Hafıza ne kadar input kullandığınız gibi durumlardan etkilenir. Inputlara müdahale edemesekde fonksiyonun içinde neler yaptığımızla hafızayı daha az kullanabiliriz.
Aşağıya ingilizce olarak yukarıda anlattıklarımın özetini iliştiriyorum.
Big O hangi algoritmanın en iyi olduğunu söyler. Big O sayesinde şirketler oldukça para birikimi yapabilir. Konuyu burada sonlandırıyorum :). Daha detaylı bilgiler için satır aralarında verdiğim linklerde araştırmalar yapabilirsiniz.
Bu notlar hem kendim için döküman oluşturmak hemde fikir sahibi olmak isteyen kişileri az da olsa kendimce yönlendirmek için yazılıyor 🙂

Have a nice day 🙂





