Büyük büyük verilerde uzun uzun işlemler yapıyoruz. Kodu yazdık, bastık 'run'a. Bekle Allah bekle...

Bir sayaç olaydı da bize geçen süreyi göstereydi, hatta kalan süreyi tahmin edeydi ne de güzel olurdu diye iç geçiriyoruz. Biliyoruz tic/toc var ama daha modüler bir şeyler olsun istiyoruz. Gelin, bugün böyle bir şey yazalım.

Bunun için persistent anahtar sözcüğünü kullanacağız. Hatırlarsanız kalıcı değişkenler yaratmamıza yarıyordu kendisi. Kalıcı olmasını istediğimiz şey ölçümün ilk yapıldığı an.

Yazacağımız zaman ölçme fonksiyonu bir döngünün içinden çağıracağımızı düşünelim. Toplamda n tane iterasyon olsun ve fonksiyonu i. iterasyonda çağıracağımızı varsayalım ve başlayalım:

function [gecenSure, kalanTahminiSure, mesaj] = zaman_olcer(i, n)
    persistent zaman

Fonksiyon ilk kez çağrıldığında zaman değişkeni boş olacak, bunu hesaba katarak ilklendirmeyi yapalım:

    if(isempty(zaman)) % İlk çağrıldığında t'yi şu anki zamana eşitle
        zaman = clock;
    end

Geçen süreyi etime fonksiyonu ile ölçmek çok kolay:

gecenSure = etime(clock, zaman); % Geçen süre = şu anki zaman - bir önceki ölçüm

Buraya kadar hava hoştu. Eğer kalan süreyi tahmin etmemiz bekleniyorsa, döngünün neresinde olunduğu bilgisi (i ve n parametreleri) verilmeli:

    if nargout > 1 % Birden fazla sonuç isteniyorsa
        assert(nargin == 2) % Şu anki döngü numarası ve toplam döngü sayısı verilmeli
        kalanTahminiSure = gecenSure / i * (n-i);
        if nargout > 2 % mesaj olarak basılacaksa
            mesaj = sprintf('Geçen süre: %.1f sn. Tahmini kalan süre: %.1f sec\n', ...
                       gecenSure, kalanTahminiSure);
        end
    end
end

Şimdi de test için, her döngüde (aynı dağılımdan gelen rastgele) bir süre harcayan şöyle basit bir betik yazalım:

zaman_olcer(); % ilklendirme
K = 200;
for k = 1:K
    pause(rand/10) % Döngüde bir takım işlemler yapılsın ve biraz zaman alsın
    [gecenSure, kalanTahminiSure, mesaj] = zaman_olcer(k, K);
    fprintf(mesaj)
end

İşimiz bittiğinde fonksiyonu silmeyi aman unutmayalım:

clear zaman_olcer;

Sonuçların her döngüde yeni bir satıra yazılması sizi rahatsız ediyor mu? Beni çok rahatsız ediyor. Gelin tek satırda bu işi çözelim! Sonucu eskisini güncelleyerek göstermeye yarayacak bir 'akıllı çıktı' fonksiyonu yazalım:

function cikti = akilli_cikti(girdi) persistent silgi if(isempty(silgi)) silgi = ''; end cikti = sprintf([silgi, girdi]); silgi = repmat(sprintf('\b'), 1, length(girdi)); end

Burada silgi dediğimiz değişken girdi'deki karakter sayısı kadar '\b' karakterinin yan yana dizilmesinden oluşuyor. '\b', backslash yerine geçiyor; yani önceki yazılan karakterleri siliyor. repmat ise belli bir girdiyi yatay veya dikey döşeyerek daha büyük değişkenler elde etmeye yarıyor. Bu durumda '\b'leri yan yana döşüyor.

Artık test betiğimizdeki ekrana basma satırını güncelleyebiliriz:

    fprintf(akilli_cikti(mesaj))

Harika! Artık yüzlerce satır görmek yerine her döngüde güncellenen tek bir satırda ne olup bittiğinden haberdar olabiliyoruz.

Bu arada unutmayalım: Akıllı çıktıyı sadece zaman ölçmede değil, kaçıncı turu attığımızı görmek gibi binbir türlü küçük ekran raporlamalarında kullanabiliriz.