What is the overhead of using subshells?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
4
down vote

favorite
2












Hopefully this question is not too generic. I am very new to shell scripting and I come from a computer architecture/non-scripting programming background. I have noticed on the scripts at my work that rarely the scripts are written by making a sub-shell around the entire script. In the scripts I am writing, when I can envelop it with a sub-shell I am since it keeps it from messing with other scripts that call mine (Just in case). Is this not a common-practice because of some overhead associated with this approach? I am having a hard time finding this online.



Example:



#!/bin/bash
( #Start of subshell
echo "Some stuff here"
) #End of subshell









share|improve this question



















  • 1




    How are those other scripts calling your script? E.g. are they using a source, or are they instead executing your script?
    – thrig
    May 19 '16 at 21:32






  • 1




    Coming from a programming background, there is a post on this site that should be mandatory introductory reading to shell scripting — it covers the conceptual differences between bash and e.g. C. The true answer to this "overhead" question is really a no-answer: If you're worried about performance overhead, you shouldn't be using a shell script.
    – Wildcard
    May 19 '16 at 21:36










  • Could you please clarify what you mean by "a subshell around the entire script"? somefunction() ( ... ) (notice the parens instead of curlies) to specify that somefunction should always create a subshell is not uncommon, however I don't think there's any need to enclose actual scripts in parentheses.
    – PSkocik
    May 19 '16 at 21:36










  • @thrig That's a good point. ( source somescript ) tends to win some milliseconds over bash somescript and there it makes to achieve the same level of isolation as bash somescript offers.
    – PSkocik
    May 19 '16 at 21:40






  • 1




    @PSkocik Added an example
    – LinuxLearner
    May 19 '16 at 23:00














up vote
4
down vote

favorite
2












Hopefully this question is not too generic. I am very new to shell scripting and I come from a computer architecture/non-scripting programming background. I have noticed on the scripts at my work that rarely the scripts are written by making a sub-shell around the entire script. In the scripts I am writing, when I can envelop it with a sub-shell I am since it keeps it from messing with other scripts that call mine (Just in case). Is this not a common-practice because of some overhead associated with this approach? I am having a hard time finding this online.



Example:



#!/bin/bash
( #Start of subshell
echo "Some stuff here"
) #End of subshell









share|improve this question



















  • 1




    How are those other scripts calling your script? E.g. are they using a source, or are they instead executing your script?
    – thrig
    May 19 '16 at 21:32






  • 1




    Coming from a programming background, there is a post on this site that should be mandatory introductory reading to shell scripting — it covers the conceptual differences between bash and e.g. C. The true answer to this "overhead" question is really a no-answer: If you're worried about performance overhead, you shouldn't be using a shell script.
    – Wildcard
    May 19 '16 at 21:36










  • Could you please clarify what you mean by "a subshell around the entire script"? somefunction() ( ... ) (notice the parens instead of curlies) to specify that somefunction should always create a subshell is not uncommon, however I don't think there's any need to enclose actual scripts in parentheses.
    – PSkocik
    May 19 '16 at 21:36










  • @thrig That's a good point. ( source somescript ) tends to win some milliseconds over bash somescript and there it makes to achieve the same level of isolation as bash somescript offers.
    – PSkocik
    May 19 '16 at 21:40






  • 1




    @PSkocik Added an example
    – LinuxLearner
    May 19 '16 at 23:00












up vote
4
down vote

favorite
2









up vote
4
down vote

favorite
2






2





Hopefully this question is not too generic. I am very new to shell scripting and I come from a computer architecture/non-scripting programming background. I have noticed on the scripts at my work that rarely the scripts are written by making a sub-shell around the entire script. In the scripts I am writing, when I can envelop it with a sub-shell I am since it keeps it from messing with other scripts that call mine (Just in case). Is this not a common-practice because of some overhead associated with this approach? I am having a hard time finding this online.



Example:



#!/bin/bash
( #Start of subshell
echo "Some stuff here"
) #End of subshell









share|improve this question















Hopefully this question is not too generic. I am very new to shell scripting and I come from a computer architecture/non-scripting programming background. I have noticed on the scripts at my work that rarely the scripts are written by making a sub-shell around the entire script. In the scripts I am writing, when I can envelop it with a sub-shell I am since it keeps it from messing with other scripts that call mine (Just in case). Is this not a common-practice because of some overhead associated with this approach? I am having a hard time finding this online.



Example:



#!/bin/bash
( #Start of subshell
echo "Some stuff here"
) #End of subshell






