#!/bin/bash # StringContain method comparison between `case` and `parameter expansion` # (C) 2023 Felix Hauri - felix@f-hauri.ch # Licensed under terms of GPL v3. www.gnu.org # Run 42 hecti loops with `dash`, `busybox shell`, `bash` and `ksh`. # Then compare method performances under each shell (not between shells) # with short or long string and complex substring. reqTestCnt=${1:-$(( 42 * 128 ))} testCase() { cat <<-"eoCase" string="$1"; substr="$2"; doloop=$3 while [ $doloop -gt 0 ]; do doloop=$((doloop-1)) case $string in *$substr*) ret=yes ;; *) ret=no ;; esac done; echo $ret eoCase } testPExp() { cat <<-"eoPExp" string="$1"; substr="$2"; doloop=$3 while [ $doloop -gt 0 ]; do doloop=$((doloop-1)) if [ -z "$substr" ] || { [ -z "${string##*$substr*}" ] && [ -n "$string" ];} then ret=yes; else ret=no; fi done; echo $ret eoPExp } longStr='Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam non' longStr+='ummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volu' longStr+='tpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamc' longStr+='orper suscipit lobortis nisl ut aliquip ex comm' longStr="$longStr $longStr" longStr="$longStr $longStr." results=() ; declare -A overall for test in Case PExp; do testcnt=0 for shell in 'busybox sh' dash ksh bash; do for string in 'echo "My string"' "Don't miss quotes" '' "$longStr"; do for substr in "'t mis" 'o "My' "s" "Y" "" \ "${longStr::12}" "${longStr: -12}" Long\"\ \'test.; do st=$EPOCHREALTIME res=$($shell <(test$test) "$string" "$substr" $reqTestCnt) end=$EPOCHREALTIME elap=00000$((${end/.}-${st/.})) if [[ -v results[testcnt] ]]; then pres=${results[testcnt]% *} pelap=${results[testcnt]#* } prct=00$(( 10#$elap * 100000 / pelap )) overall[${shell%% *}]+=$((10#$prct))+ if [[ $pres == $res ]]; then res=same; else res=DIFF; fi printf '%-8s %s %-16s %-12s %4d %4d %4s %9.5fs %8.2f%%\n'\ ${shell% *} $test "${string::16}" "${substr}" \ ${#string} ${#substr} $res ${elap::-6}.${elap: -6} \ ${prct::-3}.${prct: -3} else results[testcnt]="$res ${elap#00000}" printf '%-8s %s %-16s %-12s %4d %4d %4s %9.5fs\n'\ ${shell% *} $test "${string::16}" "${substr}" \ ${#string} ${#substr} $res ${elap::-6}.${elap: -6} fi (( testcnt++ )) done done done done valcnt=${overall[bash]//[0-9]} for shell in ${!overall[@]}; do prct=000$(( ( ${overall[$shell]}0 ) / ${#valcnt} )) printf 'Comparing time PExp vs Case method under %-8s: %9.2f%%\n' $shell \ ${prct::-3}.${prct: -3} done