Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

colors.theme.bash: pre-compute colors, startup 3x faster #699

Merged
merged 1 commit into from
Apr 10, 2016

Conversation

bmalehorn
Copy link
Contributor

bash-it takes rather a while to startup, around 0.5 seconds on my
laptop. After a bit of timing it appears the majority of the time is
spent in themes/colors.theme.bash. The reason for that is the fancy
abstraction layers that use $(). For example, consider this code:

red="$(color reset red)"

It will go through 9 forkexecs to evaluate:

red="$(color reset red)"
    "$(__color_parse make_ansi reset red)"
    "$(__make_ansi reset red)"
    "\[\e[$(__reset red)m\]"
    "\[\e[0;$(__red)m\]"
    "\[\e[0;$(__color red)m\]"
    "\[\e[0;$(__color_normal_fg $(__color_red))m\]"
    "\[\e[0;$(__color_normal_fg 1)m\]"
    "\[\e[0;31m\]"

With all the variables in colors.theme.bash, this adds up to hundreds of
forks:

$ strace -f bash ./colors.theme.bash 2>&1 | grep clone | wc -l
649

The solution is to replace the function with its result:

-red="$(color reset red)"
+red='\[\e[0;31m\]'

This is safe, since colors.theme.bash never calls external functions or
takes any input. So, its result can be safely hard-coded.

This improves startup time dramatically. Try adding "time" to your .bashrc:

# Load Bash It
time source $BASH_IT/bash_it.sh

before:

real    0m0.462s
user    0m0.100s
sys     0m0.399s

after:

real    0m0.150s
user    0m0.091s
sys     0m0.064s

bash-it takes rather a while to startup, around 0.5 seconds on my
laptop. After a bit of timing it appears the majority of the time is
spent in themes/colors.theme.bash. The reason for that is the fancy
abstraction layers that use $(). For example, consider this code:

    red="$(color reset red)"

It will go through 9 forkexecs to evaluate:

    red="$(color reset red)"
        "$(__color_parse make_ansi reset red)"
        "$(__make_ansi reset red)"
        "\[\e[$(__reset red)m\]"
        "\[\e[0;$(__red)m\]"
        "\[\e[0;$(__color red)m\]"
        "\[\e[0;$(__color_normal_fg $(__color_red))m\]"
        "\[\e[0;$(__color_normal_fg 1)m\]"
        "\[\e[0;31m\]"

With all the variables in colors.theme.bash, this adds up to hundreds of
forks:

    $ strace -f bash ./colors.theme.bash 2>&1 | grep clone | wc -l
    649

The solution is to replace the function with its result:

    -red="$(color reset red)"
    +red='\[\e[0;31m\]'

This is safe, since colors.theme.bash never calls external functions or
takes any input. So, its result can be safely hard-coded.

This improves startup time dramatically. Try adding "time" to your .bashrc:

    # Load Bash It
    time source $BASH_IT/bash_it.sh

before:

    real    0m0.462s
    user    0m0.100s
    sys     0m0.399s

after:

    real    0m0.150s
    user    0m0.091s
    sys     0m0.064s
@nwinkler nwinkler merged commit da229ea into Bash-it:master Apr 10, 2016
@nwinkler
Copy link
Member

This is great - thanks!

Depending on the number of plugins that the user has enabled, the startup will still take a long time, but this is a great step to shave off a couple of seconds.

@bmalehorn
Copy link
Contributor Author

No problem, I like making things faster.

FWIW, most of the remaining time is split between completions and plugins:

overall:
    forks: 89
    real    0m0.164s
    user    0m0.095s
    sys     0m0.072s

completion:
    forks: 7
    real    0m0.043s
    user    0m0.030s
    sys     0m0.013s

plugins:
    forks: 76
    real    0m0.104s
    user    0m0.053s
    sys     0m0.053s

alias-completion.plugin.bash:57 is the culprit for me, causing a fork() per alias, and I have about 76 aliases.

The real problem is that bash makes it difficult to get the output of bash builtins / functions without using $(). So even though completion -p may only take a few microseconds to run, we have to make it 1000x slower by forking a separate process.

@edubxb
Copy link
Member

edubxb commented Apr 11, 2016

Great! Thanks for this big improvement!

@nwinkler
Copy link
Member

If you have a suggestion for improving the alias completion plugin, feel free to provide a PR for it! I simply copied the code from a StackOverflow answer, and it worked fine. I must confess that I didn't look into timing or anything like that. The functionality that it provides easily makes up for the time it consumes during opening a new shell - at least for me...

gaelicWizard added a commit to gaelicWizard/bash-it that referenced this pull request Jan 5, 2022
This reverts Bash-it#99, a metaprogramming adventure in terminal color code escape computation. It was functionally reverted in Bash-it#699; I'm just finishing the job.
gaelicWizard added a commit to gaelicWizard/bash-it that referenced this pull request Jan 5, 2022
This reverts commit 2a3fde2 but does *not* restore the previous variables. Those are still provided by `lib/colors`.

