Сегодня будем собирать “сливки на молоке”. Поговорим немного об оптимизации bash по времени исполнения.
Все помнят, что есть команда time, которая с точностью до 1e-3 может подсчитать время выполнения конвейера.
Для перфекционистов, вроде меня, есть переменная EPOCHREALTIME, которая выдает текущее время в системе с точностью до 1e-6, т.е до микросекунды.
Но для ее использования есть два препятствия:
Она в вещественном формате, а bash не работает с вещественными числами.
Разделитель дробной части зависит от языковых настроек. (где-то точка, где-то запятая…)
Попробуем решить эти проблемы. Простая функция. Вычисляет разницу RealTime2-RealTime1 в микросекундах. Если RealTime2 не задана - принимается EPOCHREALTIME.
#uTIME RealTime1 [RealTime2]
function uTIME(){
local T2=${2:-$EPOCHREALTIME}
local T1=${1:-$T2}
T2=${T2/[^0-9]/} ;T1=${T1/[^0-9]/}
# ((T2-T1)) && \
echo $((T2-T1))
}
Ну и теперь, вооружившись инструментом, попробуем использовать на практике:
Сравним время выполнения двух функций B1 - исполняется в текущей среде, B2 - исполняется в subshell
Сравним преобразование числа в дату с помощью
dateиprintf
#!/bin/bash
function uTIME(){
local T2=${2:-$EPOCHREALTIME}
local T1=${1:-$T2}
T2=${T2/[^0-9]/} ;T1=${T1/[^0-9]/}
# ((T2-T1)) && \
echo $((T2-T1))
}
function B1(){ :;}
function B2()(:)
uTIME
echo -n 'function {} = '
T=$EPOCHREALTIME
B1
uTIME $T
echo -n 'function () = '
T=$EPOCHREALTIME
B2
uTIME $T
echo -n 'printf -v VAR "%(%Y%m%d)T" 1746024063 = '
T=$EPOCHREALTIME
printf -v VAR "%(%Y%m%d)T" 1746024063
uTIME $T
echo -n 'VAR=$(date -d@1746024063) = '
T=$EPOCHREALTIME
VAR=$(date -d@1746024063 +%Y%m%d)
uTIME $T
Обратите внимание - результаты отличаются на порядок.
Первый (пустой) вызов uTIME нужен потому, что первый вызов функции всегда выполняется дольше, чем последующие. Если кого-то напрягает “0” на экране при инициализации - раскомментируйте строчку # ((T2-T1)) && </code>
Если нужно засечь время выполнения в контрольных точках - используйте массив:
RT+=($EPOCHREALTIME)
При каждом исполнении этого оператора в массив будет добавляться время контрольной точки. Время исполнения между точками можно будет вычислить как
uTIME ${RT[N]} ${RT[N+1]}
Исследуйте bash, оптимизируйте, развивайтесь.








Комментарии