201903-mapfile.sh (2998B)
1 #!/usr/bin/env bash 2 3 if [[ ! ${BLE_VERSION-} ]]; then 4 source ../../src/benchmark.sh 5 fi 6 7 _ble_util_assign_base="/dev/shm/$UID.$$.read-stdout.tmp" 8 _ble_util_assign_level=0 9 10 function ble/util/mapfile { 11 local _ble_local_i=0 _ble_local_val _ble_local_arr; _ble_local_arr=() 12 while builtin read -r _ble_local_val || [[ $_ble_local_val ]]; do 13 _ble_local_arr[_ble_local_i++]=$_ble_local_val 14 done 15 builtin eval "$1=(\"\${_ble_local_arr[@]}\")" 16 } 17 18 #------------------------------------------------------------------------------ 19 # split-lines 20 21 function ble/util/uparr { builtin unset -v "$1" && builtin eval "$1=(\"\${@:2}\")"; } 22 function ble/string#split { 23 if [[ -o noglob ]]; then 24 # Note: 末尾の sep が無視されない様に、末尾に手で sep を 1 個追加している。 25 IFS=$2 builtin eval "$1=(\${*:3}\$2)" 26 else 27 set -f 28 IFS=$2 builtin eval "$1=(\${*:3}\$2)" 29 set +f 30 fi 31 } 32 function split-lines.1 { 33 local name=$1 text=${*:2} sep='' esc='\' 34 if [[ $text == *$sep* ]]; then 35 local a b arr ret value 36 a=$esc b=$esc'A' text=${text//"$a"/"$b"} 37 a=$sep b=$esc'B' text=${text//"$a"/"$b"} 38 39 text=${text//$'\n'/"$sep"} 40 ble/string#split arr "$sep" "$text" 41 42 for value in "${arr[@]}"; do 43 if [[ $value == *$esc* ]]; then 44 a=$esc'B' b=$sep value=${value//"$a"/"$b"} 45 a=$esc'A' b=$esc value=${value//"$a"/"$b"} 46 fi 47 ret[${#ret[@]}]=$value 48 done 49 else 50 local ret 51 text=${text//$'\n'/"$sep"} 52 ble/string#split ret "$sep" "$text" 53 fi 54 local "$name" && ble/util/uparr "$name" "${ret[@]}" 55 } 56 function split-lines.2 { 57 ble/util/mapfile "$1" <<< "$2" 58 } 59 function ble/string#split-lines { 60 split-lines.2 "$@" 61 } 62 63 data=$(< array-reverse.sh) 64 65 ble-measure 'split-lines.1 arr1 "$data"' # 532000.00 usec/eval (x1) 66 ble-measure 'split-lines.2 arr1 "$data"' # 8945.00 usec/eval (x20) 67 68 #------------------------------------------------------------------------------ 69 70 function assign { 71 eval "${@:2}" >| "$_ble_util_assign_base" 72 local _ret="$?" 73 IFS= read -r -d '' "$1" < "$_ble_util_assign_base" 74 return "$_ret" 75 } 76 77 function ble/util/assign { 78 local _ble_local_tmp=$_ble_util_assign_base.$((_ble_util_assign_level++)) 79 builtin eval "$2" >| "$_ble_local_tmp" 80 local _ble_local_ret=$? 81 ((_ble_util_assign_level--)) 82 IFS= builtin read -r -d '' "$1" < "$_ble_local_tmp" 83 eval "$1=\${$1%$'\n'}" 84 return "$_ble_local_ret" 85 } 86 87 function assign-array.1 { 88 ble/util/assign "$@" 89 if [[ ${!1} ]]; then 90 ble/string#split-lines "$1" "${!1%$'\n'}" 91 else 92 eval "$1=()" 93 fi 94 } 95 function assign-array.2 { 96 local _ble_local_tmp=$_ble_util_assign_base.$((_ble_util_assign_level++)) 97 builtin eval "$2" >| "$_ble_local_tmp" 98 local _ble_local_ret=$? 99 ((_ble_util_assign_level--)) 100 ble/util/mapfile "$1" < "$_ble_local_tmp" 101 return "$_ble_local_ret" 102 } 103 104 ble-measure 'assign-array.1 arr1 "cat array-reverse.sh"' # 11900.00 usec/eval (x10) 105 ble-measure 'assign-array.2 arr1 "cat array-reverse.sh"' # 4536.00 usec/eval (x50)