From b75a0667bc6e0c36afc307c70162c31ae20226b1 Mon Sep 17 00:00:00 2001 From: David DIDIER Date: Thu, 2 Feb 2017 22:42:41 +0100 Subject: [PATCH] Add profiling --- lib/profiler.sh | 57 ++++++++++++++++++++++++++++++++++++ oh-my-zsh.sh | 24 +++++++++++++++ templates/zshrc.zsh-template | 3 ++ 3 files changed, 84 insertions(+) create mode 100644 lib/profiler.sh diff --git a/lib/profiler.sh b/lib/profiler.sh new file mode 100644 index 000000000..c7dbda508 --- /dev/null +++ b/lib/profiler.sh @@ -0,0 +1,57 @@ + +# Store the measurements indexed by the key (name) +typeset -A _time_by_keys +# Store the order the measurements were taken +_ordered_keys=() + +# Return a timestamp in milliseconds +function _time_in_ms() { + echo $(( $(date +%s%N) / 1000000 )) +} + +# Start recording the elapsed time +# @param key the name that defines the measurement (must be unique) +function start_profiling() { + [[ $ENABLE_PROFILING = "true" ]] || return + + local key="$1" + local time_ms=$(_time_in_ms) + _time_by_keys[$key]=$time_ms + _ordered_keys+=($key) +} + +# Stop recording the elapsed time +# @param key the name that defines the measurement (must be the same than the one used with 'start_profiling') +function stop_profiling() { + [[ $ENABLE_PROFILING = "true" ]] || return + + local key="$1" + local time_ms=$(_time_in_ms) + + if [[ $_time_by_keys[$key] ]]; then + _time_by_keys[$key]=$(($time_ms - $_time_by_keys[$key])) + else + echo "WARNING: you must start the profiling with 'start_profiling \"$key\"')" + fi +} + +# Print all the measurements +function print_profiling() { + [[ $ENABLE_PROFILING = "true" ]] || return + + local dots1='..................................................' + local dots2='......' + + echo + for key in $_ordered_keys; do + local value=$_time_by_keys[$key] + local percent=$(($_time_by_keys[$key] * 100 / $_time_by_keys[TOTAL])) + + local length1=$(( ${#key} + ${#value} )) + printf "%s %s %s ms " $key "${dots1:$length1}" $value + + local length2=$(( ${#percent} )) + printf "%s %s%%\n" "${dots2:$length2}" $percent + done + echo +} diff --git a/oh-my-zsh.sh b/oh-my-zsh.sh index a7de646f2..3efb9c876 100644 --- a/oh-my-zsh.sh +++ b/oh-my-zsh.sh @@ -1,3 +1,9 @@ + +# Load the micro profiling framework +source "$ZSH/lib/profiler.sh" +# Start profiling +start_profiling "TOTAL" + # Check for updates on initial load... if [ "$DISABLE_AUTO_UPDATE" != "true" ]; then env ZSH=$ZSH DISABLE_UPDATE_PROMPT=$DISABLE_UPDATE_PROMPT zsh -f $ZSH/tools/check_for_upgrade.sh @@ -77,22 +83,34 @@ else compinit -i -d "${ZSH_COMPDUMP}" fi + # Load all of the plugins that were defined in ~/.zshrc +start_profiling " loading plugins" for plugin ($plugins); do + start_profiling " $plugin" if [ -f $ZSH_CUSTOM/plugins/$plugin/$plugin.plugin.zsh ]; then source $ZSH_CUSTOM/plugins/$plugin/$plugin.plugin.zsh elif [ -f $ZSH/plugins/$plugin/$plugin.plugin.zsh ]; then source $ZSH/plugins/$plugin/$plugin.plugin.zsh fi + stop_profiling " $plugin" done +stop_profiling " loading plugins" + # Load all of your custom configurations from custom/ +start_profiling " loading custom configurations" for config_file ($ZSH_CUSTOM/*.zsh(N)); do + start_profiling " $(basename $config_file)" source $config_file + stop_profiling " $(basename $config_file)" done +stop_profiling " loading custom configurations" unset config_file + # Load the theme +start_profiling " loading theme" if [ "$ZSH_THEME" = "random" ]; then themes=($ZSH/themes/*zsh-theme) N=${#themes[@]} @@ -111,3 +129,9 @@ else fi fi fi +stop_profiling " loading theme" + +# Stop profiling +stop_profiling "TOTAL" +# Print the profiling results +print_profiling diff --git a/templates/zshrc.zsh-template b/templates/zshrc.zsh-template index af42e5b9f..c06d25ee3 100644 --- a/templates/zshrc.zsh-template +++ b/templates/zshrc.zsh-template @@ -39,6 +39,9 @@ ZSH_THEME="robbyrussell" # much, much faster. # DISABLE_UNTRACKED_FILES_DIRTY="true" +# Uncomment the following line to enable profiling +# ENABLE_PROFILING="true" + # Uncomment the following line if you want to change the command execution time # stamp shown in the history command output. # The optional three formats: "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd"