从文件读取/写入时出现内存和时间问题

Memory and time issue when reading/writing from a file

本文关键字:内存 时间 问题 读取 文件      更新时间:2023-10-16

我正在努力解决一个学校的问题,我做到了,但如果可能的话,它应该运行得更快,内存更少-你能帮我实现吗?

问题语句:从文件中读取自然数N和字符串,并在另一个文件中输出相同的字符串N次。

输入文件示例:3.狗

输出文件示例狗狗狗

限制:1≤n≤50,并且要读取的行的长度最大为1000000

时间限制:0.27秒

这是我尝试过的(但运行时间超过了限制):

#include<fstream>
using namespace std;
ifstream cin("afisaren.in"); 
ofstream cout("afisaren.out");
short n; 
char s[1000005];
int main() {
cin >> n;
cin >> s;
while(n) {
cout << s << 'n';
n--;
}
cin.close();
cout.close();
return 0; 
}

通常,当遇到这种类型的问题时,您应该评测自己的代码,以查看代码的哪一部分消耗了多少时间。这主要可以通过在代码执行前后向计时函数添加一些调用来完成,以查看它执行了多长时间。然而,这对代码来说并不容易,因为最大的问题之一(优化方面)是char s[1000005];行。内存将在执行main()函数之前分配,该函数依赖于操作系统(或者更确切地说,取决于使用的libc和编译器)。

因此,首先,不要使用预先分配的char数组。您正在使用C++!为什么不简单地将文本读取到std::(w)string或任何C++类中,这些类将进行动态内存分配(如果行长度超过1000000,则不会使程序崩溃)。

其次,每次写入行尾字符时,c++std::流通常都会执行对磁盘的刷新。除非文本的大小与底层文件系统的块大小完全相同,否则效率非常低。要优化此功能,请创建一个内存对象(即std::string),并将文本复制到其中k次,其中k=fs块大小/文本长度。fs块大小很可能是1024、2048或4096字节。有系统调用可以发现这一点,但在写入两倍(或4倍)fs块大小时,性能通常不会受到太大影响,因此可以放心地假设其为4096,以接近或达到最大性能。

由于最大重复次数是1<n<50,并且行长度为1000000(如果ASCII,则约为1MIB),输出的最大文件大小将为50000000个字符。您还可以将所有内容写入内存,然后在一次对write()的调用中写入所有内容。就磁盘活动而言,这可能是最有效的方法,但显然与内存消耗无关。

我不是c++专家,但我在使用c++风格的文件流时也遇到了类似的问题,在谷歌上搜索了一下后,我尝试切换到c-风格文件系统,这大大提高了我的性能,因为c++文件流将文件内容复制到内部缓冲区中,这需要时间,你可以尝试c-风格,但通常不建议在c++中使用c。