
私は次のように文字列パディングの最高のパフォーマンスを決定しようとしています:
str+="A"
#one perloop
Bash用の次のスクリプトがあります。
#!/bin/bash
bReport=false
nLimit=${1-3000}; #up to 25000
echo "nLimit='$nLimit'"
shopt -s expand_aliases
nStop=100000;fMaxWorkTime=1.0;
alias GetTime='date +"%s.%N"';
nTimeBegin="`GetTime`";
nDelayPart="`GetTime`";
strFinal="";
str="";
fPartWorkSleep="`bc <<< "scale=10;($fMaxWorkTime/$nStop)*$nLimit"`"
echo "fPartWorkSleep='$fPartWorkSleep'"
nCount=0;
while true;do
str+="A";
((nCount++))&&:;
if(((nCount%nLimit)==0)) || ((nCount==nStop));then
strFinal+="$str";
str="";
if $bReport;then
echo "`bc <<< "$(GetTime)-$nDelayPart"` #${#strFinal} #`bc <<< "$(GetTime)-$nTimeBegin"`";
nDelayPart="`GetTime`";
fi
sleep $fPartWorkSleep # like doing some weigthy thing based on the amount of data processed
fi;
if((nCount==nStop));then
break;
fi;
done;
echo "strFinal size ${#strFinal}"
echo "took `bc <<< "$(GetTime)-$nTimeBegin"`"
Bashでは、最高のパフォーマンス/サイズはstr
3000〜25000文字(マイコンピュータでは)に制限されています。各セクションがいっぱいになると空にする必要がありますstr
。
私の質問は、どのシェルが文字列パディングのパフォーマンスが最善ですか?私が公開した内容に基づいています。私はこのアルゴリズムがより高速であることが証明されている場合は、bash以外のシェルを使用することになります。
PS:パフォーマンスを低下させる文字列サイズを確認する方法としてnCountを使用する必要がありました。
答え1
for sh in bash zsh yash dash mksh ksh
do printf "\n%s:\t" "$sh"
time "$sh" -c '
str="some string"
set "" ""
while ${20001+"break"}
do set "$@$@";done
IFS=A; printf %.100000s\\n "$str$*$*$*$*$*"'|
wc -c
done
bash: 100001
"$sh" -c 0.15s user 0.01s system 94% cpu 0.176 total
wc -c 0.00s user 0.00s system 1% cpu 0.175 total
zsh: 100001
"$sh" -c 0.03s user 0.01s system 97% cpu 0.034 total
wc -c 0.00s user 0.00s system 9% cpu 0.034 total
yash: 100001
"$sh" -c 0.06s user 0.01s system 94% cpu 0.067 total
wc -c 0.00s user 0.00s system 5% cpu 0.067 total
dash: 100001
"$sh" -c 0.02s user 0.01s system 92% cpu 0.029 total
wc -c 0.00s user 0.00s system 11% cpu 0.028 total
ksh: 100001
"$sh" -c 0.02s user 0.00s system 96% cpu 0.021 total
wc -c 0.00s user 0.00s system 16% cpu 0.021 total
$sh
したがって、これはfor
ループに設定されたさまざまなシェルが100,000文字列を生成できる速度のテストでした。 100,000文字のうち最初の11文字は次のとおりです。some string
asは最初に値に設定されていましたが、$str
尾部分は999,989として追加されました。A
性格。
殻は得るA
charsは、シェルパラメータ配列の各位置パラメータ間の接続区切り文字で、特殊シェル$*
パラメータ値の最初の文字を置き換えます。$IFS
すべてのパラメータが""
空なので$*
はい分離記号。
ループが繰り返されるたびに、パラメータは指数関数的な割合で累積されますwhile
。これは、パラメータが最終的に表示されたbreak
ときにのみ発生します。それまで、ループは基本的に次のことを行います。$20001
${set+}
while
### first iteration
while $unset_param; do set "" """" ""; done
### second iteration
while $unset_param; do set "" "" """" "" ""; done
### third iteration
while $unset_param; do set "" "" "" "" """" "" "" "" ""; done
...など。
while
ループが完了した後、$IFS
次に設定されます。A
そして、特別なシェルパラメータは$*
最後に5回接続されます$str
。結果をprintf
stdoutに書き込む前に%s
最大バイト数に切り捨てます。.100000
人々は次のような同じ戦術を使用することができます。
str='some string'
set "" ""
while ${51+"break"}; do set "$@$@"; done
shift "$((${#}-(51-${#str}))"
...合計40個のパラメータが生成されるため、区切り記号は39個です。
IFS=.; printf %s\\n "$str$*"
some string.......................................
他の設定に設定された同じ$IFS
パラメータを再利用することもできます。いっぱい:
for IFS in a b c; do printf %s\\n "$str$*"; done
some stringaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
some stringbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
some stringccccccccccccccccccccccccccccccccccccccc
printf
以下を使用する代わりに、フォーマット文字列を使用して空のパラメータを入力することもできます$IFS
。
printf "%s m%sy%1ss%st%sr%si%sn%sg" "$str$@"
some string my string my string my string my string my string