sistema_progs

Programas para customizar o meu entorno de traballo nos meus equipos persoais
Log | Files | Refs

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)