나는 다음과 같이 문자열 패딩에 대한 최상의 성능을 결정하려고 합니다:
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 이외의 쉘을 사용할 의향이 있습니다.
추신: 성능을 저하시키는 문자열 크기를 확인하는 방법으로 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