This plugin exists for anyone who likes the metaprogramming adventure of computing colors dynamically rather than using hard-coded value. Potentially this could be used by themes, or possibly by a theme color-scheme randomizer?
gaelicWizard added a commit to gaelicWizard/bash-it that referenced this pull request Jan 5, 2022
This reverts Bash-it#99, a metaprogramming adventure in terminal color code escape computation. It was functionally reverted in Bash-it#699; I'm just finishing the job.
gaelicWizard added a commit to gaelicWizard/bash-it that referenced this pull request Jan 8, 2022
This reverts Bash-it#99, a metaprogramming adventure in terminal color code escape computation. It was functionally reverted in Bash-it#699; I'm just finishing the job.
gaelicWizard added a commit to gaelicWizard/bash-it that referenced this pull request Jan 8, 2022
This reverts commit 2a3fde2 but does *not* restore the previous variables. Those are still provided by `lib/colors`.

This plugin exists for anyone who likes the metaprogramming adventure of computing colors dynamically rather than using hard-coded value. Potentially this could be used by themes, or possibly by a theme color-scheme randomizer?
gaelicWizard added a commit to gaelicWizard/bash-it that referenced this pull request Jan 9, 2022
This reverts Bash-it#99, a metaprogramming adventure in terminal color code escape computation. It was functionally reverted in Bash-it#699; I'm just finishing the job.
gaelicWizard added a commit to gaelicWizard/bash-it that referenced this pull request Jan 9, 2022
This reverts commit 2a3fde2 but does *not* restore the previous variables. Those are still provided by `lib/colors`.

This plugin exists for anyone who likes the metaprogramming adventure of computing colors dynamically rather than using hard-coded value. Potentially this could be used by themes, or possibly by a theme color-scheme randomizer?
gaelicWizard added a commit to gaelicWizard/bash-it that referenced this pull request Jan 9, 2022
This reverts Bash-it#99, a metaprogramming adventure in terminal color code escape computation. It was functionally reverted in Bash-it#699; I'm just finishing the job.
gaelicWizard added a commit to gaelicWizard/bash-it that referenced this pull request Jan 9, 2022
This reverts Bash-it#99, a metaprogramming adventure in terminal color code escape computation. It was functionally reverted in Bash-it#699; I'm just finishing the job.
gaelicWizard added a commit to gaelicWizard/bash-it that referenced this pull request Jan 9, 2022
This reverts Bash-it#99, a metaprogramming adventure in terminal color code escape computation. It was functionally reverted in Bash-it#699; I'm just finishing the job.
gaelicWizard added a commit to gaelicWizard/bash-it that referenced this pull request Jan 9, 2022
This reverts Bash-it#99, a metaprogramming adventure in terminal color code escape computation. It was functionally reverted in Bash-it#699; I'm just finishing the job.
gaelicWizard added a commit to gaelicWizard/bash-it that referenced this pull request Jan 25, 2022
This reverts commit 2a3fde2 but does *not* restore the previous variables. Those are still provided by `lib/colors`.

This plugin exists for anyone who likes the metaprogramming adventure of computing colors dynamically rather than using hard-coded value. Potentially this could be used by themes, or possibly by a theme color-scheme randomizer?
gaelicWizard added a commit to gaelicWizard/bash-it that referenced this pull request Jan 25, 2022
This reverts Bash-it#99, a metaprogramming adventure in terminal color code escape computation. It was functionally reverted in Bash-it#699; I'm just finishing the job.
gaelicWizard added a commit to gaelicWizard/bash-it that referenced this pull request Jan 25, 2022
This reverts Bash-it#99, a metaprogramming adventure in terminal color code escape computation. It was functionally reverted in Bash-it#699; I'm just finishing the job.
gaelicWizard added a commit to gaelicWizard/bash-it that referenced this pull request Jan 26, 2022
This reverts commit 2a3fde2 but does *not* restore the previous variables. Those are still provided by `lib/colors`.

This plugin exists for anyone who likes the metaprogramming adventure of computing colors dynamically rather than using hard-coded value. Potentially this could be used by themes, or possibly by a theme color-scheme randomizer?
gaelicWizard added a commit to gaelicWizard/bash-it that referenced this pull request Jan 26, 2022
This reverts Bash-it#99, a metaprogramming adventure in terminal color code escape computation. It was functionally reverted in Bash-it#699; I'm just finishing the job.
gaelicWizard added a commit to gaelicWizard/bash-it that referenced this pull request Jan 28, 2022
This reverts Bash-it#99, a metaprogramming adventure in terminal color code escape computation. It was functionally reverted in Bash-it#699; I'm just finishing the job.
gaelicWizard added a commit to gaelicWizard/bash-it that referenced this pull request Jan 28, 2022
This reverts commit 2a3fde2 but does *not* restore the previous variables. Those are still provided by `lib/colors`.

This plugin exists for anyone who likes the metaprogramming adventure of computing colors dynamically rather than using hard-coded value. Potentially this could be used by themes, or possibly by a theme color-scheme randomizer?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants