Python Performans İpuçları

Python kodlarının daha hızlı ve verimli çalışması için performans artırıcı ipuçlarını öğrenin.

Python kodlarının daha hızlı çalışması için birçok yöntem ve ipucu bulunmaktadır. Ancak en önemli kural şudur: **"Önce ölç, sonra optimize et!"** Yani, kodunuzun nerede yavaşladığını bilmeden optimizasyon yapmaya çalışmak genellikle zaman kaybıdır ve gereksiz karmaşıklık yaratabilir. İşte Python kodunuzu hızlandırmak için kullanabileceğiniz başlıca ipuçları: --- ### 1. Algoritma ve Veri Yapısı Seçimi (En Büyük Etki) Kodunuzun performansını en çok etkileyen faktör, kullandığınız algoritma ve veri yapısıdır. Kötü bir algoritma, ne kadar optimize ederseniz edin yavaş kalacaktır. * **Doğru Veri Yapısını Kullanın:** * `list` (liste): Sıralı veri için iyi, ancak eleman aramak (`in`) O(n) karmaşıklığındadır. * `set` (küme): Elemanların benzersiz olması gerektiğinde ve hızlı arama, ekleme, silme işlemleri için (ortalama O(1)). * `dict` (sözlük): Key-value çiftleri için ve hızlı arama (ortalama O(1)). * `collections.deque`: Listenin hem başından hem sonundan hızlı ekleme/çıkarma işlemleri için (O(1)). * **Daha Verimli Algoritmalar Kullanın:** Örneğin, O(n^2) bir algoritma yerine O(n log n) veya O(n) bir algoritma bulmaya çalışın. Büyük veri kümelerinde bu fark muazzamdır. --- ### 2. Pythonik ve İdeal Kod Yazımı Python'ın sunduğu yerleşik özellikleri ve "Pythonik" yaklaşımları kullanmak genellikle daha hızlı kod üretir çünkü bunlar C ile optimize edilmiş olabilirler. * **List Comprehensions ve Generator Expressions Kullanın:** * `[x for x in iterable if condition]` (List Comprehension) genellikle döngülerden daha hızlıdır ve daha okunabilirdir. * `(x for x in iterable if condition)` (Generator Expression) ise elemanları tek tek ürettiği için özellikle büyük veri kümelerinde hafıza dostudur ve gerektiğinde daha hızlı olabilir. * **`"".join()` Kullanın, `+` ile String Birleştirmekten Kaçının:** Bir döngü içinde `str = str + char` yapmak çok yavaştır çünkü her seferinde yeni bir string nesnesi oluşturulur. Bunun yerine `"".join(list_of_chars)` kullanın. ```python # Yavaş my_string = "" for char in my_list_of_chars: my_string += char # Hızlı my_string = "".join(my_list_of_chars) ``` * **Yerleşik Fonksiyonları Kullanın:** `map()`, `filter()`, `sum()`, `max()`, `min()`, `any()`, `all()`, `zip()` gibi yerleşik fonksiyonlar genellikle C dilinde optimize edilmiştir ve manuel döngülerden daha hızlıdır. ```python # Yavaş result = [] for x in numbers: result.append(x * 2) # Hızlı result = list(map(lambda x: x * 2, numbers)) # Daha Pythonik ve genellikle hızlı result = [x * 2 for x in numbers] ``` * **Global Değişken Erişiminden Kaçının:** Bir fonksiyon içinde sıkça kullanılan global bir değişkeni, fonksiyonun başında lokal bir değişkene atamak (eğer değeri değişmeyecekse) erişim hızını artırabilir. * **Nokta Erişimi Azaltın:** `obj.attribute.method()` gibi zincirleme erişimler yerine, sıkça kullanılan parçaları lokal değişkenlere atamak küçük bir hız artışı sağlayabilir (özellikle sık tekrar eden döngülerde). * **`in` Operatörünü Küme (`set`) veya Sözlük (`dict`) ile Kullanın:** Bir listede eleman aramak O(n) iken, küme veya sözlükte aramak ortalama O(1)'dir. * **`if/elif/else` yerine `dict` Kullanın:** Çok sayıda `if/elif` koşulunuz varsa, bir sözlük kullanarak anahtara göre işlem seçimi yapmak daha hızlı ve okunabilir olabilir. * **`isinstance()` yerine duck typing tercih edin:** Mümkün olduğunca bir objenin belirli bir tipe ait olup olmadığını kontrol etmek yerine, o objenin ihtiyacınız olan metotlara sahip olup olmadığını kontrol edin. --- ### 3. Profilleme ve Ölçümleme Araçları Nerede yavaşladığınızı bilmek için kodunuzu ölçmeniz şarttır. * **`timeit` Modülü:** Küçük kod parçalarının performansını ölçmek için idealdir. ```python import timeit setup_code = "my_list = list(range(1000))" test_code_slow = 'result = []\nfor x in my_list: result.append(x*2)' test_code_fast = 'result = [x*2 for x in my_list]' print(timeit.timeit(test_code_slow, setup=setup_code, number=10000)) print(timeit.timeit(test_code_fast, setup=setup_code, number=10000)) ``` * **`cProfile` veya `profile` Modülü:** Kodunuzun hangi fonksiyonlarda ne kadar zaman harcadığını gösteren detaylı raporlar sunar. Bu, "hot spot"ları (darboğazları) bulmak için çok güçlüdür. ```python import cProfile def my_slow_function(): total = 0 for i in range(1000000): total += i * i return total def my_program(): my_slow_function() # ... diğer kodlar ... cProfile.run('my_program()') ``` * **`line_profiler`:** Hangi kod satırının ne kadar zaman aldığını gösterir. Daha detaylı analiz için kullanışlıdır (`pip install line_profiler` ile yüklenir). * **`memory_profiler`:** Kodunuzun hafıza kullanımını izler (`pip install memory_profiler` ile yüklenir). --- ### 4. Harici Kütüphaneler ve Derlenmiş Kod Kullanımı Python yorumlayıcısı doğası gereği yavaştır. Performans kritik kısımlar için C/C++ ile yazılmış kütüphaneleri veya JIT (Just-In-Time) derleyicilerini kullanmak büyük fark yaratabilir. * **NumPy ve SciPy:** Sayısal işlemler, dizi manipülasyonları için vazgeçilmezdir. Temelde C ile yazılmışlardır ve saf Python döngülerinden kat kat hızlıdır. * **Pandas:** Veri analizi için NumPy üzerine kurulmuştur ve yüksek performans sunar. * **Cython:** Python kodunuzu C koduna dönüştürerek derlemenizi sağlar. Özellikle CPU yoğun döngülerde büyük hız artışı sağlar. Python sözdizimini kullanmaya devam edersiniz. * **Numba:** Python kodunuza `@jit` dekoratörünü ekleyerek, kodunuzu JIT (Just-In-Time) derleyicisi ile makine koduna dönüştürür. Özellikle sayısal algoritmalar ve döngüler için çok etkilidir. ```python from numba import jit @jit(nopython=True) # nopython=True saf Python modunda çalışmayı garanti eder def fast_function(x, y): return x + y ``` * **PyPy:** CPython'a alternatif bir Python yorumlayıcısıdır. Yerleşik bir JIT derleyicisi vardır ve saf Python kodunu CPython'dan çok daha hızlı çalıştırabilir. Ancak tüm CPython uzantı kütüphaneleriyle uyumlu olmayabilir. --- ### 5. Hafıza Yönetimi ve Nesne Optimizasyonları Daha az hafıza kullanmak, dolaylı olarak daha hızlı çalışmaya yol açabilir. * **Generator Kullanımı:** Liste oluşturmak yerine generator'lar kullanarak büyük veri kümelerinde hafıza kullanımını azaltın. ```python # Hafızada tüm listeyi oluşturur large_list = [i*i for i in range(10000000)] # İhtiyaç duyuldukça elemanları üretir, hafıza dostudur large_generator = (i*i for i in range(10000000)) ``` * **`__slots__` Kullanımı:** Sınıf örneklerinizin (instance) hafıza ayak izini azaltmak ve öznitelik erişimini hızlandırmak için `__slots__` kullanabilirsiniz. Özellikle çok sayıda nesne oluşturuyorsanız faydalıdır. ```python class MyClass: __slots__ = ('x', 'y', 'z') # Sadece bu özniteliklere sahip olabilir def __init__(self, x, y, z): self.x = x self.y = y self.z = z ``` * **Aynı Nesneleri Yeniden Kullanma:** Mümkün olduğunda yeni nesneler oluşturmak yerine mevcut nesneleri yeniden kullanın veya değiştirin. --- ### 6. Paralel İşleme ve Eşzamanlılık * **`multiprocessing` Modülü:** Python'ın GIL (Global Interpreter Lock) kısıtlamasını aşarak birden fazla CPU çekirdeğini kullanmanızı sağlar. CPU yoğun görevler için idealdir. * **`threading` Modülü:** G/Ç (I/O) yoğun görevler için (dosya okuma/yazma, ağ istekleri vb.) faydalıdır. Ancak GIL nedeniyle CPU yoğun görevlerde gerçek paralel çalışma sağlamaz. * **`asyncio` (Asynchronous I/O):** Tek bir iş parçacığında eşzamanlı G/Ç operasyonları yönetmek için kullanılır. Web sunucuları veya ağ istemcileri gibi G/Ç beklentisi olan uygulamalar için çok verimlidir. --- ### 7. Önemli Notlar * **Erken Optimizasyondan Kaçının:** Kodunuz çalışır duruma gelmeden ve darboğazları belirlemeden optimizasyon yapmaya çalışmayın. "Premature optimization is the root of all evil." (Donald Knuth) * **Okunabilirlik Önemlidir:** Her zaman performansa odaklanmak, okunması ve bakımı zor kodlar yazmanıza neden olabilir. Performans optimizasyonları yaparken okunabilirlik ve sürdürülebilirliği dengede tutmaya çalışın. * **İşletim Sistemi ve Donanım:** Kodunuzun çalıştığı donanım ve işletim sistemi de performansı etkileyebilir. Özellikle G/Ç hızı, CPU gücü ve RAM miktarı önemlidir. --- Yukarıdaki ipuçlarını kullanarak Python kodunuzun performansını önemli ölçüde artırabilirsiniz. Başlangıç noktanız her zaman profil (ölçüm) araçları olmalıdır.
Son Paylaşımlar
Kategoriler