19

When looking for matches with grep, I often notice that the subsequent search takes significantly less time than the first-- e.g. 25s vs. 2s. Obviously, it's not by reusing the data structures from its last run-- those should've been deallocated. Running a time command on grep, I noticed an interesting phenomenon:

real    24m36.561s
user    1m20.080s
sys     0m7.230s

Where does the rest of the time go? Is there anything I can do to make it run fast every time? (e.g. having another process read the files, before grep searches them.)

2 Answers 2

34

It is quite often related to the page cache.

The first time, the data has to be read (physically) from the disk.

The second time (for not too big files) it is likely to be sitting in the page cache.

So you could issue first a command like cat(1) to bring the (not too big) file into the page cache (i.e. in RAM), then a second grep(1) (or any program reading the file) would generally run faster.

(however, the data still needs to be read from the disk at some time)

See also (sometimes useful in your application programs, but practically rarely) readahead(2) & posix_fadvise(2) and perhaps madvise(2) & sync(2) & fsync(2) etc....

Read also LinuxAteMyRAM.

BTW, this is why it is recommended, when benchmarking a program, to run it several times. Also, this is why it could be useful to buy more RAM (even if you don't run programs using all of it for their data).

If you want to understand more, read some book like e.g. Operating Systems : Three Easy Pieces

10
  • 12
    So, the TL;DR answer is "[block waiting for] I/O". Jul 12, 2017 at 17:45
  • 10
    @PaulDraper Not really :) cat + grep is still going to take longer than grep alone.
    – chepner
    Jul 12, 2017 at 18:01
  • 3
    @chepner Unless you can multithread and use cat as a cheap pre-fetch while you're doing something else, in prep for the grep of interest.
    – hBy2Py
    Jul 12, 2017 at 18:21
  • 2
    @MarkKCowan: Lovely cats!   :-)   ⁠ Jul 12, 2017 at 22:13
  • 3
    @G-Man: You can also replace two of the cats with tac for the same effect and higher RAM usage :D Or all of the cats with tac Jul 12, 2017 at 22:58
-1

In a network storage environment, there can also be relatively significant delays when you first access a file that resides on a "filer" separate from the server. Once that file has been accessed on the server, it will be cached locally and subsequent access to the data will be much faster.

Here's an experiment just computing a checksum of the file data -- not grep. The first invocation is slow, and subsequent ones are fast.

> du -Dh file_348m
348M    file_348m

> /usr/bin/time md5sum file_348m
738709b181b52ddfcef3413997f91462  file_348m
0.60user 0.15system 0:03.02elapsed 25%CPU (0avgtext+0avgdata 1524maxresident)k
708144inputs+0outputs (0major+80minor)pagefaults 0swaps

> /usr/bin/time md5sum file_348m
738709b181b52ddfcef3413997f91462  file_348m
0.67user 0.06system 0:00.73elapsed 99%CPU (0avgtext+0avgdata 1524maxresident)k
0inputs+0outputs (0major+80minor)pagefaults 0swaps

> /usr/bin/time md5sum file_348m
738709b181b52ddfcef3413997f91462  file_348m
0.65user 0.07system 0:00.73elapsed 99%CPU (0avgtext+0avgdata 1524maxresident)k
0inputs+0outputs (0major+80minor)pagefaults 0swaps

> /usr/bin/time md5sum file_348m
738709b181b52ddfcef3413997f91462  file_348m
0.66user 0.06system 0:00.73elapsed 99%CPU (0avgtext+0avgdata 1524maxresident)k
0inputs+0outputs (0major+80minor)pagefaults 0swaps
6
  • I'd appreciate comments for downvote(s), as I don't know how to interpret them. I believe my answer description is correct. Perhaps the command example isn't clear? Or you don't like that I didn't benchmark the grep command? (I intentionally used a simpler command, md5sum, to try to illustrate my point.) Jul 18, 2017 at 21:09
  • 1
    I think the reason is, your post did not add any new information relevant to what I was asking. I already knew there was a delay, and the first answer already gave an explanation of why it's happening. But yeah, I get downvotes without explanation too. Even on questions with good answers.
    – Alex
    Jul 18, 2017 at 21:54
  • Thanks @Alex for suggesting a reason. I was trying to distinguish between the overhead time to move data from local storage to memory, which the first answer described, and the overhead time to move data from network storage to the local server. I will think if I could describe this more clearly or provide better command examples. Jul 18, 2017 at 22:11
  • I guess after reading your post, my thought is, it is still the overhead of moving data from wherever it's stored, to memory. Whether it's from network storage, or from local storage, doesn't matter-- Unix still sees it as moving from a directory to memory. p.s.-- it looks like my explanation is correct-- my comment with the reason got an upvote.
    – Alex
    Jul 18, 2017 at 22:21
  • I see, I was adding a distinction that isn't important to what you were looking for. OK. By the way, I upvoted your comment, so it doesn't solve the question of the downvoting reason. :-) Jul 18, 2017 at 22:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .