Daha İyi Performans İçin Python Komut Dosyalarınızı Nasıl Optimize Edebilirsiniz?

Daha Iyi Performans Icin Python Komut Dosyalarinizi Nasil Optimize Edebilirsiniz



Python komut dosyalarını daha iyi performans için optimize etmek, kodumuzdaki darboğazları belirleyip ele almayı ve kodun daha hızlı ve daha verimli çalışmasını sağlamayı içerir. Python, günümüzde veri analizi, makine öğrenimi projeleri (makine öğrenimi), web geliştirme ve çok daha fazlası dahil olmak üzere çok sayıda uygulamada kullanılan popüler ve güçlü bir programlama dilidir. Python kod optimizasyonu, daha az kod satırı, daha az bellek veya ek kaynak kullanarak herhangi bir etkinliği gerçekleştirirken geliştirici programının hızını ve verimliliğini artırmaya yönelik bir stratejidir. Büyük ve verimsiz kod, programı yavaşlatabilir ve bu da müşteri memnuniyetinin azalmasına ve potansiyel mali kayba veya düzeltme ve sorun giderme için daha fazla çalışma yapılmasına ihtiyaç duyulmasına neden olabilir.

Birkaç eylemin veya verinin işlenmesini gerektiren bir görevi yaparken gereklidir. Bu nedenle, bazı etkisiz kod bloklarını ve işlevlerini devre dışı bırakmak ve geliştirmek, aşağıdaki gibi şaşırtıcı sonuçlara yol açabilir:

  1. Uygulamanın performansını artırın
  2. Okunabilir ve düzenli kod oluşturun
  3. Hata izlemeyi ve hata ayıklamayı basitleştirin
  4. Önemli miktarda hesaplama gücünden tasarruf edin vb.

Kodunuzun Profilini Oluşturun

Optimize etmeye başlamadan önce proje kodunun onu yavaşlatan kısımlarını belirlemek önemlidir. Python'da profil oluşturma teknikleri cProfile ve profil paketlerini içerir. Belirli işlevlerin ve kod satırlarının ne kadar hızlı yürütüldüğünü ölçmek için bu tür araçları kullanın. cProfile modülü, her bir komut dosyası fonksiyonunun çalışmasının ne kadar sürdüğünü ayrıntılandıran bir rapor üretir. Bu rapor, yavaş çalışan işlevleri bulmamıza ve böylece bunları iyileştirmemize yardımcı olabilir.







Kod Parçacığı:



içe aktarmak cProfil gibi cP
kesinlikle hesaplamaToplamı ( Numara giriniz ) :
toplam_of_input_numbers = 0
sırasında Numara giriniz > 0 :
giriş_sayılarının toplamı + = Numara giriniz % 10
Numara giriniz // = 10
Yazdır ( 'Giriş Numarasındaki Tüm Rakamların Toplamı: 'giriş_sayılarının toplamı'' )
geri dönmek toplam_of_input_numbers
kesinlikle ana_işlev ( ) :
cP. koşmak ( 'Toplamı hesapla(9876543789)' )
eğer __isim__ == '__ana__' :
ana_işlev ( )

Program, çıktının ilk satırında görüldüğü gibi toplam beş fonksiyon çağrısı yapmaktadır. Her işlev çağrısının ayrıntıları, işlevin kaç kez çağrıldığı, işlevin toplam süresi, çağrı başına süre ve işlevdeki toplam süre (dahil olmak üzere) dahil olmak üzere aşağıdaki birkaç satırda gösterilmektedir. adı verilen tüm işlevler).



Ayrıca program, istem ekranına programın tüm görevlerinin yürütme süresini 0,000 saniye içinde tamamladığını gösteren bir rapor yazdırır. Bu programın ne kadar hızlı olduğunu gösteriyor.





Doğru Veri Yapısını Seçin

Performans özellikleri veri yapısına bağlıdır. Özellikle sözlükler, genel amaçlı depolamayla ilgili aramalarda listelerden daha hızlıdır. Verileriniz üzerinde yapacağımız işlemlere en uygun veri yapısını biliyorsanız seçiniz. Aşağıdaki örnek, veri yapısında bir öğenin mevcut olup olmadığını belirlemek amacıyla aynı süreç için farklı veri yapılarının etkinliğini araştırmaktadır.



