Dla porównania prowadzone razy skryptów między różnymi muszli, niektóre odpowiedzi SE sugerować przy użyciu bash
„s wbudowane time
polecenia, tak jak poniżej:
time bash -c 'foo.sh'
time dash -c 'foo.sh'
... itd. dla każdej powłoki do przetestowania. Takie odniesienia nie eliminuje czas potrzebny dla każdej muszli załadować i zainicjować sama . Załóżmy na przykład, że oba powyższe polecenia zostały zapisane na wolnym urządzeniu z prędkością odczytu wczesnej dyskietki (124KB / s) dash
( plik wykonywalny ~ 150K ) ładowałby się około 7 razy szybciej niż bash
( ~ 1M ) powłoka czas ładowania będzie pochylać się time
numery - czasów pre-loading tych pocisków nie ma znaczenia do pomiaru czasów pracy foo.sh
pod każdym skorupy po pociski zostały załadowane.
Jakie jest najlepsze przenośne i ogólne zastosowanie do uruchamiania taktowania skryptów, które można uruchomić z poziomu każdej powłoki? Tak więc powyższy kod wyglądałby mniej więcej tak:
bash -c 'general_timer_util foo.sh'
dash -c 'general_timer_util foo.sh'
Uwaga: brak wbudowanych time
poleceń powłoki , ponieważ żadne nie są przenośne ani ogólne.
Jeszcze lepiej, jeśli util jest również w stanie przeprowadzić analizę porównawczą czasu potrzebnego na wewnętrzne polecenia i potoki powłoki, bez konieczności uprzedniego zawijania ich przez skrypt w skrypcie. Sztuczna składnia taka jak ta pomogłaby:
general_timer_util "while read x ; do echo x ; done < foo"
Niektóre powłoki time
mogą sobie z tym poradzić. Na przykład bash -c "time while false ; do : ; done"
działa. Aby zobaczyć, co działa (i nie działa) w twoim systemie, spróbuj:
tail +2 /etc/shells |
while read s ; do
echo $s ; $s -c "time while false ; do : ; done" ; echo ----
done
/usr/bin/time
?Odpowiedzi:
Należy zauważyć, że
time
jest to określone przez POSIX , a AFAICT jedyna opcja, o której POSIX wspomina (-p
) jest poprawnie obsługiwana przez różne powłoki:źródło
time
. Jest to porównywalne z pozwalaniem sprinterom mierzyć swój czas na 100 m indywidualnie, zamiast robić to z jednym zegarem w tym samym czasie. To oczywiście podstępne, ale nadal ...time
nie jest przenośna; wydaje się być przenośny. (Zgadzam się jednak z twojądash -c 'time -p while false ; do : ; done'
zwraca „czas: nie można uruchomić, dopóki: Nie zakończono takiego pliku lub katalogu <cr> Komenda z błędami o niezerowym statusie 127” .Używam polecenia GNU
date
, które obsługuje zegar wysokiej rozdzielczości:A potem wywołuję skrypt w następujący sposób:
Jednostka wyjściowa jest w milisekundach.
źródło
date
szczególności GNU .START
iEND
ustawieniem, to oczywiście wpłynie na twój wynik. Nie mam pojęcia, jak precyzyjnie go potrzebujesz i czy ma to znaczenie w twoim przypadku, ale tak jak powiedziałem, należy pamiętać. (Zabawna historia: znam oprogramowanie, w którym dokładnie doprowadziło do nieoczekiwanie negatywnych wyników - było używane do obliczeń przepustowości - które następnietime
Narzędzie jest zwykle wbudowany w skorupkach, jak zauważyłeś, co czyni go bezużytecznym jako „neutralny” timer.Jednak narzędzie jest zwykle dostępne również jako narzędzie zewnętrzne
/usr/bin/time
, które może być również wykorzystane do przeprowadzenia proponowanych eksperymentów czasowych.źródło
foo.sh
jest wykonywalny i ma shebang, to zawsze uruchamia go z tą samą powłoką i nie liczy czasu uruchamiania tej powłoki, więc nie tego chce OP. Jeślifoo.sh
brakuje jednego z nich, to w ogóle nie działa.time
Wydaje mi się, że wziąłem pod uwagę tylko „brak wbudowanej powłoki ”. Czas uruchamiania powłoki może wymagać pomiaru osobno.time
wbudowane polecenie. Jednak wiele muszle tymbash
majątime
słowo kluczowe, które mogą być używane do rurociągów czasowych. Aby wyłączyć to słowo kluczowe, abytime
można było użyć polecenia (w systemie plików), możesz zacytować go tak"time" foo.sh
. Zobacz także unix.stackexchange.com/search?q=user%3A22565+time+keywordOto rozwiązanie, które:
Składa się z dwóch części: krótkiego programu C, który się kończy
gettimeofday
, który jest przestarzały, ale wciąż bardziej przenośny niżclock_gettime
i krótkiego skryptu powłoki, który używa tego programu, aby uzyskać zegar o precyzji mikrosekundowej odczytujący obie strony pozyskiwania skryptu. Program C jest jedynym przenośnym i minimalnym narzutem sposobem uzyskania precyzji poniżej sekundy na znaczniku czasu.Oto program C
epoch.c
:I skrypt powłoki
timer
:Jest to standardowy język poleceń powłoki i
bc
powinny działać jako skrypt pod dowolnym kompatybilnym z POSIX powłoki.Możesz użyć tego jako:
Nie mierzy czasu systemowego ani użytkownika, a jedynie upływ czasu niemonotonicznego zegara ściennego. Jeśli zegar systemowy zmieni się podczas wykonywania skryptu, da to nieprawidłowe wyniki. Jeśli system jest obciążony, wynik będzie niewiarygodny. Nie sądzę, żeby coś lepszego można było przenosić między pociskami.
eval
Zamiast tego można użyć skryptu timera do uruchamiania poleceń poza skryptem.źródło
eval
), poprawiałem skrypt w odpowiedzi Rabina , aby włączyćeval "$@"
, aby mógł on uruchamiać wbudowane powłoki w locie.Wielokrotnie poprawione rozwiązanie wykorzystujące
/proc/uptime
idc
/bc
/awk
w dużych częściach dzięki wprowadzeniu przez agc :Zakłada oczywiście, że
/proc/uptime
istnieje i ma pewną formę.źródło
/proc
systemu plików. Jeśli to dotyczy, czy nie, nie wiem.awk
może być znaczny. Możeb=$(cat /proc/uptime)
przed, potema=$(cat /proc/uptime)
po, a następnie przeanalizuj $ a i $ b i odejmij.read
były lepsze niżcat
, byłoby to czystsze (i trochę szybciej):read before dummyvar < /proc/uptime ;sleep 2s;read after dummyvar < /proc/uptime; duration=$(dc -e "${after} ${before} - n");echo "It took $duration seconds."