Tek Bir Yazıda Big O Notasyonu: Kodunuzun Performansını Anlamanın Anahtarı!

Şule Akçay
5 min readMay 19, 2024

--

Herkese kocaman selamlar!

Bilgisayar mühendisliği dünyasında, kodun performansını değerlendirmek ve analiz etmek için birçok yöntem ve araç bulunmaktadır. Ancak, belki de en temel ve yaygın olarak kullanılanı Big O notasyonudur. Big O notasyonu, bir algoritmanın veya işlevin performansının asimptotik bir üst sınırını ifade eder. Yani, algoritmanın çalışma zamanının ve hafıza kullanımının giriş boyutuyla nasıl değiştiğini tanımlar.

Kodum hazır hedefe ulaştım. Sonucumu aldım benden iyisi yok diye düşünüyorsan ve daha önce çalışma süresi senin için önemsizse , diğer basamağa atlama zamanın gelmiş olabilir ! Kodunuzun çalışma süresi, performansı ve verimliliği açısından son derece önemlidir. Big O notasyonu, kodunuzun performansını analiz etmenin ve iyileştirmenin bir yoludur. Kodunuz ne kadar hızlı veya ne kadar fazla bellek kullanırsa, o kadar verimsiz olabilir ve kullanıcılarınızın deneyimini olumsuz etkileyebilirsiniz. Big O notasyonu, algoritmanızın zaman ve hafıza karmaşıklığını belirlemeye yardımcı olarak, kodunuzun performansını tahmin etmenize ve iyileştirmenize olanak tanır. Bu nedenle, kod yazarken Big O notasyonunu göz önünde bulundurmak, daha etkili ve verimli yazılım geliştirmenin önemli bir adımıdır.

Time Complexity (Zaman Karmaşıklığı) Nedir ?

Zaman karmaşıklığı algoritmanın çalışma süresinin girdi boyutuna göre nasıl değiştiğini ifade eder. Başka bir deyişle, bir algoritmanın ne kadar hızlı veya yavaş çalıştığını anlamamıza yardımcı olur. Bir algoritmanın zaman karmaşıklığı genellikle algoritmanın içindeki işlem adımlarının girdi boyutuna (genellikle n olarak gösterilir) bağlı olarak sayılmasıyla belirlenir. Örneğin, bir algoritmanın zaman karmaşıklığı O(n) ise, bu algoritmanın çalışma süresinin girdi boyutuyla doğrusal olarak arttığı anlamına gelir. Yani, girdi iki katına çıkarsa, algoritmanın çalışma süresi de yaklaşık olarak iki katına çıkar. Zaman karmaşıklığı analizi, algoritmaları performans açısından değerlendirmek ve karşılaştırmak için önemli bir araçtır. Bu sayede, hangi algoritmanın verimli olduğunu anlayabilir ve en uygun olanı seçebiliriz.

Big O Notasyon Çeşitleri Nelerdir ?

O(1) Constant Complexity

Algoritmanın çalışma süresi girdinin boyutundan bağımsızdır. Yani, algoritmanın performansı sabittir. Bu durumda her algoritma aynı sürede çalışır.

def my_func(first_list):
print(first_list[0])

first_list = [1,2,3]

my_func(first_list)

O(n) (Linear Complexity):

Algoritmanın çalışma süresi, girdinin boyutuyla doğru orantılıdır. Yani, girdi arttıkça algoritmanın çalışma süresi de doğrusal olarak artar.

def my_func(first_list):
for item in first_list:
print(item)

first_list = [1,2,3]

my_func(first_list)

O(n²) (Quadratic Complexity):

Algoritmanın çalışma süresi, girdinin karesi ile orantılıdır. Bu tür algoritmalar genellikle iç içe döngülerle karakterizedir.

def my_func(first_list):
for i in range(len(first_list)):
for j in range(len(first_list)):
print(first_list[i], first_list[j])

first_list = [1,2,3]

my_func(first_list)

O(log N) (Logarithmic Complexity):

Algoritmanın çalışma süresi, girdinin logaritması ile orantılıdır. Bu tür algoritmalar genellikle veri yapılarındaki hızlı erişim veya sıralama algoritmalarında bulunur.

