보편적 인 비 배쉬 ‘시간’벤치 마크 대안? [닫은]

다른 쉘 사이에 스크립트의 실행 시간을 비교를 들어, 일부 SE의 대답은 사용하는 것이 좋습니다 bashs의 ‘ 내장 time 명령과 같이 :

time bash -c 'foo.sh'
time dash -c 'foo.sh'

모든 쉘을 테스트합니다. 이러한 벤치 마크는 각 쉘이 자체 로드 및 초기화하는 데 걸리는 시간을 제거하지 못합니다 . 예를 들어, 위의 두 명령이 초기 플로피 디스크의 읽기 속도 (124KB / s) dash( ~ 150K 실행 파일) 의 읽기 속도로 느린 장치 에 저장되었다고 가정하면 ( 쉘 은 ( ~ 1M ) 보다 약 7 배 빠릅니다. 로딩 시간은 숫자를 왜곡 할 수 있습니다. 쉘을로드 한 후 각 쉘 아래 의 실행 시간을 측정하는 것과 관련이없는 쉘의 사전 로딩 시간입니다 .bashtimefoo.sh

각 셸 내에서 실행할 수있는 스크립트 타이밍에 가장 적합한 휴대용 유틸리티는 무엇입니까 ? 위의 코드는 다음과 같습니다.

bash -c 'general_timer_util foo.sh'
dash -c 'general_timer_util foo.sh'

NB : 이식 가능한 명령이나 일반 명령이 없기 때문에 쉘 내장 time 명령이 없습니다.


유틸리티가 셸의 내부 명령 및 파이프 라인에서 소요되는 시간을 사용자가 스크립트로 먼저 랩핑하지 않고도 벤치마킹 할 수 있다면 더 좋습니다. 이와 같은 인공 구문이 도움이 될 것입니다.

general_timer_util "while read x ; do echo x ; done < foo"

일부 껍질 time은 이것을 관리 할 수 ​​있습니다. 예를 들어 bash -c "time while false ; do : ; done"작동합니다. 시스템에서 작동하는 것과 작동하지 않는 것을 보려면 다음을 시도하십시오.

tail +2 /etc/shells |
while read s ; do
    echo $s ; $s -c "time while false ; do : ; done" ; echo ----
done


답변

당신은이주의해야 timePOSIX로 지정 하고, (POSIX 언급하는 유일한 옵션을 AFAICT -p다양한 쉘에 의해 올바르게 지원) :

$ bash -c 'time -p echo'

real 0.00
user 0.00
sys 0.00
$ dash -c 'time -p echo'

real 0.01
user 0.00
sys 0.00
$ busybox sh -c 'time -p echo'

real 0.00
user 0.00
sys 0.00
$ ksh -c 'time -p echo'

real 0.00
user 0.00
sys 0.00

답변

고해상도 타이머를 지원하는 GNU date 명령을 사용합니다 .

START=$(date +%s.%N)
# do something #######################

"$@" &> /dev/null

#######################################
END=$(date +%s.%N)
DIFF=$( echo "scale=3; (${END} - ${START})*1000/1" | bc )
echo "${DIFF}"

그런 다음 스크립트를 다음과 같이 호출합니다.

/usr/local/bin/timing dig +short unix.stackexchange.com
141.835

출력 단위는 밀리 초입니다.


답변

time유틸리티는 일반적으로 당신이 “중립”타이머로는 쓸모하게하는, 눈치 것처럼, 쉘에 내장되어 있습니다.

그러나이 유틸리티는 일반적으로 외부 유틸리티로도 사용할 수 있으며 /usr/bin/time제안한 타이밍 실험을 수행하는 데 사용될 수도 있습니다.

$ bash -c '/usr/bin/time foo.sh'

답변

해결책은 다음과 같습니다.

  1. 각 셸이로드되고 초기화되는 데 걸리는 시간을 제거합니다.

  2. 각 쉘 에서 실행할 수 있습니다

  3. 용도

    time이식성이 없거나 일반적인 것은 없기 때문에 쉘 내장 명령이 없습니다.

  4. 모든 POSIX 호환 쉘에서 작동합니다.
  5. C 컴파일러 를 사용하거나 C 실행 파일을 미리 컴파일 할 수있는 모든 POSIX 호환 및 XSI 호환 시스템 에서 작동합니다.
  6. 모든 쉘에서 동일한 타이밍 구현을 사용합니다.

랩핑하는 짧은 C 프로그램 ( gettimeofday더 이상 사용되지 않지만보다 이식성이 뛰어남 clock_gettime)과 해당 프로그램을 사용하여 스크립트 소싱의 양면을 읽는 마이크로 초 정밀도 클록을 얻는 짧은 쉘 스크립트가 있습니다. C 프로그램은 타임 스탬프에서 1 초 미만의 정밀도를 얻을 수있는 유일한 휴대용 및 오버 헤드 방식입니다.

C 프로그램은 다음과 같습니다 epoch.c.

#include <sys/time.h>
#include <stdio.h>
int main(int argc, char **argv) {
    struct timeval time;
    gettimeofday(&time, NULL);
    printf("%li.%06i", time.tv_sec, time.tv_usec);
}

그리고 쉘 스크립트 timer:

#!/bin/echo Run this in the shell you want to test

START=$(./epoch)
. "$1"
END=$(./epoch)
echo "$END - $START" | bc

이것은 표준 쉘 명령 언어 이며 bcPOSIX 호환 쉘에서 스크립트로 작동해야합니다.

이것을 다음과 같이 사용할 수 있습니다.

$ bash timer ./test.sh
.002052
$ dash timer ./test.sh
.000895
$ zsh timer ./test.sh
.000662

그것은 시스템 또는 사용자 시간을 측정하지 않고, 벽이 아닌 벽시계 경과 시간 만 측정합니다. 스크립트 실행 중에 시스템 시계가 변경되면 잘못된 결과가 나타납니다. 시스템에 부하가 걸리면 결과를 신뢰할 수 없습니다. 나는 쉘 사이에 더 나은 것을 이식 할 수 있다고 생각하지 않습니다.

수정 된 타이머 스크립트는 eval대신 스크립트 외부에서 명령을 실행하는 데 사용할 수 있습니다 .


답변

여러 번 사용하여 솔루션을 수정 /proc/uptime하고 dc/ bc/ awk에 의해 입력에 큰 부분에 감사 AGC :

#!/bin/sh

read -r before _ < /proc/uptime

sleep 2s # do something...

read -r after _ < /proc/uptime

duration=$(dc -e "${after} ${before} - n")
# Alternative using bc:
#   duration=$(echo "${after} - ${before}" | bc)
# Alternative using awk:
#   duration=$(echo "${after} ${before}" | awk '{print $1 - $2}')

echo "It took $duration seconds."

분명히 /proc/uptime존재하고 특정 형태를 가지고 있다고 가정 합니다.