From e8269dc42cceedd2e82ebf860b1f3fa8a8b69ded Mon Sep 17 00:00:00 2001 From: Leah Neukirchen Date: Mon, 21 Aug 2017 20:17:03 +0200 Subject: holes: don't use bytewise i/o Use fread to reduce overhead of calling stdio. Then use memchr to find the initial thing we search for (to dismiss nonmatching blocks quickly), then loop manually while it matches. --- holes.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/holes.c b/holes.c index 41fc50c..6bff701 100644 --- a/holes.c +++ b/holes.c @@ -16,20 +16,37 @@ holes(FILE *input, char *filename) { off_t offset = 0; off_t run = 0; - int ch; + static char buf[16384]; - while ((ch = getc_unlocked(input)) != EOF) { - if (ch == byte) { - run++; + int len; + int i; + char *d; + + while ((len = fread(buf, 1, sizeof buf, input)) >= 1) { + if (run == 0) { + d = memchr(buf, byte, len); + if (!d) { + offset += len; + continue; + } + i = d - buf; + offset += i; } else { - if (run >= minlen) { - if (filename) - printf("%s: ", filename); - printf("%08lx %ld\n", offset - run, run); + i = 0; + } + for (; i < len; i++) { + if (buf[i] == byte) { + run++; + } else { + if (run >= minlen) { + if (filename) + printf("%s: ", filename); + printf("%08lx %ld\n", offset - run, run); + } + run = 0; } - run = 0; + offset++; } - offset++; } if (ferror(input)) { fprintf(stderr, "%s: can't read '%s': %s\n", -- cgit 1.4.1