Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
非常慢的bash循环_Bash_Performance_Function_While Loop - Fatal编程技术网

非常慢的bash循环

非常慢的bash循环,bash,performance,function,while-loop,Bash,Performance,Function,While Loop,我做了一件很快的事情,把一些命令塞进一个函数,循环一个文件,然后在每一行运行它。我对它所达到的缓慢速度感到惊讶 关于如何加速使用臭味函数的循环,有什么建议吗 #!/bin/bash list="lists/test.txt" smellyfunc() { alphabet=abcdefghijklmnopqrstuvwxyz bgam=bcdefghijklmnopqrstuvwxyz plaintext=THXGAWDITSFRIDAYTODAY plaintext=$(echo "$pl

我做了一件很快的事情,把一些命令塞进一个函数,循环一个文件,然后在每一行运行它。我对它所达到的缓慢速度感到惊讶

关于如何加速使用臭味函数的循环,有什么建议吗

#!/bin/bash
list="lists/test.txt"

smellyfunc() {

alphabet=abcdefghijklmnopqrstuvwxyz
bgam=bcdefghijklmnopqrstuvwxyz
plaintext=THXGAWDITSFRIDAYTODAY
plaintext=$(echo "$plaintext" | tr A-Z a-z | sed s/[^a-z]//g) 
step=0

while test -n "$plaintext"
do
  key=$1
  length=${#key}
  char=${plaintext:0:1}
  shift=${key:$step:1}
  code=$(echo -n $(($(expr index $bgam $char)-$(expr index $bgam $shift))))
  step=$(($(($step+1))%$length))
  if [[ $code -lt 0 ]]
    then
    code=$((code+26))
  fi
  if [[ $code -gt 25 ]]
    then
    code=$((code-26))
  fi
  echo -n ${alphabet:$code:1}
  plaintext=${plaintext:1}
done
}

while read line; do
   key="$line"
   result="$(smellyfunc "$key")"
   echo "$result" "$key"
done < $list
#/bin/bash
list=“lists/test.txt”
臭味{
字母表=abcdefghijklmnopqrstuvxyz
bgam=bcdefghijklmnopqrstuvxyz
纯文本=THXGAWDITSFRIDAYTODAY
明文=$(回显“$明文”| tr A-Z A-Z | sed s/[^A-Z]//g)
步长=0
而测试-n“$plaintext”
做
钥匙=1美元
长度=${key}
char=${纯文本:0:1}
shift=${key:$step:1}
代码=$(echo-n$($(expr索引$bgam$char)-$(expr索引$bgam$shift)))
步长=$($($step+1))%$length)
如果[$code-lt 0]]
然后
代码=$((代码+26))
fi
如果[$code-gt 25]]
然后
代码=$((代码-26))
fi
echo-n${字母:$code:1}
明文=${明文:1}
完成
}
读行时;做
key=“$line”
结果=“$(嗅觉功能“$键”)”
回显“$result”“$key”
完成<$list

谢谢

如果我们重写,这样您就不需要调用任何外部程序,并且您可以节省回显输出,那么我们可以获得很大的加速:

