我想特别了解fget()和getc()之间的速度差异--主要是针对大量的数据。我选择getc()是因为在其他线程中,有人说它比fgetc()更快,因为它可以作为宏运行。类似地,gets()是不受欢迎的,因为它没有像fget()这样的缓冲区限制。
我做了一个小小的例子程序,希望有人知道如何衡量时间和资源使用的两个备选方案。该示例需要一个具有与CHARS_PER_LINE *行对应的字符数量的文件。如果您在没有任何参数的情况下运行该程序,它将尝试使用getc()将文件复制到内存中,否则如果传递了任何数量的参数,它将运行fget()版本。
#include <stdio.h>
#include <stdlib.h>
#define CHARS_PER_LINE 2000
#define LINES 100
int main (int argc, char *argv[]) {
// DECLARE VARS
char **data;
FILE *fp;
// ALLOCATE 2D ARRAY MEMORY
data = malloc(LINES * sizeof(char*));
for (int i = 0; i < CHARS_PER_LINE; i++) {
data[i] = malloc(CHARS_PER_LINE * sizeof(char));
}
// OPEN FILE FOR READING
fp = fopen ("file.txt", "r");
// COPY CHARS WITH GETC()
if (argc == 1) { // if no arguments - getc
for (int i = 0; i < LINES; i++) {
for (int ii = 0; ii < CHARS_PER_LINE; ii++) {
data[i][ii] = getc(fp);
}
}
}
// COPY CHARS WITH FGETS()
else { // if any amount of arguments passed - fgets
for (int i = 0; i < LINES; i++) {
fgets(data[i], (CHARS_PER_LINE + 1), fp);
// does fgets not have a buffer limit?
}
}
// CLOSE FILE
fclose(fp);
return(0);
}我意识到这是不好的和不安全的,并且做了很多假设,但是我试图把重点放在使代码类似,以便能够公平地测试它。从逻辑上讲,假设getc在每次迭代获取的字符数较低的情况下优于fget,对于大量数据,fget的性能将优于getc。问题仍然存在--以多少和以何种速度?
希望我们能用一些困难的数字来总结这个永恒的问题,请帮助。
发布于 2022-01-03 20:04:19
好的,我决定帮助自己,所以我想出了一个基准测试的方法,我敢打赌,在最初的问题上,我得到的批评肯定比我得到的更多。
这是完整的代码。您可以通过搜索“随机文件生成器”获得带有随机字符的文件。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define CHARS_PER_LINE 2000
#define LINES 100
int main (int argc, char *argv[]) {
// DECLARE VARS
char **data;
FILE *fp1;
FILE *fp2;
clock_t time_before, time_after;
double time1, time2;
char check1, check2;
// ALLOCATE 2D ARRAY MEMORY
data = malloc(LINES * sizeof(char*));
for (int i = 0; i < CHARS_PER_LINE; i++) {
data[i] = malloc(CHARS_PER_LINE * sizeof(char));
}
if (argc == 3) {
// OPEN FILE 1 FOR READING
fp1 = fopen (argv[1], "r");
// COPY CHARS WITH GETC()
time_before = clock();
for (int i = 0; i < LINES; i++) {
for (int ii = 0; ii < CHARS_PER_LINE; ii++) {
data[i][ii] = getc(fp1);
}
}
time_after = clock();
time1 = (double)(time_after - time_before);
check1 = data[50][1495];
// CLOSE FILE 1
fclose(fp1);
// OPEN FILE 2 FOR READING
fp2 = fopen (argv[2], "r");
// COPY CHARS WITH FGETS()
time_before = clock();
for (int i = 0; i < LINES; i++) {
fgets(data[i], CHARS_PER_LINE, fp2);
}
time_after = clock();
time2 = (double)(time_after - time_before);
check2 = data[50][1495];
// CLOSE FILE 2
fclose(fp2);
// PRINT RESULTS
// appended characters to check for consistency amd accuracy of reads
printf("%s: %f\t%s: %f\t%c%c\n", argv[1], time1, argv[2], time2, check1, check2);
}
else {
puts("Wrong number of args. Put names of 2 files as arguments.");
}
return(0);
}产出如下:
a.txt: 1169.000000 b.txt: 95.000000 vp
b.txt: 826.000000 a.txt: 67.000000 be
a.txt: 1146.000000 b.txt: 91.000000 vp
b.txt: 1139.000000 a.txt: 89.000000 be
a.txt: 821.000000 b.txt: 77.000000 vp
b.txt: 1069.000000 a.txt: 91.000000 be
a.txt: 1141.000000 b.txt: 91.000000 vp
b.txt: 822.000000 a.txt: 70.000000 be
a.txt: 776.000000 b.txt: 68.000000 vp
b.txt: 996.000000 a.txt: 90.000000 be
a.txt: 1143.000000 b.txt: 92.000000 vp
b.txt: 1141.000000 a.txt: 93.000000 be
a.txt: 1138.000000 b.txt: 92.000000 vp
b.txt: 1140.000000 a.txt: 92.000000 be如您所见,绝大多数人赞成fget()。就像,一个数量级。大约11到12次。
如果你对此有任何有用的具体评论,或者如果你屈尊确认或否认这一研究,请这样做。
我现在能拿到金子了吗?
发布于 2022-01-03 20:16:04
从你的问题和答案来看:
在我的例子中,我正在阅读已知长度的整行
如果文件具有这样简单的结构(相同的行长)
最快的是-
// ALLOCATE 2D ARRAY MEMORY
char (*data)[CHAR_PERLINE] = malloc(LINES * sizeof(*data);
if(fread(data, sizeof(*data), LINES, fpx) != LINES * sizeof(*data))
{
/* Something gone wrong, do something. */
}但行将不会以空字符结尾。
编辑
由于您不了解上面的代码,所以现在有了整个代码:
int main (int argc, char *argv[]) {
// DECLARE VARS
FILE *fp1;
FILE *fp2;
clock_t time_before, time_after;
double time1, time2;
char check1, check2;
// ALLOCATE 2D ARRAY MEMORY
char (*data)[CHARS_PER_LINE] = malloc(LINES * sizeof(*data));
if (argc == 3) {
// OPEN FILE 1 FOR READING
fp1 = fopen (argv[1], "r");
// COPY CHARS WITH GETC()
time_before = clock();
fread(data, sizeof(*data), LINES, fp1) != LINES * sizeof(*data));
time_after = clock();
time1 = (double)(time_after - time_before);
check1 = data[50][1495];
// CLOSE FILE 1
fclose(fp1);
// OPEN FILE 2 FOR READING
fp2 = fopen (argv[2], "r");
// COPY CHARS WITH FGETS()
time_before = clock();
for (int i = 0; i < LINES; i++) {
fgets(data[i], CHARS_PER_LINE, fp2);
}
time_after = clock();
time2 = (double)(time_after - time_before);
check2 = data[50][1495];
// CLOSE FILE 2
fclose(fp2);
// PRINT RESULTS
// appended characters to check for consistency amd accuracy of reads
printf("%s: %f\t%s: %f\t%c%c\n", argv[1], time1, argv[2], time2, check1, check2);
}
else {
puts("Wrong number of args. Put names of 2 files as arguments.");
}
return(0);
}https://stackoverflow.com/questions/70568605
复制相似问题