linux bash fedora performance subshell






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited May 19 '16 at 22:59

























asked May 19 '16 at 21:13









LinuxLearner

13410




13410







  • 1




    How are those other scripts calling your script? E.g. are they using a source, or are they instead executing your script?
    – thrig
    May 19 '16 at 21:32






  • 1




    Coming from a programming background, there is a post on this site that should be mandatory introductory reading to shell scripting — it covers the conceptual differences between bash and e.g. C. The true answer to this "overhead" question is really a no-answer: If you're worried about performance overhead, you shouldn't be using a shell script.
    – Wildcard
    May 19 '16 at 21:36










  • Could you please clarify what you mean by "a subshell around the entire script"? somefunction() ( ... ) (notice the parens instead of curlies) to specify that somefunction should always create a subshell is not uncommon, however I don't think there's any need to enclose actual scripts in parentheses.
    – PSkocik
    May 19 '16 at 21:36










  • @thrig That's a good point. ( source somescript ) tends to win some milliseconds over bash somescript and there it makes to achieve the same level of isolation as bash somescript offers.
    – PSkocik
    May 19 '16 at 21:40






  • 1




    @PSkocik Added an example
    – LinuxLearner
    May 19 '16 at 23:00












  • 1




    How are those other scripts calling your script? E.g. are they using a source, or are they instead executing your script?
    – thrig
    May 19 '16 at 21:32






  • 1




    Coming from a programming background, there is a post on this site that should be mandatory introductory reading to shell scripting — it covers the conceptual differences between bash and e.g. C. The true answer to this "overhead" question is really a no-answer: If you're worried about performance overhead, you shouldn't be using a shell script.
    – Wildcard
    May 19 '16 at 21:36










  • Could you please clarify what you mean by "a subshell around the entire script"? somefunction() ( ... ) (notice the parens instead of curlies) to specify that somefunction should always create a subshell is not uncommon, however I don't think there's any need to enclose actual scripts in parentheses.
    – PSkocik
    May 19 '16 at 21:36










  • @thrig That's a good point. ( source somescript ) tends to win some milliseconds over bash somescript and there it makes to achieve the same level of isolation as bash somescript offers.
    – PSkocik
    May 19 '16 at 21:40






  • 1




    @PSkocik Added an example
    – LinuxLearner
    May 19 '16 at 23:00







1




1




How are those other scripts calling your script? E.g. are they using a source, or are they instead executing your script?
– thrig
May 19 '16 at 21:32




How are those other scripts calling your script? E.g. are they using a source, or are they instead executing your script?
– thrig
May 19 '16 at 21:32




1




1




Coming from a programming background, there is a post on this site that should be mandatory introductory reading to shell scripting — it covers the conceptual differences between bash and e.g. C. The true answer to this "overhead" question is really a no-answer: If you're worried about performance overhead, you shouldn't be using a shell script.
– Wildcard
May 19 '16 at 21:36




Coming from a programming background, there is a post on this site that should be mandatory introductory reading to shell scripting — it covers the conceptual differences between bash and e.g. C. The true answer to this "overhead" question is really a no-answer: If you're worried about performance overhead, you shouldn't be using a shell script.
– Wildcard
May 19 '16 at 21:36












Could you please clarify what you mean by "a subshell around the entire script"? somefunction() ( ... ) (notice the parens instead of curlies) to specify that somefunction should always create a subshell is not uncommon, however I don't think there's any need to enclose actual scripts in parentheses.
– PSkocik
May 19 '16 at 21:36




Could you please clarify what you mean by "a subshell around the entire script"? somefunction() ( ... ) (notice the parens instead of curlies) to specify that somefunction should always create a subshell is not uncommon, however I don't think there's any need to enclose actual scripts in parentheses.
– PSkocik
May 19 '16 at 21:36












@thrig That's a good point. ( source somescript ) tends to win some milliseconds over bash somescript and there it makes to achieve the same level of isolation as bash somescript offers.
– PSkocik
May 19 '16 at 21:40




@thrig That's a good point. ( source somescript ) tends to win some milliseconds over bash somescript and there it makes to achieve the same level of isolation as bash somescript offers.
– PSkocik
May 19 '16 at 21:40




1




1




@PSkocik Added an example
– LinuxLearner
May 19 '16 at 23:00




@PSkocik Added an example
– LinuxLearner
May 19 '16 at 23:00










2 Answers
2






active

oldest

votes

















up vote
2
down vote



accepted










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.






