V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
hujianxin
V2EX  ›  Linux

为什么 grep 大文件,第二遍就会变得很快呢?

  •  1
     
  •   hujianxin · 2018-10-25 15:58:35 +08:00 · 5460 次点击
    这是一个创建于 2213 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我 grep 一个大文件,第一遍大约几十秒,第二遍就很快了,几乎秒出,请问这是为什么呢?

    23 条回复    2018-10-26 19:36:28 +08:00
    tamlok
        2
    tamlok  
       2018-10-25 16:22:04 +08:00 via Android
    操作系统文件读写缓存吧
    hujianxin
        3
    hujianxin  
    OP
       2018-10-25 16:59:19 +08:00
    @d0m2o08 @tamlok 谢谢,我有点疑惑,貌似还不是内存缓存,因为 grep 是一行一行读的,我几十 G 的文件,grep 完之后,内存几乎没变过,还是维持在 grep 之前的水平。也就是说,这个缓存是在文件中吗?
    wohenyingyu02
        4
    wohenyingyu02  
       2018-10-25 17:06:48 +08:00 via iPhone
    @hujianxin 一楼的回答是操作系统会缓存最近读写的文件,是不是可以这么理解,原来缓存的是别的文件,你 grep 一次后,把别的文件释放了,替换进去,所以看起来内存不变?
    tamlok
        5
    tamlok  
       2018-10-25 17:12:58 +08:00 via Android
    @hujianxin 操作系统启动的时候就占用了不少内存,其中可能就有缓存的部分。另外,我觉得缓存这一部分的内存,操作系统也可能展示给用户的是空闲的状态?
    helionzzz
        6
    helionzzz  
       2018-10-25 17:40:56 +08:00
    缓存这一部分应该都是预留的吧
    LGA1150
        7
    LGA1150  
       2018-10-25 17:47:51 +08:00   ❤️ 1
    执行以下命令清除缓存之后再试试?
    sync; sudo sysctl -w vm.drop_caches=3
    sniperhgy
        8
    sniperhgy  
       2018-10-25 17:48:52 +08:00
    linux 本来就和 windows 的内存管理机制不一样,windows 是起来后,有需要才进行占用,linux 是起来后,先占用了再说,多多益善。所以楼主看到的所谓内存没有变化,只是 linux 没有占用的那一部分
    aijam
        9
    aijam  
       2018-10-25 17:54:37 +08:00
    文件系统缓存
    des
        10
    des  
       2018-10-25 17:58:31 +08:00 via Android
    @sniperhgy 现在 windows 也是了,甚至还会主动缓存最近的文件
    flynaj
        11
    flynaj  
       2018-10-25 18:48:05 +08:00 via Android
    第一次是从硬盘读,后面已经缓存在内存里面了。
    x66
        12
    x66  
       2018-10-25 18:53:35 +08:00 via iPhone
    @des 挺好的啊,用久了常用的文件都缓存起来了。别经常关机就好了
    hujianxin
        13
    hujianxin  
    OP
       2018-10-25 18:59:54 +08:00 via iPhone
    问题是,我 grep 一个 50g 的文件,内存没涨过,才用了 5g,所以这些文件是不可能缓存到内存的啊
    dszhblx
        14
    dszhblx  
       2018-10-25 19:04:51 +08:00 via iPhone
    @hujianxin 那是系统缓存没记入你看到的数值了,free 命令了解一下
    LGA1150
        15
    LGA1150  
       2018-10-25 19:05:27 +08:00
    @hujianxin free 看 cached 的变化
    liaohongxing
        16
    liaohongxing  
       2018-10-25 19:40:50 +08:00
    linux 和 windows 内存机制不一样 ,linux 会先占用空闲内存,而且 linux 会缓存文件系统 。用 free -m 或者 dd 复制一下。能明显感受到有缓存。
    mengzhuo
        17
    mengzhuo  
       2018-10-25 21:03:04 +08:00 via Android
    cache 啊~
    noli
        18
    noli  
       2018-10-26 09:36:30 +08:00
    @hujianxin 就算你文件是 100G 1T 也没有必要一次过全部放入内存中缓存啊,你的应用也没有一次过读 100G 1T 的能力啊。这么想之后你就会发现是因为你知道得太少。
    cyspy
        19
    cyspy  
       2018-10-26 11:28:25 +08:00
    Linux 的缓存策略比 Win 激进不少,Linux 下群星重开都是秒进,估计全都在 RAM 里
    yc8332
        20
    yc8332  
       2018-10-26 11:35:12 +08:00
    必须是缓存啊。。。不然怎么 linux 下可用内存长时间都是比较少的。除非手动释放
    hujianxin
        21
    hujianxin  
    OP
       2018-10-26 13:17:38 +08:00 via iPhone
    @noli 请教一下,既然没放到缓存中,为什么第二次那么快呢?
    Greenm
        22
    Greenm  
       2018-10-26 15:21:18 +08:00
    这个是缓存命中和未命中的问题吧,第一遍全部不命中,第二遍几乎都命中了。
    noli
        23
    noli  
       2018-10-26 19:36:28 +08:00
    @hujianxin

    并不是没有放到缓存中,而是不论多大的文件,怎么放入缓存里面是有讲究的。
    而你的观测方法,譬如说,只观察内存和 swap 的总使用量,不一定能说明缓存使用的内部变化。
    如果你把 Disk IO 以及内存读写次数也纳入观察了,你才可以发现第二遍读取速度变快的原因。

    简单来说就是,grep 读取一个文件是顺序向前读取,文件分片存储在文件系统中(例如 ext 系列等等)
    利用好这两个特点,可以写出一个不需要增大缓存使用量也可以提高读取效率的算法。
    而这就是 内核或者 FS 提供的,具体如何实现,可以看相关文档或者书籍或者源代码。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1036 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 19:49 · PVG 03:49 · LAX 11:49 · JFK 14:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.