【问题标题】:Grep from array is much slower than grep from file来自数组的 grep 比来自文件的 grep 慢得多
【发布时间】:2011-12-04 21:47:29
【问题描述】:

为了优化我的 bash 脚本,我将文件加载到一个数组中并尝试从那里进行 grep,我注意到内存中的 grep 比文件中的标准 grep 慢得多,即使考虑到事实上,磁盘 I/O 已被排除在外。

1) 好的,所以我有一个包含名称=值对的大文件(大约 3000 行),这是我的“缓存”。我将它从文件加载到一个数组中(足够直截了当)

# load to array
l_i_array_index=1
while read line
  do
  g_a_cache[$l_i_array_index]=$line
  let "l_i_array_index += 1"
  done < $g_f_cache

2) 然后我运行一个搜索性能的小基准测试:

time for i in `seq 1 100`
  do
  for l_i_array_index in `seq 1 ${#g_a_cache[@]}`
    do
      echo ${g_a_cache[$l_i_array_index]}
    done | grep -c $l_s_search_string > /dev/null
  done

real    0m14.387s
user    0m13.846s
sys     0m1.781s

3) 相同,但直接来自磁盘文件:

time for i in `seq 1 100`
  do
  grep -c $l_s_search_string $g_f_cache > /dev/null
  done
real    0m0.347s
user    0m0.161s
sys     0m0.136s

所以性能会差 13 到 40 倍,而实际上应该更好。

我的问题是:1)这种奇怪行为的原因是什么2)这在 bash 中是可以解决的,还是我应该硬着头皮最后在 Python 中重做

附:测试是在 Mac (bash v4) 上完成的,在 Cygwin 中,使用普通 grep(速度更快)每次 ONE 搜索的时间超过一秒,而使用数组方法则超过 10 秒。该脚本接近无法使用..

【问题讨论】:

    标签: arrays bash grep


    【解决方案1】:

    grep 程序多年来一直由搜索和算法设计领域的顶级专家进行了大量优化。你根本不会用 shell 脚本打败它。这是一个荒谬的概念。

    老实说,我无法想象您为什么会期望与grep 一样快。也许您认为所有greps 磁盘I/O 实际上都需要对实际的物理磁盘做一些事情。但事实并非如此。每个现代操作系统都有一个磁盘缓存,文件在第一次被读取后就会在缓存中,这需要几分之一秒。

    【讨论】:

    • 大卫,我也很怀疑 :) 我在优化 Cygwin 的搜索时仍然存在问题,每次搜索需要一秒钟以上的时间。那里对我有希望吗?谢谢!
    • 这很奇怪。我想知道它是否是进程启动时间。运行一个测试,启动grep,但它基本上什么都不做(也许搜索一个不存在的文件,所以你只会得到一个错误),看看需要多长时间。
    • 大卫,grep 在 Mac 上相当快,这是 Cygwin 给我带来的问题。您认为有一种方法可以加快 ONE 随机搜索的速度吗?
    • 不知道为什么它很慢,因此我建议进行测试。
    • 抱歉,知道了。您确实有一点:“grep x x”在 Mac 上执行时间为 0.4 秒或更短,在 Cygwin 上执行时间为 1 到 4 秒:(
    【解决方案2】:

    这可能与文件系统缓存有关,这会导致“优化”实现实际上增加了开销。

    文件系统缓存可以通过以下方式观察到:

    localhost elhigu$ time grep -r "testnottofind" * 
    real    0m22.468s
    user    0m0.172s
    sys 0m0.828s
    localhost elhigu$ time grep -r "testnottofind" * 
    real    0m0.826s
    user    0m0.087s
    sys 0m0.232s
    localhost elhigu$ time grep -r "testnottofind2" * 
    real    0m0.285s
    user    0m0.084s
    sys 0m0.190s
    localhost elhigu$ time grep -r "moretesting" * 
    real    0m0.285s
    user    0m0.086s
    sys 0m0.185s
    localhost elhigu$ 
    

    还有更多信息https://unix.stackexchange.com/questions/8914/does-grep-use-a-cache-to-speed-up-the-searches

    【讨论】:

    • Mikael,也许我没有很好地提出这个问题。我实际上并没有使用后续搜索。我真正的问题是我必须加快正常的“grep $string $file”搜索,而数组似乎不是办法。特别是 Cygwin 中的搜索性能非常糟糕,每次搜索超过 1 秒。对于一个残暴的交互式脚本。
    • 好的,所以问题是 grep 在 Cygwin 上太慢了。如果unxutils.sourceforge.net 端口工作得更快,你试过了吗?
    • Cygwin 是我的下意识反应,我也会尝试 unixutils,谢谢!
    猜你喜欢
    • 1970-01-01
    • 2010-12-29
    • 1970-01-01
    • 2020-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多