Issue
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?
Solution
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 by
mapfile -d, -t -s$((mloop-1)) -n1 kik <<< "${modes[$mmode,2]}"
.
If$mmode
is constant here, better replace the whole loop with
while IFS=, read -r kik; do ...; done <<< "${modes[$mmode,2]}"
.filename=$(basename "$f")
can be replaced by
filename=${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 by
precision=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 into123.45
) until you really need the decimal number.
But if speed really matters, write the script in another language. I think awk
, perl
, or python
would be a good match here.
Answered By - Socowi Answer Checked By - Cary Denson (WPSolving Admin)