Her veri yapısında (liste, küme ve sözlük) bir öğenin mevcut olup olmadığını kontrol etmek için gereken süreyi değerlendirir ve bunları karşılaştırırız.

OptimizeDataType.py:

içe aktarmak Zamani gibi tt
içe aktarmak rastgele gibi rndobj
# Tam sayıların bir listesini oluştur
rastgele_veri_listesi = [ rndobj. randevu ( 1 , 10000 ) için _ içinde menzil ( 10000 ) ]
# Aynı verilerden bir küme oluşturun
rastgele_veri_kümesi = ayarlamak ( rastgele_veri_listesi )

# Anahtarlarla aynı verilere sahip bir sözlük oluşturun
obj_DataDictionary = { birde: Hiçbiri için birde içinde rastgele_veri_listesi }

# Aranacak öğe (verilerde mevcut)
random_number_to_find = rndobj. seçenek ( rastgele_veri_listesi )

# Bir listedeki üyeliği kontrol etme süresini ölçün
liste_zamanı = tt. Zamani ( lambda : bulunacak_rastgele_sayı içinde rastgele_veri_listesi , sayı = 1000 )

# Bir kümedeki üyeliği kontrol etme süresini ölçün
ayarlanan zaman = tt. Zamani ( lambda : bulunacak_rastgele_sayı içinde rastgele_veri_kümesi , sayı = 1000 )

# Bir sözlükteki üyeliği kontrol etme süresini ölçün
dict_time = tt. Zamani ( lambda : bulunacak_rastgele_sayı içinde obj_DataDictionary , sayı = 1000 )

Yazdır ( F 'Liste üyeliği kontrol süresi: {list_time:.6f} saniye' )
Yazdır ( F 'Üyelik kontrol süresini ayarla: {set_time:.6f} saniye' )
Yazdır ( F 'Sözlük üyeliği kontrol süresi: {dict_time:.6f} saniye' )

Bu kod, üyelik kontrolleri yapılırken listelerin, kümelerin ve sözlüklerin performansını karşılaştırır. Genel olarak kümeler ve sözlükler, karma tabanlı aramaları kullandıkları için üyelik testleri için listelerden önemli ölçüde daha hızlıdırlar, dolayısıyla O(1) ortalama zaman karmaşıklığına sahiptirler. Öte yandan listeler, O(n) zaman karmaşıklığına sahip üyelik testleriyle sonuçlanan doğrusal aramalar yapmalıdır.

  Bir bilgisayarın ekran görüntüsü Açıklama otomatik olarak oluşturuldu

Döngüler Yerine Yerleşik İşlevleri Kullanın

Python'daki çok sayıda yerleşik işlev veya yöntem, filtreleme, sıralama ve haritalama gibi tipik görevleri gerçekleştirmek için kullanılabilir. Kendi döngülerinizi oluşturmak yerine bu rutinleri kullanmak, genellikle performans açısından optimize edildikleri için kodun hızlandırılmasına yardımcı olur.

Tipik işler için (map(), filter() ve sorted() gibi) yerleşik işlevleri kullanarak özel döngüler oluşturma performansını karşılaştırmak için bazı örnek kodlar oluşturalım. Çeşitli haritalama, filtreleme ve sıralama yöntemlerinin ne kadar iyi performans gösterdiğini değerlendireceğiz.

DahiliFunctions.py:

içe aktarmak Zamani gibi tt
# Numara_listesinin örnek listesi
sayılar_listesi = liste ( menzil ( 1 , 10000 ) )