def binary_search(arr, target):
low, high = 0, len(arr) - 1

while low <= high:
mid = (low + high) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
low = mid + 1
else:
high = mid - 1

return -1

my_list = [1, 3, 5, 7, 9]

target = 5

result_index = binary_search(my_list, target)
if result_index != -1:
print("Eleman", target, "listede", result_index, "indeksinde bulundu.")
else:
print("Eleman", target, "liste içinde bulunamadı.")

O(nlog N) (Logarithmic Complexity):

Algoritmanın çalışma süresi, girdinin boyutu ile logaritmasının çarpımı ile orantılıdır. Bu karmaşıklık sınıfına sahip algoritmalar genellikle hızlı sıralama gibi sıralama algoritmalarında görülür.

def merge_sort(arr):
if len(arr) <= 1:
return arr

mid = len(arr) // 2
left_half = merge_sort(arr[:mid])
right_half = merge_sort(arr[mid:])

return merge(left_half, right_half)

def merge(left, right):
result = []
i = j = 0

while i < len(left) and j < len(right):
if left[i] < right[j]:
result.append(left[i])
i += 1
else:
result.append(right[j])
j += 1

result.extend(left[i:])
result.extend(right[j:])

return result

my_list = [5, 3, 8, 2, 7, 1, 4, 6]

sorted_list = merge_sort(my_list)
print("Sıralanmış liste:", sorted_list)

O(c^N) (Exponential Complexity):

Algoritmanın çalışma süresi, bir sabit sayının n üzerindeki üssüne orantılıdır. Bu tür algoritmalar genellikle çok yavaşdır ve büyüdükçe hızlı bir şekilde performansları kötüleşir.

def func_fibonacci(n):
if n <= 1:
return n
else:
return func_fibonacci(n-1) + func_fibonacci(n-2)

for i in range(10):
print(func_fibonacci(i), end=" ")

O(N!) (Factorial Complexity):

Algoritmanın çalışma süresi, girdinin faktöriyeline orantılıdır. Bu tür algoritmalar genellikle permütasyon veya kombinasyon problemlerini çözmek için kullanılır ve genellikle çok yavaşdır.

import itertools

def func_permutation(n):
numbers = list(range(1, n + 1))
perm_list = list(itertools.permutations(numbers))
return perm_list


permutations = func_permutation(4)

for perm in permutations:
print(perm)

Bu yazı özelinde öğrendiklerimizi özetlememiz gerekirse ,

Bilgisayar bilimlerinde temel bir kavram olan Big O notasyonunu inceledik ve çeşitlerini öğrendik. Yazılım geliştirme süreçlerinde Big O notasyonunun önemi göz ardı edilemez. Kodun zaman ve hafıza karmaşıklığını belirlemek ve iyileştirmek için bu notasyonu kullanmak, tüm yazılım geliştirme ekibinin performansını optimize etmek ve kullanıcı deneyimini iyileştirmek için önemlidir.

Zaman karmaşıklığı, bir algoritmanın girdi boyutuna bağlı olarak nasıl değiştiğini ifade eder. Big O notasyonu, bu karmaşıklığı analiz etmenin ve algoritmalar arasında karşılaştırma yapmanın bir yoludur. O(1) sabit karmaşıklıktan O(N!) faktöriyel karmaşıklığa kadar geniş bir yelpazede algoritmaları temsil eder.

Yazılım geliştiriciler olarak, Big O notasyonunu anlamak ve uygulamak, kodun performansını optimize etmek ve kullanıcı deneyimini iyileştirmek için önemlidir. Bu nedenle, kod yazarken ve algoritma seçerken Big O notasyonunu göz önünde bulundurmak, başarılı bir yazılım geliştirme pratiğinin vazgeçilmez bir parçasıdır.

Tüm yazılım geliştirme ekibi, Big O notasyonunu kullanarak kodu daha verimli hale getirebilir ve daha iyi sonuçlar elde edebilir. Küçük optimizasyonlar, büyük başarıların temelini oluşturabilir.

Harika bir süreçti ! Bir sonraki yazımda görüşmek üzere…

Thanks -> Next!

Kaynaklar

--

--