是否正在使用内置增强功能来增强无偿使用子壳的性能?

时间:2018-04-07 02:32:50

标签: performance shell subshell gnu-coreutils

我正在编写一个脚本,我需要确保字符串包含逗号。如果它不是我需要脚本退出。考虑下面的内容,我的目的是仅使用内置函数来提高性能:

#!/bin/sh

check_for_commas='This string must contain a comma'

comma_found='0'
iterate_through_string="$check_for_commas"
while [ -n "$iterate_through_string" ]; do
    char="$(printf '%.1s' "$iterate_through_string")"

    if [ "$char" = ',' ]; then
        comma_found='1'
        break
    fi

    iterate_through_string="${iterate_through_string#?}"
done

if [ "$comma_found" != '1' ]; then
    echo 'Your string does not contain a comma. Exiting...'
    exit
else
    echo 'Found a comma in the string. Script can continue...'
fi

我在这个脚本中使用命令替换,它为它迭代的每个字符生成一个子shell。与此相比:

#!/bin/sh

check_for_commas='This string must contain a comma'

if [ "$(echo "$check_for_commas" | grep -q -F ','; echo "$?")" = '1' ]; then   
    echo 'Your string does not contain a comma. Exiting...'
    exit
else
    echo 'Found a comma in the string. Script can continue...'
fi

我显然不介意做一些额外的工作来挤出额外的表现。但是我担心使用这么多子壳已经打败了我的整个初衷。

当无意中使用子壳进入画面时,我对仅使用内置增强性能的追求是否变得毫无用处?

2 个答案:

答案 0 :(得分:3)

命令替换,如$(printf ...),确实很昂贵 - 并且你不需要它们用于你在这里做的事情

case $check_for_commas in
  *,*) echo "Found a comma in the string";;
  *)   echo "No commas present; exiting"; exit 1;;
esac

在更一般的情况下 - 仅fork()成本低于fork()/execve()对,因此拥有单个子shell比单个外部命令调用更便宜;但是如果你比较一个生成多个子shell的循环与一个外部命令调用的比较,这个更便宜取决于你的循环迭代次数(以及你的操作系统中每个东西的价格有多贵 - 分叉是传统上在Windows上比较昂贵,并且就像这样一个事实密集型调查。 :)

(说到最初提出的代码 - 请注意,ksh93会优化特定fork案例中的var=$(printf ...);相比之下,在bash中,您需要使用printf -v var ...来得到同样的效果)。

答案 1 :(得分:1)

这是一个简短的 POSIX shell函数,它使用组合的删除匹配的前缀模式删除匹配的后缀模式和{{ 1}},(或者更确切地说test这是相同的事情),如果有逗号,则返回 true 标志:

[

没有逗号的示例:

chkcomma(){ [ "${1#${1%,*}}" ] ; }

输出:

chkcomma foo && echo comma found || echo no comma

逗号示例:

no comma

输出:

chkcomma foo,bar && echo comma found || echo no comma

这可以进一步抽象,以使用globbing找到子字符串:

comma found

示例:

# Usage: instr globpattern string
# returns true if found, false if not.
instr(){ [ "${2#${2%${1}*}}" ] ; }

输出:

instr '[Mm]oo' mood && echo found