2010-09-21 2 views
5

есть ли какой-либо хороший способ GNU, как измерить среднее (наихудший случай, лучший случай) время выполнения какой-либо программы командной строки? У меня есть фильтр изображений, неуказанное количество изображений, их фильтрация с использованием for-loop в bash. До сих пор я использую время, но я не могу найти способ получения статистики.Среднее время выполнения

+0

@chown В чем смысл вышеуказанного комментария? –

+1

Аналогичный вопрос, который имеет несколько хороших ответов - [bash: среднее время работы над несколькими прогонами] (http://stackoverflow.com/questions/8215482/mean-running-time-over-a-number-of-runs/ 8216082 # 8216082). – chown

ответ

4

Есть интересная программа Perl под названием dumbbench, которая по существу является оберткой вокруг команды time. Он запускает вашу программу несколько раз, отбрасывает выбросы, затем вычисляет некоторую статистику.

Автор имеет несколько статей (here и here) с изложением а) ​​почему бенчмаркинг отстой, и б) какой вид симпатичных графиков вы можете сделать, чтобы ваши номера бенчмаркинга сосать немного меньше.

+0

Я просто надеюсь, что смогу передать разные параметры для каждого прогона, я проведу его сегодня вечером. –

2

Вы на правильном пути с time. Это то, что я использую для предварительного анализа небольшого кода.

Затем я использую python для сбора статистики, считывая вывод time. Чтобы повысить точность, я обычно делаю пробу 10 - 1000 раз, в зависимости от того, сколько времени занимает каждый процесс.

Я не знаком с каким-либо предустановленным GNU-приложением, которое проводит такой анализ.

+1

Если вы собираетесь использовать Python, вы можете использовать [timeit] (http://www.python.org/doc//current/library/timeit.html). – GreenMatt

+1

Еще в прежние времена мы запускали программу 12 раз, используя «время», выбрасывали лучшие и худшие времена, а затем усредняли оставшиеся 10 значений. –

+0

Мне нравится тайм! Я просто рекомендую писать сообщения из 'time', потому что я не хочу, чтобы python контролировал выполнение моих команд и тем самым потенциально замедлял выполнение, захватывая stdin и whatnot. Это вроде как, я должен использовать C или использовать Python: Такое чувство. – Sean

6

Вы можете отправить вывод времени в какой-то файл, а затем «работать» этот файл

echo "some info" >> timefile.txt 
time (./yourprog parm1 parm2) 2>> timefile.txt 
+2

Вам не нужны скобки. –

+0

На моем компьютере (версия bash 4.1.5 (1) -release (x86_64-pc-linux-gnu)), без скобок, '2 >>' применяется к внутренней программе – pmg

+0

@DennisWilliamson То же самое здесь, я также * * do ** нужен parens. – chown

2
#!/bin/bash 
for i in {1..100} 
do 
    env time --append -o time_output.txt ./test_program --arguments-to-test-program 
done 
exit 

Если вы обнаружили, что {1..100} синтаксис не работает для вас то вам следует взглянуть на команду seq.

Я использовал env time для выполнения временной программы, а не встроенной команды оболочки, которая не принимает всех аргументов, которые принимает программа времени. Программа времени также принимает другие аргументы, чтобы изменить формат ее вывода, который вы, вероятно, захотите использовать, чтобы упростить обработку данных другой программой. Аргумент -p (--portability) выводит его в формате POSIX (например, время встроенного времени BASH), но с использованием опции -f вы можете получить больше контроля. man 1 time для получения дополнительной информации.

После того как вы собрали свои данные, простой скрипт perl или python может легко анализировать и анализировать ваши данные синхронизации.

+0

Вам не нужно использовать 'seq'. Вы можете сделать 'for ((i = 1; i <= 100; i ++))'. –

+0

Если возможно, я хочу, чтобы не писать собственный анализатор, если кто-то еще это сделал. –

0

Вы должны рассмотреть вопрос о том, нужно ли время для внешнего цикла и делить на повторения, а не на каждую итерацию отдельно. Если вы беспокоитесь об отбрасывании максимума и минимума, просто сделайте еще несколько итераций, чтобы заглушить их.

time for i in {1..1000} 
do 
    something 
done 

Вы можете capture the output from time in a variable:

foo=$({ time { 
    echo "stdout test message demo" 
    for i in {1..30} 
    do 
     something 
    done 
    echo "stderr test message demo" >&2 
} 1>&3 2>&4; } 2>&1) 

и сделать некоторые поддельные математику:

foo=${foo/.}   # "divide" by ... 
echo "0.00${foo/#0}" # ... 1000 

Или просто использовать bc:

echo "scale=8; $foo/1000" | bc 
Смежные вопросы