İşlemin tahmini gerçekleşme süresini hesaplama

def asalbul(sayi):
    asallar=[2]
    for i in range(3,sayi+1):
        for j in asallar:
            if i%j==0:
             break
            elif j==asallar[-1]:
                asallar.append(i)
    return asallar
print(asalbul(10000000))

Mesela böyle bir kodum var.
Programı çalıştırdığımda işlemin tahmini süresi 100 saniye işlem başlıyor gibi birşeyin yazması mümkün müdür

Tabi, kalan süre denklemini oluşturabilirseniz neden olmasın. İpucu olması açısından şöyle göstereyim:

import time

# İşlemi ölçmeye t zamanında başlayacak olalım.
t = time.perf_counter()

# İşlem boyutunu s ile ifade edelim.
s = 100000

# İşlem adımları için c isimli bir değişken oluşturalım.
c = 0

Bu üç parametreye göre bir denklem yazmalısınız.
Adım adım gidelim.

Tahmini gerçekleşme süresini hesaplamak için bizim önce işlemin gerçekleşme hızını hesaplamamız lazım. Lise fizik derslerinden hatırladığımız kadarıyla, hız formülü şöyleydi:

hız = mesafe / zaman

Bizim bu örnekteki mesafe kavramı yerine koyabileceğimiz kavram c değişkeni, çünkü bu değer bizim hangi adımda olduğumuzu belirliyor; veya işlem boyutunu ifade eden s. Zamanı nasıl hesaplarız? Şimdiki zamandan t'yi çıkartarak. O halde işlem hızını şöyle hesaplayabiliriz:

islem_hizi = c / (time.perf_counter() - t)

Peki islem_hizi'ni bulduk. Şimdi elimizde s var islem_hizi var, s'in toplamda ne kadar süreye ihtiyacı olduğunu şöyle hesaplayabiliriz değil mi? (x = v.t formülünü hatırlayın)

toplam_zaman = s / islem_hizi

Toplamda bu işlemin süresi toplam_zaman'ın değeri kadarmış. Peki biz kalan süreyi nasıl hesaplarız?
Toplam zamandan, geçen zamanı çıkartarak, yani:

kalan_zaman = toplam_zaman - (time.perf_counter() - t)

Şimdi bu açıklamaları koda dönüştürelim:

from time import perf_counter


def eta(s):
    t = perf_counter()
    for i in range(1, s + 1):
        print(f"\rETA: {((s / (i / (e := perf_counter() - t))) - e)}", end="")


eta(10000000)

Buradaki kodlar, her saniyede kalan işlemin tahmini gerçekleşme süresini hesaplar ve ekrana yazdırır. Buradaki denklemi kendi kodlarınıza göre uyarlayabilirsiniz.

3 Beğeni

Sizin kodda çalışıyor fakat benim kodda çalışmıyor sebebi ise sanırım şu sizin kodda sürekli aynı mesajı yazdırıyor sadece fakat benim kodda sürekli yapacağı iş artıyor. Örneğin ilk başladığında gelen sayı 3 3 2 ye bölünüyor mu hayır asallara ekle döngü bitti ama döngünün 98. turundayız atıyorum gelen sayı 100 bundan önceki asallar kümeye eklendiği için ilk adımdaki gibi 1 sayıya değil 25 sayıya bölünüyor mu diye kontrol edecek nasıl düzeltirim.

from time import perf_counter


def asalbul(sayi):
    asallar = [2]
    t = perf_counter()
    array = range(3, sayi + 1)
    s = len(array)
    for i, j in enumerate(array, 1):
        for j in asallar:
            if i % j == 0:
                break
            elif j == asallar[-1]:
                asallar.append(i)
        print(f"\rETA: {((s / (i / (e := perf_counter() - t))) - e)}", end="")
    print()
    return asallar

Ama size bir şey söylememe izin verin. Yukardaki kodlarda for döngüsünün her adımında kalan süre tekrar tekrar hesaplanıyor. Bu ne demek? Bu, print ifadesinin olduğu satırın da ekstra bir işlem yükü oluşturması demek. Diyelim ETA size belirli parametreler altında gerçekleşen bir işlemin 25 saniyede tamamlanacağını söylüyor. Ama bu süreye print ifadesinde gerçekleşen işlem de dahil ediliyor. Normalde, o işlemin gerçekleşme süresi 25 saniyeden daha az olmalı.
Aşağıdaki kodları çalıştırdığınız zaman elde edeceğiniz t2 - t1 farkını bir yere not edin:

from time import perf_counter


def eta(n: int):
    # t = perf_counter()
    array = []
    for i in range(1, n + 1):
        if i % 2 == 0:
            array += [i]
        # print(f"\rETA: {((n / (i / (e := perf_counter() - t))) - e)}", end="", flush=True)
    print()


t1 = perf_counter()
eta(n=1000000)
t2 = perf_counter()
print(t2 - t1)

Şimdi de aşağıdaki kodları çalıştırdığınız zaman elde edeceğiniz t2 - t1 farkını bir yere not edin:

from time import perf_counter


def eta(n: int):
    t = perf_counter()
    array = []
    for i in range(1, n + 1):
        if i % 2 == 0:
            array += [i]
        print(f"\rETA: {((n / (i / (e := perf_counter() - t))) - e)}", end="", flush=True)
    print()


t1 = perf_counter()
eta(n=1000000)
t2 = perf_counter()
print(t2 - t1)

Şimdi de aradaki farkı karşılaştırın isterseniz.

Teşekkür ederim

from time import perf_counter


def asalbul(sayi):
    asallar = [2]
    t = perf_counter()
    array = range(3, sayi + 1)
    s = len(array)
    for i, j in enumerate(array, 1):
        for j in asallar:
            if i % j == 0:
                break
            elif j == asallar[-1]:
                asallar.append(i)
        if i ==1:
            print(f"\rETA: {((s / (i / (e := perf_counter() - t))) - e)}", end="")
    print()
    return asallar
asalbul(1000000)

kod normalde çalışıyor fakat ben sadece başta vermesini istediğim için böyle bir şey yaptım fakat terminale 5 yazıyor 1 saniye geçmeden bitiyor hatam nedir

if i == 1 bu ifade.

Onu neyle değiştirmeliyim sadece ilkinde yazmasını istiyorsam. Yani sonuçta i 1den 1000000 a kadar değer alıyor ilk turda i 1

Siz, o kod satırı sadece i == 1 durumunda çalışsın istiyorsunuz ama (s / (i / (e := perf_counter() - t))) - e) ifadesini hesaba katmıyorsunuz. Çünkü bu satırı çalıştırmadığınızda, işlem hızı artacaktır. Dolayısıyla i == 1 durumunda size ne yazarsa yazsın, işlem daha kısa sürede sonlanır.

Peki ne yapmalıyım (Yeni başladım sayılır pek bilmiyorum kusura bakmayın)

tqdm gibi bir kutuphane de kullanilabilir.

Tabi bu iki cozum de islemin dogrusal oldugunu (zaman gectikce yavaslamayacagini veya hizlanmayacagini) varsayiyor. Oysa algoritma daha “yavas”. (O(n²/log(n)) galiba)

1 Beğeni