C 快速读取文件

C 快速读取文件,c,input,graph,text-files,C,Input,Graph,Text Files,我有一个txt文件,其中包含2个图形和以下格式的顶点数: 6 0 1 0 1 0 0 1 0 1 0 0 1 0 1 0 1 0 0 1 0 1 0 1 0 0 0 0 1 0 1 0 1 0 0 1 0 0 1 0 0 1 0 1 0 1 0 0 0 0 1 0 1 0 1 0 0 1 0 1 0 1 0 0 1 0 1 0 0 1 0 1 0 矩阵表示垂直邻接。如果两个顶点相邻,则其对为1。 尽管这些图形没有在视觉上分开,但第二个图形在第一个图形的第6行之后开始。 每个图可以有很多顶点,比

我有一个txt文件,其中包含2个图形和以下格式的顶点数:

6
0 1 0 1 0 0
1 0 1 0 0 1
0 1 0 1 0 0
1 0 1 0 1 0
0 0 0 1 0 1
0 1 0 0 1 0
0 1 0 0 1 0
1 0 1 0 0 0
0 1 0 1 0 1
0 0 1 0 1 0
1 0 0 1 0 1
0 0 1 0 1 0
矩阵表示垂直邻接。如果两个顶点相邻,则其对为1。 尽管这些图形没有在视觉上分开,但第二个图形在第一个图形的第6行之后开始。 每个图可以有很多顶点,比如5000个,它们的大小都相同(图)。 我写了一个算法来检查两个图是否同构,我注意到读取这些图需要8秒,而实际的算法需要2.5秒(对于5000个顶点)。 由于我的目标是优化程序的总体速度,我想知道我是否可以提高(速度方面)当前读取文件的代码:

FILE* file = fopen ("input.txt", "r");
fscanf (file, "%d", &i);
int n = i;
while (!feof (file))
{  
    fscanf (file, "%d", &i); 
    if (j < (n*n)) {  // first graph
        if (i==1) {
            adj_1[j/n][v_rank_1[j/n]] = j - (j/n)*n; // add the vertice to the adjacents of the current vertice
            v_rank_1[j/n] += 1;
        }
    }
    else if (j>=(n*n)) {   // second graph
        if (i==1) {
            adj_2[(j-(n*n))/n][v_rank_2[(j-(n*n))/n]] = (j-(n*n)) - ((j-(n*n))/n)*n; // add the vertice to the adjacents of the current vertice
            v_rank_2[(j-(n*n))/n] += 1;
        }
    }
    j++;
}
fclose (file);
FILE*FILE=fopen(“input.txt”、“r”);
fscanf(文件“%d”和&i);
int n=i;
而(!feof(文件))
{  
fscanf(文件“%d”和&i);
如果(j<(n*n)){//第一个图
如果(i==1){
adj_1[j/n][v_rank_1[j/n]]=j-(j/n)*n;//将垂直添加到当前垂直的相邻位置
v_秩_1[j/n]+=1;
}
}
如果(j>=(n*n)){//第二个图
如果(i==1){
adj_2[(j-(n*n))/n][v_rank_2[(j-(n*n))/n]]=(j-(n*n))-((j-(n*n))/n)*n;//将垂直添加到当前垂直的相邻位置
v_秩_2[(j-(n*n))/n]+=1;
}
}
j++;
}
fclose(文件);
adj.*
表保存垂直点相邻顶点的索引

v\u rank.*
表包含与顶点相邻的顶点数


重要的是,我要从图表中获取这些信息,并且只获取这些信息。

您可以通过减少访问文件系统的次数来加快速度。每次从文件中读取一个整数,因此每次通过循环访问该文件


相反,尝试一次读取整个文件或文件的一大块。(这称为块读取)。可以将其缓冲到数组中。在循环中,从内存缓冲区而不是文件中读取。如果不读取整个文件,请根据需要在循环中刷新内存缓冲区。

您可以通过减少访问文件系统的频率来提高速度。每次从文件中读取一个整数,因此每次通过循环访问该文件

相反,尝试一次读取整个文件或文件的一大块。(这称为块读取)。可以将其缓冲到数组中。在循环中,从内存缓冲区而不是文件中读取。如果不读取整个文件,请根据需要在循环中刷新内存缓冲区。

用于一次将一行读取到行缓冲区中。将行缓冲区解析为整数值

此函数可减少从文件中读取的次数,因为在幕后,
fgets()
从文件中读取大量数据,并一次返回一行。只有当内部缓冲区中没有多余的行时,它才会尝试读取另一个块。

用于一次将一行读取到行缓冲区中。将行缓冲区解析为整数值


此函数可减少从文件中读取的次数,因为在幕后,
fgets()
从文件中读取大量数据,并一次返回一行。它只在内部缓冲区中没有多余的行时才尝试读取另一个块。

第一个优化是一次性读取内存中的整个文件。在循环中访问内存将比调用fread更快

第二个优化是做更少的算术运算,即使这意味着更多的代码

第三个优化是将文件中的数据作为字符处理,以避免整数转换

结果可能是:

// bulk read file into memory
fseek(file, 0, SEEK_END);
long fsize = ftell(file);
fseek(file, 0, SEEK_SET);
char *memFile = malloc(fsize + 1);
if (memFile == NULL) return; // not enough memory !! Handle it as you wish
fscanf(file, "%d", &n);
fread(memFile, fsize, 1, file);
fclose(file);
memfile[fsize] = 0;

// more code but less arythmetic operations
int lig, col;
char *mem = memFile, c;
for (int lig = 0; lig < n; lig++) { // first graph
    for (int col = 0; col < n; col++) {
        for (;;)
        {
            c = *mem;
            if (c == 0) break;
            mem++;
            if (c == '1') {
                adj_1[lig][v_rank_1[lig]++] = col; // add the vertice to the adjacents of the current vertice
                k++; // ??
                break;
            }
            if (c == '0') break;
        }

    }
}
for (int lig = 0; lig < n; lig++) { // second graph
    for (int col = 0; col < n; col++) {
            c = *mem;
            if (c == 0) break;
            mem++;
            if (c == '1') {
                adj_2[(lig][v_rank_2[lig]++] = col; // add the vertice to the adjacents of the current vertice
                l++;  // ??
                break;
            }
            if (c == '0') break;
        }
    }
}
free(memFile);
//将文件大容量读取到内存中
fseek(文件,0,SEEK_END);
长fsize=ftell(文件);
fseek(文件,0,搜索集);
char*memFile=malloc(fsize+1);
if(memFile==NULL)返回;//内存不足!!随你的便
fscanf(文件“%d”和(&n);
fread(memFile,fsize,1,file);
fclose(文件);
memfile[fsize]=0;
//代码多,算术运算少
国际法,哥伦比亚;
char*mem=memFile,c;
对于(int-lig=0;lig

备注:您没有提到变量
k
l

第一个优化是一次性读取内存中的整个文件。在循环中访问内存将比调用fread更快

第二个优化是做更少的算术运算,即使这意味着更多的代码

第三个优化是将文件中的数据作为字符处理,以避免整数转换

结果可能是:

// bulk read file into memory
fseek(file, 0, SEEK_END);
long fsize = ftell(file);
fseek(file, 0, SEEK_SET);
char *memFile = malloc(fsize + 1);
if (memFile == NULL) return; // not enough memory !! Handle it as you wish
fscanf(file, "%d", &n);
fread(memFile, fsize, 1, file);
fclose(file);
memfile[fsize] = 0;

// more code but less arythmetic operations
int lig, col;
char *mem = memFile, c;
for (int lig = 0; lig < n; lig++) { // first graph
    for (int col = 0; col < n; col++) {
        for (;;)
        {
            c = *mem;
            if (c == 0) break;
            mem++;
            if (c == '1') {
                adj_1[lig][v_rank_1[lig]++] = col; // add the vertice to the adjacents of the current vertice
                k++; // ??
                break;
            }
            if (c == '0') break;
        }

    }
}
for (int lig = 0; lig < n; lig++) { // second graph
    for (int col = 0; col < n; col++) {
            c = *mem;
            if (c == 0) break;
            mem++;
            if (c == '1') {
                adj_2[(lig][v_rank_2[lig]++] = col; // add the vertice to the adjacents of the current vertice
                l++;  // ??
                break;
            }
            if (c == '0') break;
        }
    }
}
free(memFile);
//将文件大容量读取到内存中
fseek(文件,0,SEEK_END);
长fsize=ftell(文件);
fseek(文件,0,搜索集);
char*memFile=malloc(fsize+1);
if(memFile==NULL)return;//内存不足!!可以随意处理
fscanf(文件“%d”和(&n);
fread(memFile,fsize,1,file);
fclose(文件);
memfile[fsize]=0;
//代码多,算术运算少
国际法,哥伦比亚;
char*mem=memFile,c;
对于(int-lig=0;lig