【问题标题】:Memory and time issue when reading/writing from a file从文件读取/写入时的内存和时间问题
【发布时间】:2019-05-25 11:15:03
【问题描述】:

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

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

输入文件示例: 3 狗

输出文件示例狗 狗 狗

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

时间限制: 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; 
}

【问题讨论】:

  • cincout 不是文件流的好名称。它们很容易与std::cinstd::cout 混淆,尤其是当您使用邪恶的using namespace std 时。
  • 您为什么选择1000005 作为char 数组的大小?为什么它是一个char 数组?
  • 请注意,cin &gt;&gt; s 会在任何空白处停止。如果您想读取任意字符串(文件末尾或第一个换行符),请使用其他内容。另外,我无法重现您的问题。在我的桌面上(在 x86-64 Arch Linux 上使用 g++ -O3 编译,与 glibc / libstdc++ 链接)它在 0.029 秒内运行 50 次 ~500kB 输入。我使用(echo '50'; seq 100000 | tr -d '\n' ) &gt; afisaren.in/tmp(tmpfs ramdisk)中创建输入文件,wc afisaren.* 显示1 2 488898 afisaren.in50 50 24444800 afisaren.outstrace ./a.out 显示它使用了 50 倍 writev

标签: c++ file memory benchmarking file-read


【解决方案1】:

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

首先,不要使用预先分配的字符数组。您正在使用 C++!为什么不简单地将文本读入std::(w)string 或任何将进行动态内存分配的 C++ 类(如果行长确实超过 1,000,000,也不会导致程序崩溃)。

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

由于最大重复次数为 1

【讨论】:

  • “其次,c++ std::streams 通常在每次写入行尾字符时都会执行刷新到磁盘” 这是不正确的。底层操作系统的设备可能会这样做(尽管它不应该这样做),但 C++ 不会。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2015-09-17
    • 1970-01-01
    • 1970-01-01
    • 2012-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多