AMD E1-6010 6Gb Swap 0
Сегодня будем собирать пенки на кабачковой икре и протестируем несколько циклов.
Скрипт для тестирования циклов. Каждый цикл выводит два числа.
Первое - число секунд от начала цикла до вывода первого значения.
Второе - число секунд длительности цикла.
Если решите перетестировать у себя - обратите внимание, что в циклах FOR0 и GAWK число итераций прописаны константами.
В остальных - через переменную MAX. Меняйте синхронно. Выводы будут в конце. Рекомендую рассмотреть код.
Может найдете для себя что-то новое. Да, у некоторых циклов обратный порядок. Это для случаев, когда переменная цикла не используется, а важно количество итераций.
#!/bin/bash
declare -i MAX=5000000
declare -i MA1=MAX+1
declare -i Z0=0
declare -i Z1=1
declare -i P
declare LOG=./log.txt
declare LOOPNAME
clear
LOOPNAME=FOR0
P=0
SECONDS=0
for i in {1..5000000};do
if [[ $P -eq 0 ]];then
echo $LOOPNAME $SECONDS
P=1
fi
done
echo $LOOPNAME $SECONDS
LOOPNAME=FOR1
P=0
SECONDS=0
for i in $(seq $Z1 $MAX);do
if [[ $P -eq 0 ]];then
echo $LOOPNAME $SECONDS
P=1
fi
done
echo $LOOPNAME $SECONDS
LOOPNAME=FOR2
P=0
SECONDS=0
seq $Z1 $MAX|for i in $(</dev/stdin);do
if [[ $P -eq 0 ]];then
echo $LOOPNAME $SECONDS
P=1
fi
done
echo $LOOPNAME $SECONDS
LOOPNAME=FOR3
P=0
SECONDS=0
for ((i=$Z0;i++<$MAX;));do
if [[ $P -eq 0 ]];then
echo $LOOPNAME $SECONDS
P=1
fi
done
echo $LOOPNAME $SECONDS
LOOPNAME=FOR4
P=0
SECONDS=0
for ((i=$MAX;i--!=0;));do
if [[ $P -eq 0 ]];then
echo $LOOPNAME $SECONDS
P=1
fi
done
echo $LOOPNAME $SECONDS
LOOPNAME=FOR5
P=0
SECONDS=0
for ((i=$Z1;i<$MA1;i++));do
if [[ $P -eq 0 ]];then
echo $LOOPNAME $SECONDS
P=1
fi
done
echo $LOOPNAME $SECONDS
LOOPNAME=WHL0
P=0
i=$Z0
SECONDS=0
while ((i++<$MAX));do
if [[ $P -eq 0 ]];then
echo $LOOPNAME $SECONDS
P=1
fi
done
echo $LOOPNAME $SECONDS
LOOPNAME=WHL1
P=0
i=$MAX
SECONDS=0
while ((i--));do
if [[ $P -eq 0 ]];then
echo $LOOPNAME $SECONDS
P=1
fi
done
echo $LOOPNAME $SECONDS
gawk 'BEGIN{p=0
for(i = 1;i < 5000000;i++){
if(p==0)
print "GAWK 0";p++}
}'
gawk 'BEGIN{t=systime();p=0
for(i = 1;i < 5000000;i++){
if(p==0){
print "GAWK " systime()-t;p++}
}
print "GAWK "systime()-t}'
— Я немного отделил, поскольку gawk не совсем bash, но привел для примера.
Выводы:
1. Самый быстрый - FOR2 for in (seq)
2. Самый медленный - FOR5 (сишный классический)
3. Несмотря на небольшие разницы в скорости выполнения скорость циклов соизмерима.
4. Циклы for in - ВНАЧАЛЕ получают полный список значений (в памяти) потом быстро его перебирают.
4.1 Эти циклы жрут больше памяти, в случае нехватки - может быть критическая потеря производительности при использовании swap.
4.2 У этих циклов может быть большая задержка на инициализацию цикла. Это может быть критичным - если сам цикл большой, но очень часто происходит прерывание цикла в самом начале.
5. awk (а gawk самый медленный awk) значительно быстрее bash. Если скорость в приоритете - используйте его.
6. Цикл FOR0 вообще нежелательно применять, поскольку пределы цикла и инкремент нельзя задать переменными. только константы. Но сам конструкт {1..5} применять можно и даже нужно в подстановках (но не циклах). Например: ls text{9..27}.txt.
Продолжение следует…








Комментарии