The C Programming Language, 2nd Edition, by Kernighan and Ritchie
Exercise 5.07 on page 110
Rewrite readlines to store lines in an array supplied by main , rather than calling alloc to maintain storage. How much faster is the program?
Solution by Steven Huang
/* K&R Exercise 5-7 */ /* Steven Huang */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <time.h> #define TRUE 1 #define FALSE 0 #define MAXLINES 5000 /* maximum number of lines */ #define MAXLEN 1000 /* maximum length of a line */ char *lineptr[MAXLINES]; char lines[MAXLINES][MAXLEN]; /* K&R2 p29 */ int getline(char s[], int lim) { int c, i; for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; i++) s[i] = c; if (c == '\n') { s[i++] = c; } s[i] = '\0'; return i; } /* K&R2 p109 */ int readlines(char *lineptr[], int maxlines) { int len, nlines; char *p, line[MAXLEN]; nlines = 0; while ((len = getline(line, MAXLEN)) > 0) if (nlines >= maxlines || (p = malloc(len)) == NULL) return -1; else { line[len - 1] = '\0'; /* delete the newline */ strcpy(p, line); lineptr[nlines++] = p; } return nlines; } int readlines2(char lines[][MAXLEN], int maxlines) { int len, nlines; nlines = 0; while ((len = getline(lines[nlines], MAXLEN)) > 0) if (nlines >= maxlines) return -1; else lines[nlines++][len - 1] = '\0'; /* delete the newline */ return nlines; } int main(int argc, char *argv[]) { /* read things into cache, to be fair. */ readlines2(lines, MAXLINES); if (argc > 1 && *argv[1] == '2') { puts("readlines2()"); readlines2(lines, MAXLINES); } else { puts("readlines()"); readlines(lineptr, MAXLINES); } return 0; }
Steven writes:
"Unfortunately, the follow-up question here on which
version is faster is difficult to determine on my
machine, because the difference is very small. I
can call malloc() one million times in under a
second - this suggests that the conventional wisdom
that malloc() is slow and should be avoided may need
some more adjustment."
[Editor's note: That's probably because malloc is actually
taking memory requests to the system as infrequently as possible,
so that most of the calls invoke little more than pointer
arithmetic. This suggests that the conventional wisdom may be
based on real world programs, rather than artificial "how
many mallocs per second can I do" benchmarks. :-) ]
[This space reserved for Steven's right of reply!]