share|improve this answer


















  • 1




    Thank you. This is actually really useful. I am writing scripts on old laptops. If I am writing a script that is called multiple times I'll avoid using subshells. Even if it is negligible I'm trying to develop good coding practices from start.
    – LinuxLearner
    May 19 '16 at 23:12

















up vote
0
down vote













(This would have been comment, but I am behind firewall at work.)



Running the excellent code provided by PSkocik on my system showed negligible results.



However, this example really hits home - native commands vs subshell commands:
MyPath="path/name.ext"



this takes forever



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



this is over 100x less time



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





share








New contributor




Spioter is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

















    Your Answer







    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "106"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f284268%2fwhat-is-the-overhead-of-using-subshells%23new-answer', 'question_page');

    );

    Post as a guest






























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    2
    down vote



    accepted










    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.






    share|improve this answer


















    • 1




      Thank you. This is actually really useful. I am writing scripts on old laptops. If I am writing a script that is called multiple times I'll avoid using subshells. Even if it is negligible I'm trying to develop good coding practices from start.
      – LinuxLearner
      May 19 '16 at 23:12














    up vote
    2
    down vote



    accepted










    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.






    share|improve this answer


















    • 1




      Thank you. This is actually really useful. I am writing scripts on old laptops. If I am writing a script that is called multiple times I'll avoid using subshells. Even if it is negligible I'm trying to develop good coding practices from start.
      – LinuxLearner
      May 19 '16 at 23:12












    up vote
    2
    down vote



    accepted







    up vote
    2
    down vote



    accepted






    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.






    share|improve this answer














    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.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited May 20 '16 at 12:22

























    answered May 19 '16 at 21:31









    PSkocik

    17.4k34893




    17.4k34893







    • 1




      Thank you. This is actually really useful. I am writing scripts on old laptops. If I am writing a script that is called multiple times I'll avoid using subshells. Even if it is negligible I'm trying to develop good coding practices from start.
      – LinuxLearner
      May 19 '16 at 23:12












    • 1




      Thank you. This is actually really useful. I am writing scripts on old laptops. If I am writing a script that is called multiple times I'll avoid using subshells. Even if it is negligible I'm trying to develop good coding practices from start.
      – LinuxLearner
      May 19 '16 at 23:12







    1




    1




    Thank you. This is actually really useful. I am writing scripts on old laptops. If I am writing a script that is called multiple times I'll avoid using subshells. Even if it is negligible I'm trying to develop good coding practices from start.
    – LinuxLearner
    May 19 '16 at 23:12




    Thank you. This is actually really useful. I am writing scripts on old laptops. If I am writing a script that is called multiple times I'll avoid using subshells. Even if it is negligible I'm trying to develop good coding practices from start.
    – LinuxLearner
    May 19 '16 at 23:12












    up vote
    0
    down vote













    (This would have been comment, but I am behind firewall at work.)



    Running the excellent code provided by PSkocik on my system showed negligible results.



    However, this example really hits home - native commands vs subshell commands:
    MyPath="path/name.ext"



    this takes forever



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



    this is over 100x less time



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





    share








    New contributor




    Spioter is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.





















      up vote
      0
      down vote













      (This would have been comment, but I am behind firewall at work.)



      Running the excellent code provided by PSkocik on my system showed negligible results.



      However, this example really hits home - native commands vs subshell commands:
      MyPath="path/name.ext"



      this takes forever



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



      this is over 100x less time



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





      share








      New contributor




      Spioter is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.



















        up vote
        0
        down vote










        up vote
        0
        down vote









        (This would have been comment, but I am behind firewall at work.)



        Running the excellent code provided by PSkocik on my system showed negligible results.



        However, this example really hits home - native commands vs subshell commands:
        MyPath="path/name.ext"



        this takes forever



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



        this is over 100x less time



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





        share








        New contributor




        Spioter is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.









        (This would have been comment, but I am behind firewall at work.)



        Running the excellent code provided by PSkocik on my system showed negligible results.



        However, this example really hits home - native commands vs subshell commands:
        MyPath="path/name.ext"



        this takes forever



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



        this is over 100x less time



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






        share








        New contributor




        Spioter is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.








        share


        share






        New contributor




        Spioter is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.









        answered 57 secs ago









        Spioter

        1




        1




        New contributor




        Spioter is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.





        New contributor





        Spioter is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.






        Spioter is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.



























             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f284268%2fwhat-is-the-overhead-of-using-subshells%23new-answer', 'question_page');

            );

            Post as a guest