[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: efficient way to use matched string in variable substitution
From: |
Koichi Murase |
Subject: |
Re: efficient way to use matched string in variable substitution |
Date: |
Wed, 25 Aug 2021 09:43:05 +0900 |
Fun to see different techniques from different people. I have also
played with this interesting problem. In my environment, the following
implementations seem to be the fastest.
f21b() { local -a "arr=('\${1:'{0..$((${#1}-1))}':1}')";
arr=("${arr[@]@P}"); } # Any strings
f31() { local arr i=${#1} v=$1 x='arr[--i]=v%10,v/=10,i&&x'; : $((x));
} # Only numbers ([0-9]+)
I compared the following implementations:
# L A Walsh
f1() { local x n="$1" arr; for x in 0 1 2 3 4 5 6 7 8 9; do
n=${n//$x/$x }; done; arr=($n); }
f2() { local i n="${#1}" arr; for ((i=0; i<n; i++)); do
arr+=("${1:i:1}"); done; }
# Greg Wooledge
f3() { local n="$1" tmp arr i; while ((n > 0)); do tmp+=("$((n%10))");
((n /= 10)); done; for ((i=${#tmp[@]}-1; i >= 0; i--)); do
arr+=("${tmp[i]}"); done; }
f4() { local n="$1" i=${#1} arr; while ((n > 0)); do
arr[--i]=$((n%10)); ((n /= 10)); done; }
f5() { local i n=${#1} arr; while ((i < n)); do arr[i]="${1:i:1}";
((i++)); done; }
f6() { local i n=${#1} arr; for ((i=0; i<n; i++)); do arr[i]="${1:i:1}"; done; }
# Lea Gris
shopt -s extglob
f7() { local arr; IFS=' ' read -ra arr <<< "${1//?()/ }"; }
f8() { local arr; IFS= mapfile -s1 -t -d $'\37' arr
<<<"${1//?()/$'\37'}"; arr[-1]="${arr[-1]%?}"; }
# Mike Jonkmans
f12() { local arr; [[ "$1" =~ ${1//?/(.)} ]]; arr=( "${BASH_REMATCH[@]:1}" ); }
# my experiments with brace expansions and eval
f20() { local arr; eval "for i in {0..$((${#1}-1))}; do
arr[i]=\${1:i:1}; done"; }
f21() { local arr; eval "arr=('\${1:'{0..$((${#1}-1))}':1}')";
arr=("${arr[@]@P}"); }
f21b() { local -a "arr=('\${1:'{0..$((${#1}-1))}':1}')"; arr=("${arr[@]@P}"); }
f22() { local arr; eval "arr=('\"\${1:'{0..$((${#1}-1))}':1}\"')";
local -a "arr=(${arr[*]})"; }
f23() { local arr; eval "arr=('\"\${1:'{0..$((${#1}-1))}':1}\"')";
eval "arr=(${arr[*]})"; }
f24() { local -a "arr=('\"\${1:'{0..$((${#1}-1))}':1}\"')"; local -a
"arr=(${arr[*]})"; }
# my experiments with arithmetic evaluations
f30() { local arr; eval "let i={1..${#1}}-1,'arr[i]=$1/10**i%10'"; }
f31() { local arr i=${#1} v=$1 x='arr[--i]=v%10,v/=10,i&&x'; : $((x)); }
The result is summarized in the following table:
NAME ARG bash-5.0 bash-5.1 bash-dev
---- --- ---------------- ---------------- ----------------
f1 *N 37.633 usec/eval 39.822 usec/eval 39.791 usec/eval
f2 *A 44.171 usec/eval 42.643 usec/eval 43.752 usec/eval
f3 *N 79.760 usec/eval 77.892 usec/eval 79.842 usec/eval
f4 *N 39.870 usec/eval 40.510 usec/eval 40.929 usec/eval
f5 *A 42.635 usec/eval 43.349 usec/eval 43.617 usec/eval
f6 *A 39.060 usec/eval 40.191 usec/eval 40.704 usec/eval
f7 *B 35.110 usec/eval 30.255 usec/eval 31.550 usec/eval
f8 *R 46.324 usec/eval 36.974 usec/eval 37.672 usec/eval
f12 *A 30.016 usec/eval 30.566 usec/eval 31.865 usec/eval
f20 *A 37.930 usec/eval 38.076 usec/eval 38.143 usec/eval
f21 *A 36.189 usec/eval 34.517 usec/eval 34.967 usec/eval
f21b *A 29.954 usec/eval 28.655 usec/eval 29.729 usec/eval
f22 *A 39.251 usec/eval 37.458 usec/eval 38.099 usec/eval
f23 *A 45.939 usec/eval 42.630 usec/eval 43.187 usec/eval
f24 *A 33.615 usec/eval 31.600 usec/eval 32.905 usec/eval
f30 *N 28.908 usec/eval 28.750 usec/eval 28.871 usec/eval
f31 *N 23.723 usec/eval 23.659 usec/eval 24.366 usec/eval
The column ARG denotes the accepted type of the argument: *N = only
numbers are accepted, *A = any characters (except for NUL), *B = any
non-space characters, *R = any characters except for RS. bash-dev is
built with "define(relstatus, release)" (configure.ac:27). The
times are measured by EPOCHREALTIME. I have run "fN 682390" for
5000 times and obtained the average time of each call. The whole
measurements are repeated five times, and the minimal time from the
five results is picked up for each function and bash version.
- Re: efficient way to use matched string in variable substitution, (continued)
- Re: efficient way to use matched string in variable substitution, Léa Gris, 2021/08/24
- Re: efficient way to use matched string in variable substitution, Greg Wooledge, 2021/08/24
- Re: efficient way to use matched string in variable substitution, Léa Gris, 2021/08/24
- Re: efficient way to use matched string in variable substitution, Mike Jonkmans, 2021/08/24
- Re: efficient way to use matched string in variable substitution, Greg Wooledge, 2021/08/24
- Re: efficient way to use matched string in variable substitution, Mike Jonkmans, 2021/08/24
- Re: efficient way to use matched string in variable substitution, Léa Gris, 2021/08/24
- Re: efficient way to use matched string in variable substitution, Greg Wooledge, 2021/08/24
- Re: efficient way to use matched string in variable substitution, Mike Jonkmans, 2021/08/24
- Re: efficient way to use matched string in variable substitution, L A Walsh, 2021/08/24
- Re: efficient way to use matched string in variable substitution,
Koichi Murase <=
Re: efficient way to use matched string in variable substitution, Oğuz, 2021/08/23