Re: Q: what is a fast way to see if an 'item' is present in an array?
Linda Walsh schreef op 16-02-16 om 04:59: > w/the slow func being killed by a $() sub process, likely: Yes, subshells are fatal for performance, particularly on bash. > my fn2='() {my t="${2:?}[*]" >my arRE="^($(IFS="|"; echo "${!t}"))$" >[[ $1 =~ $arRE ]] > } > ' (What's "my"? An alias for "local"?) Try this: appears_in() { local IFS="|" val="$1" shift [[ "$IFS$*$IFS" == *"$IFS$val$IFS"* ]] } if appears_in "somevalue" "${array[@]}"; then do stuff; fi For anyone reading who may not know, the trick is that "$*" expands to a single string containing all the positional parameters separated by the first character of $IFS (or with no separator if IFS is empty, but that's not useful here). Of course this function is dependent on none of the elements containing "|". But this lets you set any separator you want, so you could use a really unlikely character such as IFS=$'\1'. - M.
Re: Q: what is a fast way to see if an 'item' is present in an array?
On Monday, February 15, 2016 at 7:59:35 PM UTC-8, Linda Walsh wrote: > I has a little 4 line func that returns true or false > if a string was in an array Arrays aren't really a great datastructure for testing presence and absence in. An associative array / dictionary / hash is better. Consider: http://stromberg.dnsalias.org/~strombrg/database/
Re: Q: what is a fast way to see if an 'item' is present in an array?
Greg Wooledge wrote: On Mon, Feb 15, 2016 at 07:59:21PM -0800, Linda Walsh wrote: Obviously, If I could precook the array into a hash, I'd think it would be faster... but the "cooking part", I think, is the high overhead part. Redesign the entire script so that you use the associative array (hash) from the beginning instead of, or in addition to, storing your information in a "list" (indexed array). It would also take throwing away previous cfg-file compat as well as changing the linux kernel interface. Somehow I don't think that is going to be easier: (cd /sys/class/net/br0/brif/; echo *) eth0 eth5 grep ^BRIDGE_PORTS "$CFG" BRIDGE_PORTS='eth0 eth5' --- In my case it's only 2, but other interfaces... still not that long *usually*, (cd $PWD/holders; echo *) dm-0 dm-1 dm-12 dm-2 dm-3 dm-4 dm-5 dm-6 dm-7 dm-8 dm-9 But I tend to think about worst case behaviors and at least try to ask around if anyone has anything better... but in this case, the impact is minimal. Though when designing 'anew', I try to make things data/table driven as much as possible for things that fit into that paradigm. Thanks! L.
Re: Q: what is a fast way to see if an 'item' is present in an array?
On Mon, Feb 15, 2016 at 07:59:21PM -0800, Linda Walsh wrote: > Obviously, If I could precook the array into > a hash, I'd think it would be faster... but > the "cooking part", I think, is the high > overhead part. Redesign the entire script so that you use the associative array (hash) from the beginning instead of, or in addition to, storing your information in a "list" (indexed array).
Q: what is a fast way to see if an 'item' is present in an array?
I has a little 4 line func that returns true or false if a string was in an array I came up with a different way of doing it, that I though might be faster... but... putting them in a file and running loops on them. (times below). Obviously, my feeling for what might be faster was way wrong. w/my 2nd method being 15-44X slower depending on where the match is. Obviously, If I could precook the array into a hash, I'd think it would be faster... but the "cooking part", I think, is the high overhead part. The fast function was: my fn1='() { my __ my t="${2:?}[@]" for __ in "${!t}"; do [[ $1 == "$__" ]] && return 0;done return 1; } ' w/the slow func being killed by a $() sub process, likely: my fn2='() { my t="${2:?}[*]" my arRE="^($(IFS="|"; echo "${!t}"))$" [[ $1 =~ $arRE ]] } ' Was wondering if anyone else had fast functions like this to determine if a string is in a list? I can attach the test script (doubles as an "include" or "source" file), if people want to test their own... The frameworks should be simple to copy in other test functions...(or replace #2...)... This was in bash-4.3.42. ---data results--- (-t [#loops] string WORDLIST): so false case 1st: _in.shh -t 300 word {0..999} func(fn1): 1.49sec 1.48usr 0.00sys (100.02% cpu) false func(fn2): 22.78sec 18.38usr 4.32sys (99.69% cpu) false then true w/match @ end of the list _in.shh -t 300 word {0..999} word func(fn1): 1.49sec 1.49usr 0.00sys (100.03% cpu) true func(fn2): 22.85sec 18.46usr 4.31sys (99.67% cpu) true then true w/match @ beginning of list... _in.shh -t 300 word word {0..999} func(fn1): 0.51sec 0.51usr 0.00sys (100.01% cpu) true func(fn2): 22.75sec 18.40usr 4.28sys (99.70% cpu) true