Jak uzyskać czas wykonywania Bash w milisekundach w systemie Mac OS X?

12

Sprawdziłem to , ale dostarczone rozwiązanie nie działało dla mnie.

Za pomocą daty mogę uzyskać czas wykonania w sekundach:

T="$(date +%s)"
#some work here
T="$(($(date +%s)-T))"
echo "execution time (secs) ${T}"

Jednak gdy spróbuję:

T="$(date +%s%N)"
#some work here
T="$(($(date +%s%N)-T))"

Dodając% N (jak wyżej) do daty, aby uzyskać precyzję w sekundach, otrzymuję następujący błąd: -bash: 1369320760N: wartość zbyt duża dla podstawy (token błędu to „1369320760N”)

Czy ktoś wie, jak mierzyć czas wykonywania w milisekundach przy użyciu bash w systemie Mac OS X?

pacodelumberg
źródło
Czy naprawdę potrzebujesz nanosekundowej rozdzielczości? Które to podejście masz dużo narzutów. W przypadku # some work heretrybu wspólnego otrzymuję czasy od 0,2 do 0,3 sekundy - co powinno wynosić zero (lub przynajmniej stałą), aby osiągnąć cel. Natomiast /usr/bin/time usleep 50000daje uzasadniony czas stabilny 0,05 +/- 0,01 sek. (Testowane tylko w systemie Linux, nie wiem, czy / OSR / bin / time i / lub usleep jest dostępny w OSX.)
mpy
Czy jesteś pewien, że rozdzielczość zegara wewnętrznego zapewnia DOKŁADNĄ rozdzielczość aż do poziomu nano-sekundowego?
mdpc

Odpowiedzi:

14

Ponieważ OSX jest systemem BSD, jego biblioteka strftime nie ma %N( http://www.freebsd.org/cgi/man.cgi?query=date )

Czy wbudowane timepolecenie bash dostarcza potrzebnych informacji?

time some work here
Glenn Jackman
źródło
2
dzięki za wyjaśnienie, czas działa idealnie i daje trzy wyniki, ale muszę konkretnie pracować z czasem początkowym i końcowym.
pacodelumberg
11

Wybrałbym tę trasę, gdybym potrzebował milisekund, a BSD nie obsługiwał daty +%s%N

perl -MTime::HiRes -e 'printf("%.0f\n",Time::HiRes::time()*1000)'
hpavc
źródło
dzięki!!! To jest rozwiązanie, którego nikt nie zgłaszał ...
Daniele B,
3

echo $(($(date +%s%N)/1000000))

To przekształciłoby się z nano sekund do milisekund.

Z @mpy date +%s.%Ndziała.

Wyjście różni się jednak między linuksem a OS X:
linux: 1369322592.573787111
OS X:1369322610.N

poważny
źródło
Otrzymuję następujący błąd: -bash: 1369321446N: wartość zbyt duża dla podstawy (token błędu to „1369321446N”) to nie działa w systemie Mac OSX, otrzymuję:
pacodelumberg
Cóż, to denerwujące ... (testowane na niewłaściwym oknie), widząc ten sam błąd: /
demure
1
Nie trzeba dzielić danych wyjściowych, wystarczy użyć date +%s.%N(ale nie mogę sprawdzić OSX; działa na Linuksie). Ale problem jest wtedy, że bash„s $(( ))IMHO nie jest w stanie obsłużyć liczb zmiennoprzecinkowych.
mpy
@mpy To działa na osx. To samo dotyczy pierwszych 10 znaków, ale działa inaczej w systemie Linux i OS X.
skromny
Czy to oznacza, że ​​nie możemy uzyskać nanosekundowych informacji na podstawie daty?
pacodelumberg
3

Jeśli zainstalujesz coreutils, możesz użyć GNU Linux datepisząc gdate.

coreutils jest dostępny z Homebrew: brew install coreutils.

youyoup
źródło
1

Jak wspomniano w innej odpowiedzi, data OS X nie obsługuje% N (nanosekund).

Czy możesz po prostu zapisać polecenia jako czas? Lub użyj dla nich podpowłoki lub grupy poleceń:

time (sleep 0.1; echo a; sleep 0.1)
time { sleep 0.1; echo a; sleep 0.1; }

Lub zsumuj czasy poszczególnych poleceń:

$ time=$(TIMEFORMAT=%R; (time sleep 0.1; echo a) 2>&1 > /dev/null)
$ time+=+$(TIMEFORMAT=%R; (time sleep 0.1) 2>&1)
$ bc <<< $time
.206

Lub użyj jakiegoś języka skryptowego:

$ ruby -e 'puts "%.3f" % Time.now'
1369329611.046
$ time ruby -e '""'
0.029
$ time ruby -e 'puts "%.3f" % Time.now'
1369329622.943
0.029

%.3fjest specyfikatorem formatu dla liczby zmiennoprzecinkowej z 3 miejscami po przecinku. Time.now to metoda klasowa klasy Time.

Lri
źródło
Dzięki za odpowiedź, czy mógłbyś opisać powyższy kod ruby?
pacodelumberg
1
W ruby -e 'puts "%.3f" % Time.now', rubywywołuje interpreter ruby, -ewykonuje skrypt następujący w wierszu poleceń. putsjest ruby printf(w pewnym sensie), Timejest rubinowym przedmiotem i Time.nowjest sekundą od epoki. Użycie %.3fprzycina dane wyjściowe do 3 miejsc po przecinku, czyli w milisekundach (części „.046” i „.943” danych wyjściowych).
Olie
1
Ponadto timejest narzędziem wiersza polecenia, które mierzy czas potrzebny do uruchomienia następującego polecenia. Zobacz man timepo więcej szczegółów.
Olie,
1

Glenn ma rację, timeto polecenie, którego szukasz, ale aby przeanalizować potrzebne informacje, musisz przekazać je do innego procesora, takiego jak sed.

time command-goes-here >/dev/null 2>$1|sed rules-go-here

To polecenie pozbywa się danych wyjściowych z samego polecenia (wysyłając zarówno dane wyjściowe standardowe, jak i dane błędu do / dev / null) i przekazuje wyniki czasowe do sed, gdzie będziesz musiał wybrać odpowiednie reguły, aby edytować strumień i dane wyjściowe żądana wartość.

Zach Melnick
źródło