【问题标题】:How to speed up reading lines from stream to memory?如何加快从流到内存的读取行?
【发布时间】:2014-09-20 17:39:12
【问题描述】:

我在输入流中有大约1E6 行(来自键盘)。以下是我的阅读方式:

int main () {
  ul n, in;
  scanf("%lu", &n);

  ul *a = new ul[n];

  while(n--){
    scanf("%lu", a+n);
  }

n 是要读取的行数。 ulunsigned long 我在其他地方定义的。

为了澄清,数据是一串整数 (1E9),由键盘输入流中的换行符 (\n) 分隔。

这种方法可以完成工作,但我想加快速度。 我曾考虑过使用缓冲区将整个流读取到内存并进行解析,但我不知道如何使用 C++ 11。

我使用stdio.h 来读取流,因为它似乎比 C++ 流读取器更快。否则,我更喜欢 C++ 11 解决方案。

【问题讨论】:

  • “因为它似乎比 C++ 流阅读器更快”——它不是,这是一个难以消除的神话。 C 和 C++ 流几乎完全一样,理论上 C++ 流可以更快(尽管我知道没有实现可靠的情况)。
  • 嗯,让我们看看。一百万个整数还不错。作为文本,它可能是几十兆。如今,它很容易装入 RAM。您可以使用std::istreambuf_iterators 初始化std::string,以便将整个文件读入内存。
  • @TheParamagneticCroissant 这不会是最快的解决方案。最快的解决方案可能是mmap
  • @JamesKanze 可能最快的解决方案而不是猜测将是先完成它最简单的方法,检查性能是否可以接受,只有在不可以的情况下才想知道优化,最好使用分析器。
  • @BartoszKP 这当然是正确的方法;最后,您需要的不是最快的解决方案,而是足够快的解决方案。从经验来看,使用mmap 可以提高性能,在必要时并且正确地完成并不是很困难。但是当然,你应该只删除ifstream如果你显然有性能问题。 (这样做时,您应该验证是否是由于转换(某些实现不是很好)或数据通过放置;mmap 仅对后者有帮助。)

标签: c++ performance c++11 input stream


【解决方案1】:

我认为您可以通过编辑 while 循环稍微提高性能。

由于数字小于 1e9,因此您可以读取 int,而不是 uns。长。 在下面的代码中,我通过 getc 读取每个字符并将其转换为自己的数字。
注意 current_number 是 int
为了使代码正常工作,您必须修改您的第一个 scanf("%lu", &n); 通过阅读 '\n' 以及,即您的第一个 scanf 将是 scanf("%lu\n", &n);

while (n--) {
    int c = getc(stdin);
    int current_number = 0;
    do {
        current_number = (current_number << 1) + (current_number << 3) + (c - 48);
        c = getc(stdin);
    } while (c >= 48 && c <= 57);
    a[n] = current_number;
}

scanf 函数在大数据上的运行速度比 getc 慢。
(current_number 等价于 current_number * 10 ,但我认为没有必要。现代编译器能够找出计算小操作的最佳方法。
祝你好运

【讨论】:

    猜你喜欢
    • 2012-05-13
    • 2015-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-26
    • 2016-06-30
    • 1970-01-01
    相关资源
    最近更新 更多