【问题标题】:Why is this grep filter slow?为什么这个 grep 过滤器很慢?
【发布时间】:2011-03-22 22:16:53
【问题描述】:

我想获取 BSD dict 单词列表中每个单词的前两个字母,不包括那些仅以一个字母开头的单词。

没有一个字母的排除,它运行得非常快:

time cat /usr/share/dict/web2 | cut -c 1-2 | tr '[a-z]' '[A-Z]' | uniq -c > /dev/null

real    0m0.227s
user    0m0.375s
sys 0m0.021s

然而,在 '..' 上的 grepping 非常缓慢:

time cat /usr/share/dict/web2 | cut -c 1-2 | grep '..' | tr '[a-z]' '[A-Z]' | uniq -c > /dev/null

real    1m16.319s
user    1m0.694s
sys 0m10.225s

这是怎么回事?

【问题讨论】:

  • ʞɔıu,这一定是我见过的最酷的帐户名称之一。

标签: regex unix command-line grep


【解决方案1】:

问题在于 UTF-8 语言环境,100 倍加速的简单解决方法


在 Mac 上真正慢的是 UTF-8 语言环境。

将grep .. 替换为LC_ALL=C grep ..,那么您的命令运行速度将提高100 倍以上。

Linux 可能也是如此,除了给定的 Linux 发行版可能更可能默认为 C 环境。

【讨论】:

    【解决方案2】:

    我不知道为什么它如此糟糕。但我知道加快速度的一种快速方法是将grep(1) 表达式与-v 反转,并丢弃所有单字符行:

    $ time cat /usr/share/dict/words | cut -c 1-2 | grep -v '^.$' | tr '[a-z]' '[A-Z]' | uniq -c > /dev/null
    
    real    0m0.086s
    user    0m0.090s
    sys  0m0.000s
    

    【讨论】:

      【解决方案3】:

      这可能会运行得更好一些,并且还可以摆脱需要另一个管道的切割。

      cat /usr/share/dict/web2 | egrep -o '^.{2,}' | tr '[a-z]' '[A-Z]' | uniq -c > /dev/null
      

      【讨论】:

        【解决方案4】:

        如果你减少使用过多的管道和无用的猫,它可能会更快

        $ awk '{ a[toupper(substr($0,1,2))]++ } END{for(i in a) print i,a[i] }' file
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-10-19
          • 2016-10-13
          • 1970-01-01
          • 1970-01-01
          • 2011-06-15
          • 2011-03-27
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多