Return values ​​from functions at efficiency

It seems to me that there are several ways to return a value from a Bash function.

Approach 1 . Use the local-global variable, which is defined as local in the caller:

 func1() { a=10 } parent1() { local a func1 a=$(($a + 1)) } 

Approach 2 : use command substitution:

 func2() { echo 10 } parent2() { a=$(func2) a=$(($a + 1)) } 

How many accelerations could be expected from using approach 1 over convergence 2?

And I know that using a good global variable, as in approach 1, is not good practice, but can it be justified at some point for efficiency reasons?

+6
source share
2 answers

The single most expensive operation in shell scripts is forking. Any operation associated with the plug, such as command substitution, will be 1-3 orders of magnitude slower than one that does not.

For example, here we propose a direct approach for a loop that reads a bunch of generated files in the form file-1234 and cuts out the file- prefix with sed , requiring a total of three forks (command substitution + two-stage pipeline):

 $ time printf "file-%s\n" {1..10000} | while read line; do n=$(echo "$line" | sed -e "s/.*-//"); done real 0m46.847s 

Here's a loop that does the same with parameter expansion without requiring forks:

 $ time printf "file-%s\n" {1..10000} | while read line; do n=${line#*-}; done real 0m0.150s 

A forked version takes 300 times.

So the answer to your question is yes: if efficiency matters, you have a solid justification for factoring or replacing forky code.

When the fork metric is constant relative to the input (or it's too dirty to make it constant) and the code is still too slow, this is when you have to rewrite it to a faster language.

+4
source

Of course, approach 1 is much faster than approach 2, because it does not have an interrupt (which, in turn, may need several OS kernel switches for the service) and has only one memory access !!!

+1
source

Source: https://habr.com/ru/post/985410/


All Articles