[Bash-completion-devel] speed up bash completion init by > 30%...

Linda A. Walsh bash at tlinx.org
Thu Oct 9 03:09:53 UTC 2014


Currently this function is used all over the place:

#have() { unset -v have
#    # Completions for system administrator commands are installed as 
well in
#    # case completion is attempted via `sudo command ...'.
#    PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin type $1 &>/dev/null &&
#    have="yes"
----
Save the PATH off once and set the path to designed.

Likely want to ensure common dirs are up front and user path later
as common dirs are the ones that have the commands being completed..
I.e
savepath=$PATH
PATH=/usr/bin:/bin:/usr/local/bin:/usr/sbin:/sbin:/usr/local/sbin:$PATH

Then get rid of the have function and use:

shopt -s expand aliases
alias have=' >&/dev/null type -P'

Running the main script and "big script" (I 'catted' all the
script in /etc/completion.d  into 1 big script for speed')...

individual scripts went into 'archive', then cat all of them into 1 script.

Might be more compat to keep single scripts in /etc/bash.completion.d, and
put a concatonated version in a subdir... (I don't know if that saves much
time, I didn't time that part)....wait.....
oh poop... well with all the files already read in (in cache),
it saved <4%... ok, scratch that...

But the alias replacing the function saves 30%... (32.15%) ..
That's free gravy!

----
BTW while my timing script introduces considerable overhead, it is useful
for ***comparison***..

Works on linux and cygwin and can be toggled by including
the code at the beginning of where you want to measure:

declare -i __cmd_timing=1
((__cmd_timing)) &&
. /etc/local/cmd_step_timing.shh

When not in use, can set it to 0 or delete the lines
...

output displays throughout execution via "set -x":
looks like:
> >[    0.01]/etc/profile#35> 
PATH=/usr/local/bin:/usr/bin:/bin:/usr/ucb:/bin:/usr/bin:
> >[    0.03]/etc/profile#36> export PATH
> >[    0.05]/etc/profile#38> MANPATH=/usr/local/man:/usr/share/man:/usr/man:
> >[    0.07]/etc/profile#39> export MANPATH
> >[    0.09]/etc/profile#41> 
INFOPATH=/usr/local/info:/usr/share/info:/usr/info:
> >[    0.11]/etc/profile#42> export INFOPATH
> >>[    0.14]/etc/profile#45> id -un
> >>>[  47.661]/etc/local/bash_env.sh#8> (( 1 ))
> >>>[  47.693]/etc/local/bash_env.sh#9> shopt -s extglob
> >>>[  47.723]/etc/local/bash_env.sh#10> f=x
> >>>[  47.755]/etc/local/bash_env.sh#10> [[ -n x ]]
> >>>[  47.787]/etc/local/bash_env.sh#10> set +x
> >>>[  47.818]/etc/local/bash_env.sh#15> : /Users/law.Bliss/.bash_env
> >>>[  47.849]/etc/local/bash_env.sh#16> export BASH_ENV
> >>>>[  47.891]/etc/local/bash_env.sh#17> type -t include
> >>>[  47.923]/etc/local/bash_env.sh#17> [[ function == function ]]
> >>[  47.954]/Users/law.Bliss/.bash_env#22> export _LOCAL_BASH_ENV_CALLED=1
> >>[  47.986]/Users/law.Bliss/.bash_env#22> _LOCAL_BASH_ENV_CALLED=1

(the function version ended in 71.5s)... thus the measured savings of 32%.


The included script is fairly short:

/etc/local> cat cmd_step_timing.shh
#!/bin/bash
shopt -s extglob
declare -i _t_basetime=0 _t_ifac=0
declare _t_digs=""
if ((!_t_ifac)) ; then
  if [[ -e /proc/schedstat ]] ; then
    _t_ifac=1000; _t_digs="3"
    function _rdtime { declare _t_wd; declare -i _t_tm;
      { read; read _t_wd _t_tm ; } </proc/schedstat ; echo "$_t_tm" ; }
  else
    _t_ifac=100; _t_digs="2"
    if [[ -e /proc/uptime ]]; then
      function _rdtime { declare _t_a _t_b; read _t_a _t_b </proc/uptime;
        echo "${_t_a/./}" ; }
    fi
  fi
  ((!_t_basetime)) && _t_basetime=0+$(_rdtime)
  function _delta { echo "$[0 + $(_rdtime) - $_t_basetime ]" ; }
fi

function __age {
  declare -i dt=0+$(_delta)
  declare -i ms=$[$dt%$_t_ifac]
  dt=$[$dt/$_t_ifac]
  printf "%5d.%0*d\n" "$dt" "$_t_digs" "$ms"
}

export 
PS4='>>[$(__age)]${BASH_SOURCE:+${BASH_SOURCE[0]}}#${LINENO}${FUNCNAME:+(${FUNCNAME[0]})}> 
'
set -x

==============

comments?  fix the 'have' thing?













More information about the Bash-completion-devel mailing list