Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
fopen、fclose的效率_C_Performance_For Loop_Io_Fopen - Fatal编程技术网

fopen、fclose的效率

fopen、fclose的效率,c,performance,for-loop,io,fopen,C,Performance,For Loop,Io,Fopen,如果在嵌套的for循环中迭代写入文件,那么在循环之前打开文件,在循环之后关闭文件,而不是在循环中打开和关闭文件,在效率上是否有任何区别?见下文: int main(){ FILE *file1; char filename; int i, j, N, M; for(i=0; i<N; i++){ file1=fopen(filename, "a"); for(j=0; j<M; j++){ fp

如果在嵌套的for循环中迭代写入文件,那么在循环之前打开文件,在循环之后关闭文件,而不是在循环中打开和关闭文件,在效率上是否有任何区别?见下文:

int main(){
    FILE *file1;
    char filename;
    int i, j, N, M;

    for(i=0; i<N; i++){
        file1=fopen(filename, "a");
        for(j=0; j<M; j++){
            fprintf(file1,"%d %d\n", i, j);
        }
        fclose(file1);
    }
return 1;
}
intmain(){
文件*file1;
字符文件名;
int i,j,N,M;

对于(i=0;iYes),存在差异。fopen()和fclose()映射到open()和close()上系统调用,它需要一个中断来触发一个上下文切换来运行内核代码。

我做了一个快速的基准测试,看看是否有显著的差异。代码与您的代码略有不同,但它仍然显示出效率上的差异。另外,我没有考虑缓存等

你可以自己看看这是否重要

测试程序:

#include <stdio.h>
#include <stdlib.h>


#ifdef TEST1
void test(char *filename, int n) {
    int i;
    FILE *fp;

    for (i=0; i<n; i++) {
        fp = fopen(filename, "a");
        if (fp) {
            fprintf(fp, "%d\n", i);
            fclose(fp);
        }
    }
}
#else
void test(char *filename, int n) {
    int i;
    FILE *fp;

    fp = fopen(filename, "a");
    if (!fp)
        return;

    for (i=0; i<n; i++) {
        fprintf(fp, "%d\n", i);
    }

    fclose(fp);
}
#endif

int main(int argc, char *argv[]) {
    char *filename;
    int n;

    if (argc < 3)
        return -1;

    filename = argv[1];
    n = atoi(argv[2]);

    test(filename, n);

    return 0;
}
这台机器是2.2GHz核心i7,8GB内存,运行OS X

结果是:

   n   |  test1  |  test2
-------+---------+---------
10     | 0.009s  | 0.006s
100    | 0.036s  | 0.006s
1000   | 0.340s  | 0.007s
10000  | 2.535s  | 0.011s
100000 | 24.509s | 0.041s
总之,有区别吗?是的

是否存在显著差异?是的,但仅适用于大量迭代

这有关系吗?这取决于你计划进行多少次迭代?在大约1000次迭代之前,用户不太可能注意到这种差异。任何更高的东西,你都会开始看到两种不同实现在运行时间上的一些显著差异


归根结底,如果您可以不费吹灰之力地高效编码,为什么还要故意使用效率较低的算法呢?

如果您关心性能,您可能不想执行额外的打开和关闭操作。但是如果您非常关心避免数据丢失,那么您可能希望打开以进行追加、写入和关闭例如,如果您要添加一个调试打印模块,您可能不太关心性能,而只关心保持每一位输出

例如:

void debug_print(char *debug_string)
{
  struct timespec *now;
  int success = clock_gettime(CLOCK_REALTIME, &now);
  /* We ignore errors in the file I/O, because if we can't write to the debug file we have no place to report the problem. */
  FILE *f = fopen("debug.text", "a");
  if (success) {
    fwrite(f, "time %d.%9d: %s\n", now.tv_sec, now.tv_nsec, debug_string);
  } else {
    fwrite(f, "time errno=%d: %s\n", errno, debug_string);
  }
  fclose(f);
}

为什么不对它进行基准测试并自己找出答案?为什么有人会使用第一个代码段?好吧,在第一种情况下,您要做更多的工作,所以需要更长的时间。无论它是否对实时性产生影响,您只能使用基准测试来找出答案。保持文件打开通常更有效,因为缓冲区和缓存可以刷新当你关闭文件时,它会自动关闭。但是,如果你担心在崩溃或电源故障的情况下丢失数据,那么你可能需要采取更具防御性的方法,反复打开和关闭文件。@PaulR你不想让文件系统或操作系统更好地处理电源故障吗?我也考虑过这一点,但在发生故障的情况下
fprintf
,文件仍然以任何方式打开。使用缓存和all,即使文件已关闭,也可能不会向磁盘写入任何内容。-1.系统调用的触发方式完全取决于体系结构。使用中断是启动系统调用的多种方法之一。True。我暗指的是Linux x86。我的错。在操作系统设计术语中,任何这样的内核条目都被称为“中断”,而不仅仅是使用相同机制的硬件中断和软件中断。“中断”过载过多,IMHO.Java等又增加了一个过载,这个术语现在产生了很多混乱;(我所说的中断是指x86上触发同步中断的int汇编指令。
   n   |  test1  |  test2
-------+---------+---------
10     | 0.009s  | 0.006s
100    | 0.036s  | 0.006s
1000   | 0.340s  | 0.007s
10000  | 2.535s  | 0.011s
100000 | 24.509s | 0.041s
void debug_print(char *debug_string)
{
  struct timespec *now;
  int success = clock_gettime(CLOCK_REALTIME, &now);
  /* We ignore errors in the file I/O, because if we can't write to the debug file we have no place to report the problem. */
  FILE *f = fopen("debug.text", "a");
  if (success) {
    fwrite(f, "time %d.%9d: %s\n", now.tv_sec, now.tv_nsec, debug_string);
  } else {
    fwrite(f, "time errno=%d: %s\n", errno, debug_string);
  }
  fclose(f);
}