I've read that scripts that are calling for a subshell are slow, which would explain why my script are slow.
for example here, where I'm running a loop that gets an number from an array, is this running a subshell everytime, and can this be solved without using subshells?
mmode=1
modes[1,2]="9,12,18,19,20,30,43,44,45,46,47,48,49"
until [[ -z $kik ]];do
((++mloop))
kik=$(echo ${modes[$mmode,2]} | cut -d "," -f $mloop)
filename=$(basename "$f")
# is all these lines
xcolorall=$((xcolorall+$storednr)
# also triggering
pros2=$(echo "100/$totpix*$xcolorall" | bc -l)
IFS='.' read -r pros5 pros6 <<< "$pros2"
procenthittotal2=$pros5.${pros6:0:2}
#subshells and if,
# is it possible to circumvent it?
#and more of the same code..
done
updated: the pros2 variable is calculating percent, how many % xcolorall are of totpix and the kik variable is getting a number from the array modes, informing the loop about what color it should count in this loop. I suspect these are the main hoggers, is there anyway to do this without subshells?
You can replace all the subshells and extern commands shown in your question with bash built-ins.
kik=$(echo ${modes[$mmode,2]} | cut -d "," -f $mloop)
can be replaced bymapfile -d, -t -s$((mloop-1)) -n1 kik <<< "${modes[$mmode,2]}"
.If
$mmode
is constant here, better replace the whole loop withwhile IFS=, read -r kik; do ...; done <<< "${modes[$mmode,2]}"
.filename=$(basename "$f")
can be replaced byfilename=${f##*/}
which runs 100 times faster, see benchmark.pros2=$(echo "100/$totpix*$xcolorall" | bc -l)
can be replaced by(( pros2 = 100 * xcolorall / totpix ))
if you don't care for the decimals, or byprecision=2; (( pros = 10**precision * 100 * xcolorall / totpix )); printf -v pros "%0${precision}d" "$pros"; pros="${pros:0: -precision}.${pros: -precision}"
if you want 2 decimal places.Of course you can leave out the last commands (for turning 12345 into
123.45
) until you really need the decimal number.But if speed really matters, write the script in another language. I think
awk
,perl
, orpython
would be a good match here.