Zaman ölçer
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.