Bir betiğin ortalama yürütme süresi nasıl ölçülür?


23

Her biri bir sayının faktöriyel hesaplamak iki komut dosyaları var. Hangisinin daha hızlı olduğunu bilmek istiyorum. timeKomut bana milisaniye verir ve sonuç zaman zaman farklıdır:

piousbox@piousbox-laptop:~/projects/trash$ time ruby fac2.rb
30414093201713378043612608166064768844377641568960512000000000000

real    0m0.089s
user    0m0.052s
sys 0m0.028s
piousbox@piousbox-laptop:~/projects/trash$ time ruby fac1.rb
30414093201713378043612608166064768844377641568960512000000000000

real    0m0.091s
user    0m0.048s
sys 0m0.036s
piousbox@piousbox-laptop:~/projects/trash$ time ruby fac1.rb
30414093201713378043612608166064768844377641568960512000000000000

real    0m0.088s
user    0m0.048s
sys 0m0.040s
piousbox@piousbox-laptop:~/projects/trash$ time ruby fac2.rb
30414093201713378043612608166064768844377641568960512000000000000

real    0m0.088s
user    0m0.048s
sys 0m0.028s
piousbox@piousbox-laptop:~/projects/trash$ time ruby fac1.rb
30414093201713378043612608166064768844377641568960512000000000000

real    0m0.087s
user    0m0.064s
sys 0m0.028s
piousbox@piousbox-laptop:~/projects/trash$ time ruby fac2.rb
30414093201713378043612608166064768844377641568960512000000000000

real    0m0.089s
user    0m0.068s
sys 0m0.016s
piousbox@piousbox-laptop:~/projects/trash$ 

Komut dosyasını çalıştırmak için geçen ortalama süreyi nasıl alabilirim? Bir 100 time's çıktısını ayrıştırmak ve ortalama olabilir ama daha iyi bir çözüm olduğunu hayal?


Yanıtlar:


4

Hayır, ortalama alma fikriniz doğrudur.

Komut dosyası yürütme birçok faktöre bağlıdır ve bununla birlikte kurulum süresi (belleğe yorumlayıcı yükleme, kodun bayt koduna veya makine koduna derlenmesi ve muhtemelen derleme) ve gerçek yürütme süresi arasında bölünmesi gerekir.

İç yürütme süresine daha iyi odaklanmak için, komut dosyasının kendisinde döngü yaparsınız (yani, bir faktöriyeli hesaplamak yerine, komut dosyasını bir yürütme içinde 100 kez hesaplarsınız. Komut dosyası bir kez kurulur ve iç rutin 100 yürütür zamanlar).

Toplam süreye odaklanmak için, komut dosyasını yüz kez yürütür ve sonuçları ortalaması alırsınız. İdeal olarak, bu yürütmeleri, sistemin her seferinde bir "referans durumunda" (veya komut dosyası ile ilgisiz bir durumda) döndürecek kadar ayırmanız gerekir. Örneğin, yorumlayıcının kendisi bellekte önbelleğe alınacaktır, böylece betiğin ilk yürütülmesi sonraki kodlardan çok daha yavaş olacaktır.

Algoritma hakkında daha iyi bir fikir edinmek için, en iyi yolun (aksi takdirde boşta bir makinede) böyle bir şey olduğunu düşünüyorum:

  • algoritmayı tek bir işleve sarın.
  • kontrol eden uygulamada:
    • işlevi bir kez çağır
    • sistem ("duvar saati") süresini alın ve 10 (veya makul bir N) saniye ekleyin
    • döngüye girin ve yinelemeleri saymaya başlayın
    • işleve yapılan her çağrıdan sonra sayacı artırın
    • sistem saati kaydedilen sürenin altındaysa, başka bir döngü yapın
    • geçerli duvar saati zamanından kesin N, muhtemelen kayan nokta elde edin
    • sayacı N'ye bölme: bu yineleme sayısı / saniye.

Uygulama yalnızca bir kez çalışır, tüm kurulum ve hazırlama ilk zamanlanmamış yineleme ile yapılır, bu nedenle ek yükleri en aza indirmelidir (belki de zaman araması hariç).

İşlev bir girdi alırsa, sınanan işlevin her iki sürümünün de aynı değerleri almasını sağlamak için sabit bir değerle eklenmiş bir PRNG kullanarak rastgele bir girdi dizisi sağlamak iyi olur. Bu, bir fonksiyon yerine getirilmesinin önüne görünüşte nedeniyle "şanslı numaralar" (örneğin ben öğelerin sayısı formu 2 oldu sıralanmasını eğer ölçülebilir daha iyi bir performans Hillsort algoritmasının çeşitlerini hatırlamak daha iyi k -1 küçük olan k ler).


Doğru, teşekkürler. Daha sonraki aramaların nerede kısaldığını fark ettim. Şimdi betiklerin içindeki döngüyü çalıştırıyorum ve bir algoritmanın kesinlikle diğerinden daha hızlı olduğunu gördüm.
Victor Piousbox

39

Programın yinelemelerini bir döngüde çalıştırabilirsiniz; ve toplam süreyi yineleme sayısına bölün:

time for i in {1..10}; do sleep 1; done
real    0m10.052s
user    0m0.005s
sys 0m0.018s

2
Süper basit, seviyorum. Ayrıca daha {1..10}önce hiç görmedim ve işe yaradığını şaşırttı, bash kılavuzunda bulamıyorum. Sadece üzücü olan şey sonuçlarınızın yayılmasını bilmemenizdir (minimum ve maksimum süre).
w00t

@ man -P 'less +/Brace\ Expansion' bash
w00t

Teşekkürler @ user2683246! Daha sonra gnu.org/software/bash/manual/bash.html#Brace-Expansion adresinde de buldum - daha az btw'nin güzel kullanımı. Şimdi bunun
bash'da

1
Aha, bash kullanmaya başladıktan 3, 10 yıl sonra sürüm tldp.org/LDP/abs/html/bashver3.html
w00t

2
Bu, Google çalışanları için işe yaramıyorsa, bunun nedeni çalışmamanız olabilir bash. Bundan /bin/bashönce koşmayı deneyin .
Cory Klein

14

tam olarak bunu yapan multitime adlı bir araç var : bir komutu birkaç kez çalıştırmak, ne kadar sürdüğünü ölçmek (ortalama / min / maks ve medyan zaman otomatik olarak hesaplanır)

Örneğin, benzer bir komut dosyasını 100 kez ölçmek için:

multitime -q -n 100 "fact1.sh"
===> multitime results
1: -q fact1.sh
            Mean        Std.Dev.    Min         Median      Max
real        0.122       0.032       0.086       0.116       0.171       
user        0.148       0.044       0.096       0.137       0.223       
sys         0.023       0.019       0.000       0.014       0.061 

12

Bu eski ama daha önce kullandığım ama bulamadım bir komut ararken google'da çok yüksek geldi. Her neyse, bunu yapmayı tercih ettiğim yol:

perf stat -r 10 -B sleep 1

Bu, sondaki ortalama yürütme süresi de dahil olmak üzere biraz ayrıntı verir:

1.002248382 seconds time elapsed                   ( +-  0.01% )


1

Hiperfin başka bir seçenektir.

Örnek kullanım:

hyperfine --warmup 3 'ruby fac1.rb'

1
aşırı ince, diğer alternatiflerden çok daha iyi, saçma. Gerekli koşuların tespiti, ısınma, güzel çıktı, etiketleme raporları, pasla yazılmış vb.
Klas Mellbourn
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.