쉘 스크립트의 문자열 패딩 성능: 최적의 양은 얼마이며 어떤 쉘에 적합합니까?

쉘 스크립트의 문자열 패딩 성능: 최적의 양은 얼마이며 어떤 쉘에 적합합니까?

나는 다음과 같이 문자열 패딩에 대한 최상의 성능을 결정하려고 합니다:
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에서 최고의 성능/크기는 str3000~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 stringas 는 처음에 값으로 설정되었지만 $str꼬리 부분은 999,989로 추가되었습니다.A성격.

껍질은 얻는다Achars는 쉘 매개변수 배열의 각 위치 매개변수 사이의 연결 구분 기호로 $*특수 쉘 매개변수 값의 첫 번째 문자를 대체합니다 . $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. 결과를 printfstdout에 쓰기 전에 %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

관련 정보