【发布时间】:2015-01-14 20:13:46
【问题描述】:
fopen 和 fclose 在 "w" 模式下打开时是否比 "a" 模式下在以下情况下花费更多时间 1.文件已经存在 2. 没有文件存在 以下内容 日志文件 = fopen(log,"a"); 和 logFile = fopen(log,"w");
我有以下代码,我对它进行了快速 strace 分析,以获取每个系统调用的时钟周期,而在测试开始时没有文件存在。
代码
int main(int argc, char **argv)
{
const char* log = "log.txt";
FILE* logFile = NULL;
char timeBuf[100];
time_t now;
struct tm *logtime1;
time(&now);
logtime1 = localtime(&now);
strftime(timeBuf,sizeof(timeBuf),"[%Y-%m-%d %H:%M:%S]",logtime1);
int i;
char *inMessage = "The Quick Brown Fox Jumps Over The Lazy Dog";
for(i=0;i<50000;i++)
{
logFile = fopen(log,"a"); //or **logFile = fopen(log,"w");**
if(logFile != NULL)
{
fflush( 0 );
int error = 0;
fprintf(logFile, "%s\t%s %d at (%s:%d)\n",timeBuf,
inMessage, error,__FILE__, __LINE__);
fclose(logFile);
}
}
return 0;
}
当我以“w”模式打开文件时,strace 分析显示在打开系统调用中需要更多时间。这背后有什么原因吗?
以下是两个配置文件
-
--------- 使用“w”模式跟踪代码
strace -c ./test.out -o 报告
% time seconds usecs/call calls errors syscal
76.17 0.522555 10 50006 打开
12.13 0.083197 2 50006 关闭
4.61 0.031626 1 50000 写入
3.96 0.027151 1 50002 munmap
1.57 0.010737 0 50017 映射
1.55 0.010663 0 50007 fstat
100.00 0.686068 300060 共 1 个
- 使用“a”模式跟踪代码
--------- strace -c ./test.out -o 报告
% time seconds usecs/call 调用错误 syscall
22.08 0.020467 0 50002 munmap
20.24 0.018763 0 50000 写入
16.76 0.015542 0 100007 fstat
13.43 0.012450 0 50006 打开
9.90 0.009177 0 50006 关闭
9.44 0.008756 0 50017 映射
8.15 0.007558 0 50001 lseek
100.00 0.092713 400060 共 1 个
【问题讨论】:
-
w将截断您正在打开的文件。如果它是一个“大”文件,操作系统需要一段时间才能清理干净。 -
我认为打开文件的性能更多地取决于操作系统的实现,因为它是一个系统调用。
-
有意义的是,在“w”模式下截断文件将占用操作系统一些周期(取决于实现)。谢谢
-
您要测量的内容很大程度上取决于实施; “a”和“w”做不同的事情不一定可比。并考虑在对程序进行计时时,应在不同条件下重复多次测量:考虑操作系统需要时间在磁盘中查找文件,但后续访问会更快,因为缓存信息甚至磁盘磁头更接近文件内容。也就是说,从冷启动运行的第一个程序最终会支付 I/O 开销,并且比第二个程序花费更长的时间。
-
我同意你的看法,但只是为了让你知道我对这两种实现进行了多次分析,结果相似。此外,我认为代码运行了 50000 次迭代,我可以忽略两种实现的初始 I/O 开销。我不能吗?