Kıyaslama ve Profil Oluşturma
Bu bölümde, kıyaslama ve profil oluşturmanın performans sorunlarının ele alınmasına nasıl yardımcı olduğunu öğreneceğiz.
Diyelim ki bir kod yazdık ve bu da istenen sonucu veriyor ama ya bu kodu biraz daha hızlı çalıştırmak istiyorsak, çünkü ihtiyaçlar değişti. Bu durumda, kodumuzun hangi kısımlarının tüm programı yavaşlattığını bulmamız gerekir. Bu durumda, kıyaslama ve profil oluşturma faydalı olabilir.
Kıyaslama nedir?
Kıyaslama, bir şeyi bir standartla karşılaştırarak değerlendirmeyi amaçlar. Ancak burada ortaya çıkan soru, kıyaslamanın ne olacağı ve yazılım programlama durumunda buna neden ihtiyacımız olduğudur. Kodun karşılaştırılması, kodun ne kadar hızlı yürütüldüğü ve darboğazın nerede olduğu anlamına gelir. Kıyaslamanın en önemli nedenlerinden biri kodu optimize etmesidir.
Kıyaslama nasıl çalışır?
Kıyaslamanın çalışması hakkında konuşursak, tüm programı tek bir mevcut durum olarak kıyaslayarak başlamalıyız, sonra mikro kıyaslamaları birleştirebilir ve ardından bir programı daha küçük programlara ayırabiliriz. Programımızdaki darboğazları bulmak ve optimize etmek için. Başka bir deyişle, büyük ve zor problemi, onları optimize etmek için daha küçük ve biraz daha kolay problemler dizisine ayırmak olarak anlayabiliriz.
Kıyaslama için Python modülü
Python'da, karşılaştırma için varsayılan olarak adlandırılan bir modülümüz var. timeit. Yardımıylatimeit modülünde, ana programımızdaki küçük Python kodunun performansını ölçebiliriz.
Misal
Aşağıdaki Python betiğinde, timeit modül, iki işlevi yerine getirmek için harcanan zamanı daha da ölçer - functionA ve functionB -
import timeit
import time
def functionA():
print("Function A starts the execution:")
print("Function A completes the execution:")
def functionB():
print("Function B starts the execution")
print("Function B completes the execution")
start_time = timeit.default_timer()
functionA()
print(timeit.default_timer() - start_time)
start_time = timeit.default_timer()
functionB()
print(timeit.default_timer() - start_time)
Yukarıdaki betiği çalıştırdıktan sonra, aşağıda gösterildiği gibi her iki işlevin de yürütme zamanını alacağız.
Çıktı
Function A starts the execution:
Function A completes the execution:
0.0014599495514175942
Function B starts the execution
Function B completes the execution
0.0017024724827479076
Dekoratör işlevini kullanarak kendi zamanlayıcımızı yazmak
Python'da, kendi zamanlayıcımızı oluşturabiliriz, bu da tıpkı timeitmodül. Yardımı ile yapılabilirdecoratorişlevi. Aşağıda, özel zamanlayıcıya bir örnek verilmiştir -
import random
import time
def timer_func(func):
def function_timer(*args, **kwargs):
start = time.time()
value = func(*args, **kwargs)
end = time.time()
runtime = end - start
msg = "{func} took {time} seconds to complete its execution."
print(msg.format(func = func.__name__,time = runtime))
return value
return function_timer
@timer_func
def Myfunction():
for x in range(5):
sleep_time = random.choice(range(1,3))
time.sleep(sleep_time)
if __name__ == '__main__':
Myfunction()
Yukarıdaki python betiği, rastgele zaman modüllerinin içe aktarılmasına yardımcı olur. Timer_func () dekoratör işlevini yarattık. Bunun içinde function_timer () işlevi vardır. Şimdi, yuvalanmış işlev, geçirilen işlevi çağırmadan önce zamanı alacaktır. Daha sonra fonksiyonun dönmesini bekler ve bitiş zamanını alır. Bu şekilde, nihayet python betiğinin yürütme zamanını yazdırmasını sağlayabiliriz. Komut dosyası, çıktıyı aşağıda gösterildiği gibi oluşturacaktır.
Çıktı
Myfunction took 8.000457763671875 seconds to complete its execution.
Profil oluşturma nedir?
Bazen programcı, o programın gerçek kapasitesini ölçmek için bellek kullanımı, zaman karmaşıklığı veya programlarla ilgili belirli talimatların kullanımı gibi bazı özellikleri ölçmek ister. Programla ilgili bu tür ölçümlere profilleme denir. Profil oluşturma, bu tür ölçümleri yapmak için dinamik program analizi kullanır.
Sonraki bölümlerde, Profil Oluşturma için farklı Python Modülleri hakkında bilgi edineceğiz.
cProfile - dahili modül
cProfileprofil oluşturma için yerleşik bir Python modülüdür. Modül, uzun süre çalışan programların profilini çıkarmak için uygun hale getiren makul ek yüke sahip bir C uzantısıdır. Çalıştırdıktan sonra, tüm işlevleri ve yürütme zamanlarını günlüğe kaydeder. Çok güçlüdür ancak bazen yorumlanması ve harekete geçmesi biraz zordur. Aşağıdaki örnekte, aşağıdaki kodda cProfile kullanıyoruz -
Misal
def increment_global():
global x
x += 1
def taskofThread(lock):
for _ in range(50000):
lock.acquire()
increment_global()
lock.release()
def main():
global x
x = 0
lock = threading.Lock()
t1 = threading.Thread(target=taskofThread, args=(lock,))
t2 = threading.Thread(target= taskofThread, args=(lock,))
t1.start()
t2.start()
t1.join()
t2.join()
if __name__ == "__main__":
for i in range(5):
main()
print("x = {1} after Iteration {0}".format(i,x))
Yukarıdaki kod, thread_increment.pydosya. Şimdi, kodu komut satırında cProfile ile aşağıdaki gibi yürütün -
(base) D:\ProgramData>python -m cProfile thread_increment.py
x = 100000 after Iteration 0
x = 100000 after Iteration 1
x = 100000 after Iteration 2
x = 100000 after Iteration 3
x = 100000 after Iteration 4
3577 function calls (3522 primitive calls) in 1.688 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
5 0.000 0.000 0.000 0.000 <frozen importlib._bootstrap>:103(release)
5 0.000 0.000 0.000 0.000 <frozen importlib._bootstrap>:143(__init__)
5 0.000 0.000 0.000 0.000 <frozen importlib._bootstrap>:147(__enter__)
… … … …
Yukarıdaki çıktıdan, cProfile'ın çağrılan tüm 3577 işlevi, her birinde harcanan süre ve kaç kez çağrıldıklarıyla birlikte yazdırdığı açıktır. Çıktıda aldığımız sütunlar aşağıdadır -
ncalls - Yapılan aramaların sayısıdır.
tottime - Verilen işlevde harcanan toplam süredir.
percall - Toplam zamanın ncalls ile bölünmesiyle elde edilen bölümü ifade eder.
cumtime- Bu ve tüm alt işlevlerde harcanan toplam süredir. Yinelemeli işlevler için bile doğrudur.
percall - Cumtime oranının ilkel çağrılara bölünmesiyle elde edilen orandır.
filename:lineno(function) - Temel olarak her işlevin ilgili verilerini sağlar.