Как эффективно читать новые целые числа с разделителями строк в C ++? - PullRequest
1 голос
/ 14 декабря 2011

Мне нужно прочитать большой список целых чисел из файла, но максимально эффективно с точки зрения времени.Целые числа разделены новой строкой.Я предполагаю, что чтение одного целого числа за один раз с использованием cin вызовет очень частые чтения.

Полагаю, что чтение целых чисел за один раз ускорит это!Но как это сделать?

Редактировать: я использовал файл, который перенаправлен на стандартный ввод.Итак, я читал целые числа, используя cin.

Ответы [ 3 ]

2 голосов
/ 14 декабря 2011

Вы можете попробовать этот код, используя stl

std::ifstream myFile("TheNameOfYourFile");
std::list<int> myList;

int number;
while (myFile >> number)
{
    myList.push_back(number);
}
2 голосов
/ 14 декабря 2011

С аппаратной точки зрения вы не можете просто прочитать несколько байтов - вы читаете весь сектор в память, а следующие сектора буферизуются, пока вы читаете их, используя fstream (я думаю, вы думали о fstream, когда писали cin...).

Однако вы можете сделать это так, как это делают примеры Boost :: Spirit - IDK, если он быстрее с точки зрения буферизации;вероятно, это так же быстро, как и обычное чтение, из-за аппаратной точки зрения, которую я объяснил.Однако для получения содержимого файла в stringstream вместо string потребуется некоторая настройка.

http://www.boost.org/doc/libs/1_48_0/libs/spirit/example/lex/example.hpp

1 голос
/ 14 декабря 2011

Если вам нужна лучшая производительность:

  1. Анализ целых чисел из строк ASCII выполняется медленнее, чем чтение двоичных данных.
  2. iostream IO намного медленнее, чем stdio.h IO.

Чтобы прочитать nitems целые числа из двоичного файла / stdin в массив:

#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("%d\n", *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 array\n";
    return 1;
  }
}

Недостатком является то, что он не является переносимым: sizeof(int) и / или endianess, выравнивание может быть различным в разных ОС.

Пример

Преобразовать в целые числа двоичного формата, хранящиеся в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

Выше предполагается, что вам нужно читать целые числа из файла много раз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...