如何在c++中有效地读取新行分隔的整数

How to read new line separated integers efficiently in C++?

本文关键字:新行 分隔 整数 读取 有效地 c++      更新时间:2023-10-16

我需要从文件中读取一个大的整数列表,但在时间方面尽可能高效。整数用换行符分隔。我猜使用cin一次读取一个整数会导致非常频繁的读取。

我猜一次读取多个整数会加快速度!但是怎么做呢?

编辑:我使用了重定向到stdin的文件。所以我用cin读取整数

您可以使用stl

来尝试此代码
std::ifstream myFile("TheNameOfYourFile");
std::list<int> myList;
int number;
while (myFile >> number)
{
    myList.push_back(number);
}

从硬件的角度来看,你不能只读取几个字节-你读取整个扇区到内存中,下一个扇区是缓冲的,而你使用fstream读取它们(我猜你在写cin时正在考虑fstream…)。

但是,你可以像Boost::Spirit示例那样做——IDK,如果它在缓冲方面更快;我解释说,由于硬件的原因,它可能和正常读取一样快。不过,需要进行一些调整才能将文件的内容放入stringstream而不是string。 http://www.boost.org/doc/libs/1_48_0/libs/spirit/example/lex/example.hpp

如果您需要最佳性能:

  1. 从ASCII字符串解析整数比读取二进制数据慢。
  2. iostream IO比stdio.h IO慢得多。

从二进制文件/stdin中读取nitems整数到数组中:

#include <stdio.h>
#include <stdlib.h>
int main() {
  // first read number of integers in the array
  size_t nitems = -1;
  if (fread(&nitems, sizeof(nitems), 1, stdin) != 1) {
    perror("nitems");
    exit(EXIT_FAILURE);
  }
  // allocate memory for the array
  int *arr = (int*) malloc(nitems*sizeof(*arr));
  if (arr == NULL) {
    perror("malloc");
    exit(EXIT_FAILURE);
  }
  // read integers
  size_t n = fread(arr, sizeof(*arr), nitems, stdin);
  if (n != nitems) {
    perror("fread");
    exit(EXIT_FAILURE);
  }
  // do something with `arr` here
  for (int* a = arr; a != &arr[nitems]; ++a)
    printf("%dn", *a);
  exit(EXIT_SUCCESS);
}

将行分隔的整数转换为有效的二进制格式:

#include <cstdio>
#include <iostream>
#include <vector>
int main() {
  using namespace std;
  // read integers from ascii file/stdin
  int i = -1;
  vector<int> v;
  while (cin >> i) v.push_back(i);
  if (v.size() == 0) return 2;
  // write the array in binary format
  size_t nmemb = v.size();
  if (fwrite(&nmemb, sizeof(nmemb), 1, stdout) != 1 || 
      fwrite(&v[0], sizeof(v[0]), nmemb, stdout) != nmemb) {
    cerr << "failed to write the arrayn";
    return 1;
  }
}

缺点是不可移植:sizeof(int)和/或尾端对齐在不同的操作系统上可能不同。

例子

转换成二进制格式的整数存储在array.txt:

$ g++ convert-to-bin.cc -o convert-to-bin && 
  < array.txt ./convert-to-bin >array.bin

之后,你可以有效地从array.bin中读取整数:

 $ g++ read-integer-array.cc -o read-integer-array &&
   < array.bin ./read-integer-array

以上假设需要多次从文件中读取整数。