What is the overhead of using subshells?

Subshells do have overhead.

On my system, the minimal fork-exec cost (when you run a program from disk when the file ins't cold) is about 2ms and the minimal forking cost is about 1ms.

With subshells, you're talking the forking cost alone, as no file needs to be execed. If the subshells are kept reasonable low, 1ms is quite negligible in human-facing programs. I believe humans can't notice anything that happens faster than 50ms (and that's how long it tends to take for modern scripting language interpreters to even start (I'm talking python and ruby in rvm here) with the newest nodejs taking up around 100ms).

However, it does add up with loops, and then you might want to replace for example the rather common bactick or $() pattern where you return something from a function by printing it to stdout for the parent shell to catpure with bashisms like printf -v (or use a fast external program to process the whole batch).

The bash-completion package specifically avoid this subshell cost by returning via passed variable names using a technique described at http://fvue.nl/wiki/Bash:_Passing_variables_by_reference


Comparing

time for((i=0;i<10000;i++)); do echo "$(echo hello)"; done >/dev/null 

with

time for((i=0;i<10000;i++)); do echo hello; done >/dev/null 

should give you a good estimate of what your systems fork-ing overhead is.