为什么约会这么慢?

时间:2012-04-26 17:41:47

标签: bash

任何人都知道更好的方法是做得更快吗?当每秒高行输入此脚本时,这当前很慢:


#!/bin/bash

declare -A clientarray
file=$1
timer=$2
e=$(date --date "now +$timer second" +%s)

while read line
do

    if [ -n "${clientarray[$line]}" ]; then
            let "clientarray[$line]=clientarray[$line]+1"
            echo "$line: ${clientarray[$line]}"

    elif [ -z "${clientarray[$line]}" ]; then
            clientarray[$line]=1
            echo "$line: ${clientarray[$line]}"

    fi
    if [ $(date +%s) -gt $e ]; then
                    e=$(date --date "now +$timer second" +%s)

    fi
done < <(tail -F $file | gawk -F"]" '/]/ {print $1}')

以下是这些行的示例:

someline]
someline2]
somethingidontwant
someline3]
somethingelseidontwant
someline4]

并调用脚本:

bash script.sh somelogfile.log 1

如果我在最后注释掉if逻辑它会非常快但是速度会下降2 / 3rds。用pv:

测试

(这是if逻辑):

ubuntu@myhost:~/graphs$ tail -F somelogfile.log | pv -N RAW -lc >/dev/null | 
                      > bash script.sh somelogfile.log 1 | pv -N SCP -lc >/dev/null

  RAW: 2.18k 0:00:16 [ 493/s ] [                 <=>                             ]
  SCP:  593 0:00:16 [ 150/s ] [             <=>                                  ]

(没有)

ubuntu@myhost:~/graphs$ tail -F somelogfile.log | pv -N RAW -lc >/dev/null |
                      > bash script.sh somelogfile.log 1 | pv -N SCP -lc >/dev/null

  RAW: 7.69k 0:00:15 [512/s] [                                     <=>           ]
  SCP:  7.6k 0:00:15 [503/s] [                              <=>                  ]

如果我在脚本或测试方面遗漏了某些内容,请告诉我,尤其是“DOH!”。 我想在这一点上我会爱一个=)

2 个答案:

答案 0 :(得分:2)

作为猜测,我说可能是最后if ... fi块每次迭代添加两个非内置命令。循环中的其他所有内容都是bash builtins,执行速度更快。有了它,您可以在测试中调用date,在if的正文中调用另一个调用。此外,date --date必须在每次调用"now +$timer second"表达式时对其进行解析和评估,这可能不是非常快速,因为--date&#39}概论。如果我是你,我会尝试用脚本语言重新实现这一点,并使用更多的日期/时间本地处理:Perl,Ruby,Python,无论你喜欢什么。

您似乎也有错误:

if [ `date +%s` > $e ] ...

这说:执行命令date +%s并将其输出(比如12345)插入另一个命令[ 12345 > $e ](到目前为止一直很好)。该命令说:使用两个参数([12345)运行]内置,并将其标准输出流重定向到由$e值命名的文件(呃-哦)。您可能希望在此使用-gt代替>

答案 1 :(得分:0)

我不确定您使用$e做了什么,但是您可以使用内置printf的内容以比date更快的速度打印当前日期}。子进程调用往往很昂贵。例如,如果你不在glibc2上,你可以这样做:

printf '%(%+)T\n' -1

准确获取date命令的输出。 glibc2不支持%+,因此您可以构造与其他参数相同的内容,或类似的内容:

printf '%(%c %Z)T\n' -1

如果您需要以某种方式捕获和处理日期,那么您可能仍然需要使用$()进行子shell调用,但是它仍然比date更快。< / p>