从《The.C.Programming.Language.2Nd.Ed 》5.7题出发,用参考答案开始。
“Exercise 5−7. Rewrite readlines to store lines in an array supplied by main, rather than calling alloc to maintain storage. How much faster is the program?”
/* 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. :-) ]“
修改上面的参考答案源码,使之可以正确运行,代码如下。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#define TRUE 1
#define FALSE 0
#define MAXLINES 10000300 /* maximum number of lines */
#define MAXLEN 1000 /* maximum length of a line */
char *lineptr[MAXLINES];
char lines[MAXLINES][MAXLEN];
///* K&R2 p29 */
//int my_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, FILE * file)
{
int len, nlines;
char *p, line[MAXLEN];
int maxlen = MAXLEN;
nlines = 0;
while ((len = getline((char **)&line, (size_t *)&maxlen, file)) > 0)
if (nlines >= maxlines || (p = malloc( len + 1 )) == 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, FILE * file)
{
int len, nlines;
int maxlen = MAXLEN;
nlines = 0;
while ((len = getline((char **)lines, (size_t *)&maxlen, file)) > 0)
if (nlines >= maxlines)
return -1;
else
lines[nlines++][len - 1] = '\0'; /* delete the newline */
return nlines;
}
int main(int argc, char *argv[])
{
FILE * strm_file = fopen("input_data.txt", "r");
if( strm_file == NULL )
{
perror("Failed to open file.");
return 1;
}
/* read things into cache, to be fair. */
printf("readlines2()=%d\n",readlines2(lines, MAXLINES, strm_file));
rewind(strm_file);
if (argc > 1 && *argv[1] == '2') {
printf("readlines2()=%d\n",readlines2(lines, MAXLINES, strm_file));
} else {
printf("readlines()=%d\n",readlines(lineptr, MAXLINES, strm_file));
}
if(strm_file != NULL)
{
fclose(strm_file);
}
return 0;
}
目前还有段错误。