# function to mimic `expr index`
index() {
    local prefix=${1%%$2*}
    local i=${#prefix}
    if [[ $prefix == $1 ]]; then
        # substring $2 not found in $1
        i=-1
    fi
    echo $((i+1))
}

aromaticfunc() {
    local alphabet=abcdefghijklmnopqrstuvwxyz
    local bgam=bcdefghijklmnopqrstuvwxyz
    local step=0
    local -l plaintext=THXGAWDITSFRIDAYTODAY
    plaintext=${plaintext//[^a-z]/}
    local key length char shift code
    local result=""

    while [[ -n $plaintext ]]; do
        key=$1
        length=${#key}
        char=${plaintext:0:1}
        plaintext=${plaintext:1}
        shift=${key:$step:1}
        code=$(( $(index $bgam $char) - $(index $bgam "$shift") ))
        code=$(( (code+26) % 26 ))
        step=$(( (step+1) % length ))
        result+=${alphabet:$code:1}
    done
    echo "$result"
}
然后看看我们是否得到相同的结果:

$ s=$( smellyfunc helloworld )
$ a=$( aromaticfunc helloworld )
$ [[ $s == $a ]] && echo OK || echo different
OK
而且,为了解决这个问题,它是否更快

$ time for i in {1..100}; do result=$(smellyfunc helloworld); done 

real    0m7.339s
user    0m5.739s
sys 0m0.967s
$ time for i in {1..100}; do result=$(aromaticfunc helloworld); done 

real    0m2.725s
user    0m1.879s
sys 0m0.613s

因此,大约有3倍的加速。

如果我们重写,这样您就不需要调用任何外部程序,并且您可以节省回显输出,我们可以获得很大的加速:

# function to mimic `expr index`
index() {
    local prefix=${1%%$2*}
    local i=${#prefix}
    if [[ $prefix == $1 ]]; then
        # substring $2 not found in $1
        i=-1
    fi
    echo $((i+1))
}

aromaticfunc() {
    local alphabet=abcdefghijklmnopqrstuvwxyz
    local bgam=bcdefghijklmnopqrstuvwxyz
    local step=0
    local -l plaintext=THXGAWDITSFRIDAYTODAY
    plaintext=${plaintext//[^a-z]/}
    local key length char shift code
    local result=""

    while [[ -n $plaintext ]]; do
        key=$1
        length=${#key}
        char=${plaintext:0:1}
        plaintext=${plaintext:1}
        shift=${key:$step:1}
        code=$(( $(index $bgam $char) - $(index $bgam "$shift") ))
        code=$(( (code+26) % 26 ))
        step=$(( (step+1) % length ))
        result+=${alphabet:$code:1}
    done
    echo "$result"
}
然后看看我们是否得到相同的结果:

$ s=$( smellyfunc helloworld )
$ a=$( aromaticfunc helloworld )
$ [[ $s == $a ]] && echo OK || echo different
OK
而且,为了解决这个问题,它是否更快

$ time for i in {1..100}; do result=$(smellyfunc helloworld); done 

real    0m7.339s
user    0m5.739s
sys 0m0.967s
$ time for i in {1..100}; do result=$(aromaticfunc helloworld); done 

real    0m2.725s
user    0m1.879s
sys 0m0.613s

因此,大约有3倍的加速。

我敢打赌,用Perl这样的语言实现它会带来更大的改进将
local
s更改为
typeset
s,并且您支持ksh,它可以更快地运行同一个脚本。这就是说,这仍然是分岔——更有效的方法是让
索引
使用间接赋值来传回结果,这样它的调用就不需要使用命令替换。使用ksh93,我得到了100次调用循环的0.13秒挂钟时间……看,我在windows 10中运行ubuntu vm,所以我已经在速度上受到了惩罚。然而,使用ksh带来了更大的改进:臭味=3.24s real,芳香(在s/local/typeset/之后)=0.20s real我敢打赌,用Perl这样的语言实现它会带来更大的改进将
local
s更改为
typeset
s,并且您支持ksh,它可以更快地运行相同的脚本。这就是说,这仍然是分岔——更有效的方法是让
索引
使用间接赋值来传回结果,这样它的调用就不需要使用命令替换。使用ksh93,我得到了100次调用循环的0.13秒挂钟时间……看,我在windows 10中运行ubuntu vm,所以我已经在速度上受到了惩罚。然而,使用ksh带来了更为显著的改进:臭味=3.24s real,芳香(在s/local/typeset/之后)=0.20s realRule#1编写bash时性能良好:不要使用命令替换(
$()
或等效命令)。规则2:不要使用管道。规则#3:不要使用外部命令……也就是说,对于CPU绑定的代码,一个完全不同的实现通常是合适的(或者只是一个不同的解释器;一旦删除了必要的慢的东西(如子shell和c),David Korn ksh93比bash快得多).编写性能良好的bash的规则1:不要使用命令替换(
$()
或等效命令)。规则2:不要使用管道。规则#3:不要使用外部命令……也就是说,对于CPU绑定的代码,一个完全不同的实现通常是合适的(或者只是一个不同的解释器;一旦删除了必要的慢的东西(如子shell和c),David Korn ksh93比bash快得多)。