【发布时间】:2019-07-23 12:28:16
【问题描述】:
PROMPT_COMAND 运行缓慢。需要代码优化。
我使用 bash 内置 PROMPT_COMMAND 来自定义 PS1。执行了太多echo | grep 命令以获得彩色 git 分支指示。提示运行速度要慢得多。关于优化的任何想法?
function git_branch {
branch="`git branch 2>/dev/null | grep "^\*" | sed -e "s/^\*\ //"`"
if [ "${branch}" != "" ];then
if [ "${branch}" = "(no branch)" ];then
branch="(`git rev-parse --short HEAD`...)"
fi
echo "$branch"
fi
}
# display last two dentry
function get_curdir {
dir=$(pwd);
last_dirent=${dir##*/}
dir=${dir%/*}
lastbutone_dirent=${dir##*/}
echo -n "${lastbutone_dirent}/${last_dirent}"
}
# colours
RED="\[\033[1;31m\]"
GREEN="\[\033[1;32m\]"
BROWN="\[\033[0;33m\]"
BLUE="\[\033[1;34m\]"
PURPLE="\[\033[1;35m\]"
CYAN="\[\033[1;36m\]"
GRAY="\[\033[0;37m\]"
LIGHT_RED="\[\033[0;31m\]"
LIGHT_GREEN="\[\033[1;32m\]"
LIGHT_BLUE="\[\033[0;34m\]"
YELLOW="\[\033[1;33m\]"
LIGHT_PURPLE="\[\033[1;35m\]"
LIGHT_CYAN="\[\033[1;36m\]"
LIGHT_GRAY="\[\033[0;37m\]"
WHITE="\[\033[1;37m\]"
RESTORE="\[\033[0m\]" #0m restores to the terminal's default colour
function prompt_command {
RET=$?
PS1="${CYAN}[${RESTORE}${GREEN}\u${RESTORE} "
PS1+="${BLUE}$(get_curdir)${RESTORE}${CYAN}]${RESTORE}"
BRANCH=$(git_branch)
if [ "${BRANCH}" != "" ]; then
STATUS="$(git status -s 2>/dev/null)"
if echo "${STATUS}" | grep -e "??"; then
PARENTHESES_COLOR=${RED}
else
PARENTHESES_COLOR=${GREEN}
fi >/dev/null
if [ "${STATUS}" = "" ]; then
BRANCH_COLOR=${GREEN}
else
if echo "${STATUS}" | grep -e "^[ M]M"; then
if echo "${STATUS}" | grep -e "^M[ M]"; then
BRANCH_COLOR=${PURPLE}
else
BRANCH_COLOR=${RED}
fi
elif echo "${STATUS}" | grep -e "^M "; then
BRANCH_COLOR=${YELLOW}
fi
fi >/dev/null
PS1+="${PARENTHESES_COLOR}(${RESTORE}${BRANCH_COLOR}$(git_branch)${RESTORE}${PARENTHESES_COLOR})${RESTORE}"
fi
if [ "$RET" = "0" ]; then
PS1+=" ${CYAN}->${RESTORE} "
else
PS1+=" ${RED}->${RESTORE} "
fi
}
export PROMPT_COMMAND=prompt_command
更新
我在 git repo 所在的某个目录中运行了一个简单的测试,并使用 time 来获取时间成本。
for ((i=0;i<10000;i++));do
prompt_command;
done
上面原版的性能是:
real 3m4.567s
user 1m32.698s
sys 3m2.495s
然后我将 [] 改为 [[ ]],diff 如下:
17,18c17,18
< if [ "${branch}" != "" ];then
< if [ "${branch}" = "(no branch)" ];then
---
> if [[ "${branch}" != "" ]];then
> if [[ "${branch}" == "(no branch)" ]];then
58c58
< if [ "${BRANCH}" != "" ]; then
---
> if [[ "${BRANCH}" != "" ]]; then
65c65
< if [ "${STATUS}" = "" ]; then
---
> if [[ "${STATUS}" == "" ]]; then
81c81
< if [ "$RET" = "0" ]; then
---
> if [[ "$RET" == "0" ]]; then
性能变差了一点
real 3m7.690s
user 1m30.717s
sys 3m6.676s
所以,[] 没关系。
但是内置的正则表达式有很大帮助。
当我更改为以下内容并将 $(pwd) 替换为 $PWD
if [ "${BRANCH}" != "" ]; then
regex_untracked=".*^\?\?.*"
regex_staged=".*^M[ M].*"
regex_modified=".*^[ M]M.*"
STATUS="$(git status -s 2>/dev/null)"
if [[ ${STATUS} =~ $regex_untracked ]]; then
PARENTHESES_COLOR=${RED}
else
PARENTHESES_COLOR=${GREEN}
fi >/dev/null
if [[ ${STATUS} =~ $regex_modified ]]; then
if [[ ${STATUS} =~ $regex_staged ]]; then
BRANCH_COLOR=${PURPLE}
else
BRANCH_COLOR=${RED}
fi
elif [[ ${STATUS} =~ $regex_staged ]]; then
BRANCH_COLOR=${YELLOW}
else
BRANCH_COLOR=${GREEN}
fi >/dev/null
PS1+="${PARENTHESES_COLOR}(${RESTORE}${BRANCH_COLOR}$(git_branch)${RESTORE}${PARENTHESES_COLOR})${RESTORE}"
fi
消耗的时间减少:
real 2m15.534s
user 1m1.036s
sys 2m15.043s
顺便说一句,如果没有这个多彩的分支功能,性能是
real 1m0.478s
user 0m29.499s
sys 1m1.411s
【问题讨论】:
-
你可以用
git branch 2>/dev/null | sed -ne "s/^\*\ //p"分解echo | grep | sed -
您确定这是 bash 问题吗?也许真正的问题是 Git 命令?
-
$(pwd)应该是"$PWD",只要性能很重要。 -
这里不太可能产生明显的差异,但双方括号的计算速度比单方括号快得多。前者是一个 shell 关键字,而后者是一个内置的 shell。这可能只会在循环中产生真正的差异。正如其他人所指出的那样,产生一堆外部进程很可能是罪魁祸首。
-
@CharlesDuffy:是的,我知道,我也说了这么多。但显然
[[的计算速度大约快了三分之一,至少在某些情况下是这样:将time for ((i=0; i<10000000; i++)); do [[ "$i" = 1000 ]]; done与带有单方括号的相同事物进行比较。对我来说,[[的循环在大约 24 秒内执行,但[大约需要 36 秒。