# Bir döngü kullanarak sayıların karesini alma işlevi
kesinlikle square_using_loop ( sayılar_listesi ) :
square_result = [ ]
için birde içinde sayılar_listesi:
square_result. eklemek ( birde ** 2 )
geri dönmek square_result
# Bir döngü kullanarak çift sayılar_listesini filtreleme işlevi
kesinlikle filter_even_using_loop ( sayılar_listesi ) :
filtre_sonucu = [ ]
için birde içinde sayılar_listesi:
eğer birde % 2 == 0 :
filter_result. eklemek ( birde )
geri dönmek filtre_sonucu
# Bir döngü kullanarak sayılar_listesini sıralama işlevi
kesinlikle sort_using_loop ( sayılar_listesi ) :
geri dönmek sıralanmış ( sayılar_listesi )
# Map()'ı kullanarak sayıların karesine kadar geçen süreyi ölçün
harita_zamanı = tt. Zamani ( lambda : liste ( harita ( lambda x: x ** 2 , sayılar_listesi ) ) , sayı = 1000 )
# filter() işlevini kullanarak çift sayılar_listesini filtrelemek için gereken süreyi ölçün
filtre_zamanı = tt. Zamani ( lambda : liste ( filtre ( lambda x: x % 2 == 0 , sayılar_listesi ) ) , sayı = 1000 )
# sorted() işlevini kullanarak sayı_listesini sıralamak için gereken süreyi ölçün
sıralanmış_zaman = tt. Zamani ( lambda : sıralanmış ( sayılar_listesi ) , sayı = 1000 )
# Bir döngü kullanarak sayı_listesinin karesine kadar geçen süreyi ölçün
loop_map_time = tt. Zamani ( lambda : square_using_loop ( sayılar_listesi ) , sayı = 1000 )
# Bir döngü kullanarak çift sayılar_listesini filtrelemek için gereken süreyi ölçün
loop_filter_time = tt. Zamani ( lambda : filter_even_using_loop ( sayılar_listesi ) , sayı = 1000 )
# Bir döngü kullanarak sayı_listesini sıralamak için gereken süreyi ölçün
loop_sorted_time = tt. Zamani ( lambda : sort_using_loop ( sayılar_listesi ) , sayı = 1000 )
Yazdır ( 'Numara Listesi 10000 öğe içeriyor' )
Yazdır ( F 'Harita() Süresi: {map_time:.6f} saniye' )
Yazdır ( F 'Filter() Süresi: {filter_time:.6f} saniye' )
Yazdır ( F 'Sorted() Süresi: {sorted_time:.6f} saniye' )
Yazdır ( F 'Döngü (Harita) Süresi: {loop_map_time:.6f} saniye' )
Yazdır ( F 'Döngü (Filtre) Süresi: {loop_filter_time:.6f} saniye' )
Yazdır ( F 'Döngü (Sıralı) Süresi: {loop_sorted_time:.6f} saniye' )

Muhtemelen yerleşik işlevlerin (map(), filter() ve sorted()), bu ortak görevler için özel döngülerden daha hızlı olduğunu gözlemleyeceğiz. Python'daki yerleşik işlevler, bu görevleri gerçekleştirmek için daha kısa ve anlaşılır bir yaklaşım sunar ve performans açısından yüksek düzeyde optimize edilmiştir.

Döngüleri Optimize Edin

Döngüleri yazmak gerekiyorsa onları hızlandırmak için yapabileceğimiz birkaç teknik vardır. Genellikle range() döngüsü geriye doğru yinelemeden daha hızlıdır. Bunun nedeni range() işlevinin, listeyi ters çevirmeden bir yineleyici oluşturmasıdır; bu, uzun listeler için maliyetli bir işlem olabilir. Ayrıca range() hafızada yeni bir liste oluşturmadığı için daha az hafıza kullanır.

OptimizeLoop.py:

içe aktarmak Zamani gibi tt
# Sayı_listesinin örnek listesi
sayılar_listesi = liste ( menzil ( 1 , 100000 ) )
# Listeyi ters sırada yineleme işlevi
kesinlikle loop_reverse_iteration ( ) :
sonuç_reverse = [ ]
için J içinde menzil ( sadece ( sayılar_listesi ) - 1 , - 1 , - 1 ) :
result_reverse. eklemek ( sayılar_listesi [ J ] )
geri dönmek sonuç_reverse
# range() işlevini kullanarak liste üzerinde yineleme yapma işlevi
kesinlikle loop_range_iteration ( ) :
sonuç_aralığı = [ ]
için k içinde menzil ( sadece ( sayılar_listesi ) ) :
sonuç_aralığı. eklemek ( sayılar_listesi [ k ] )
geri dönmek sonuç_aralığı
# Ters yinelemeyi gerçekleştirmek için gereken süreyi ölçün
ters_zaman = tt. Zamani ( loop_reverse_iteration , sayı = 1000 )
# Aralık yinelemesini gerçekleştirmek için gereken süreyi ölçün
aralık_zamanı = tt. Zamani ( loop_range_iteration , sayı = 1000 )
Yazdır ( 'Numara listesi 100000 kayıt içeriyor' )
Yazdır ( F 'Tersine Yineleme Süresi: {reverse_time:.6f} saniye' )
Yazdır ( F 'Aralık Yineleme Süresi: {range_time:.6f} saniye' )

Gereksiz İşlev Çağrılarından Kaçının

Bir işlev her çağrıldığında bir miktar ek yük vardır. Gereksiz işlev çağrılarından kaçınılırsa kod daha hızlı çalışır. Örneğin, bir değeri hesaplayan bir işlevi tekrar tekrar çalıştırmak yerine, hesaplamanın sonucunu bir değişkende saklayıp onu kullanmayı deneyin.

Profil Oluşturma Araçları

Kodunuzun performansı hakkında daha fazla bilgi edinmek için yerleşik profil oluşturmaya ek olarak cProfile, Pyflame veya SnakeViz gibi harici profil oluşturma paketlerinden yararlanabiliriz.

Önbellek Sonuçları

Kodumuzun pahalı hesaplamalar yapması gerekiyorsa, zamandan tasarruf etmek için sonuçları önbelleğe almayı düşünebiliriz.

Yeniden yapılandırılan kod

Kodun okunmasını ve bakımını kolaylaştırmak için yeniden düzenleme yapmak bazen kodu optimize etmenin gerekli bir parçasıdır. Daha hızlı bir program aynı zamanda daha temiz de olabilir.

Tam Zamanında Derlemeyi (JIT) kullanın

PyPy veya Numba gibi kütüphaneler, belirli Python kodu türlerini önemli ölçüde hızlandırabilen bir JIT derlemesi sağlayabilir.

Python'u Yükselt

Yeni sürümler genellikle performans iyileştirmeleri içerdiğinden Python'un en son sürümünü kullandığınızdan emin olun.

Paralellik ve Eşzamanlılık

Paralelleştirilebilecek işlemler için çoklu işlem, iş parçacığı veya eşzamansız gibi paralel ve senkronizasyon tekniklerini araştırın.

Karşılaştırma ve profil oluşturmanın optimizasyonun ana itici güçleri olması gerektiğini unutmayın. Kodumuzun performans üzerinde en önemli etkiye sahip alanlarını iyileştirmeye odaklanın ve daha fazla kusur yaratmadan istenen etkilere sahip olduklarından emin olmak için iyileştirmelerinizi sürekli olarak test edin.

Çözüm

Sonuç olarak, Python kod optimizasyonu, gelişmiş performans ve kaynak verimliliği açısından çok önemlidir. Geliştiriciler, uygun veri yapılarını seçmek, yerleşik işlevlerden yararlanmak, ekstra döngüleri azaltmak ve belleği etkili bir şekilde yönetmek gibi çeşitli teknikleri kullanarak Python uygulamalarının yürütme hızını ve yanıt verebilirliğini büyük ölçüde artırabilirler. Sürekli kıyaslama ve profil oluşturma, kod ilerlemelerinin gerçek dünya performans gereksinimlerine uygun olmasını sağlayarak optimizasyon çabalarını yönlendirmelidir. Uzun vadeli bir proje başarısını garanti etmek ve yeni sorunların ortaya çıkma olasılığını azaltmak için kodun optimize edilmesi, kodun okunabilirliği ve sürdürülebilirliği hedefleriyle sürekli olarak dengelenmelidir.