string-split-words.sh (2600B)
1 #!/usr/bin/env bash 2 3 if [[ ! ${BLE_VERSION-} ]]; then 4 _ble_term_IFS=$' \t\n' 5 source ../../src/benchmark.sh 6 _ble_bash_tmout_wa=() 7 fi 8 9 text=$' 10 echo hello world\x20 11 echo hello\t\tworld\t 12 13 echo hello 11 14 ' 15 16 Answer=(echo hello world echo hello world echo hello 11) 17 18 function check-split-implementation { 19 local ret 20 if ! "$1" ret "$text"; then 21 ble/util/print "$1: failed (exit: $?)" >&2 22 return 1 23 fi 24 25 if ((${#ret[@]}!=${#Answer[@]})); then 26 ble/util/print "$1: the size of array is incorrect" >&2 27 return 1 28 fi 29 30 local i 31 for ((i=0;i<${#Answer[@]};i++)); do 32 if [[ ${ret[i]} != "${Answer[i]}" ]]; then 33 ble/util/print "$1: the element ret[$i]='${ret[i]}' is incorrect (expect '${Answer[i]}')" >&2 34 return 1 35 fi 36 done 37 } 38 39 # original impl of ble/string#split-words 40 function split1 { 41 if [[ -o noglob ]]; then 42 IFS=$_ble_term_IFS builtin eval "$1=(\${*:2})" 43 else 44 set -f 45 IFS=$_ble_term_IFS builtin eval "$1=(\${*:2})" 46 set +f 47 fi 48 } 49 check-split-implementation split1 50 ble-measure 'split1 ret "$text"' 51 52 function split2 { 53 builtin eval -- "$1=()" 54 builtin read -r -d '' "${_ble_bash_tmout_wa[@]}" -a "$1" <<< "$2" 55 return 0 56 } 57 check-split-implementation split2 58 ble-measure 'split2 ret "$text"' 59 60 function split3 { 61 if [[ -o noglob ]]; then 62 IFS=$_ble_term_IFS builtin eval "$1=(\$2)" 63 else 64 set -f 65 IFS=$_ble_term_IFS builtin eval "$1=(\$2)" 66 set +f 67 fi 68 } 69 check-split-implementation split3 70 ble-measure 'split3 ret "$text"' 71 72 function split4 { 73 if [[ -o noglob ]]; then 74 IFS=$_ble_term_IFS builtin eval "$1"'=($2)' 75 else 76 set -f 77 IFS=$_ble_term_IFS builtin eval "$1"'=($2)' 78 set +f 79 fi 80 } 81 check-split-implementation split4 82 ble-measure 'split4 ret "$text"' 83 84 function split5 { 85 local IFS=$_ble_term_IFS 86 if [[ -o noglob ]]; then 87 builtin eval "$1=(\$2)" 88 else 89 set -f 90 builtin eval "$1=(\$2)" 91 set +f 92 fi 93 } 94 check-split-implementation split5 95 ble-measure 'split5 ret "$text"' 96 97 # 5.2 5.1 5.0 4.4 4.3 4.2 4.1 4.0 3.2 3.1 3.0 98 # split1 34.5 32.9 33.5 37.7 33.9 38.0 45.3 44.6 44.1 34.4 31.8 99 # split2 58.8 58.2 72.7 75.0 74.5 83.8 94.3 93.6 89.1 92.6 90.2 100 # split3 30.6 30.1 31.1 33.1 31.0 32.0 39.4 38.9 37.6 29.2 27.1 [split1 + only $2] 多少速くなる。 101 # split4 30.0 30.6 30.8 34.8 30.3 33.2 38.2 38.7 37.1 29.0 26.6 [split3 + change quoting] 一緒に計測すると遅くなる傾向 102 # split5 21.0 20.7 20.5 22.8 22.9 25.8 31.6 32.1 30.4 31.0 29.9 [split3 + local instead of tempenv] どうも tempenv は遅い様だ。 103 # 104 # split5 の実装が最も早いのでこれを採用する。