как читать из большого текстового файла в массив с ++

0

Я пытаюсь прочитать из очень большого текстового файла с двумя столбцами, это веб-граф, что-то вроде этого: (кроме 40 миллионов строк).

1 2

1 3

2 1...

поэтому я хотел прочитать из txt файла в myArray [mysize] [2], и я использовал код:

ifstream file("web-graph.txt");
if(file.is_open())
{
    for(int i = 0; i < mysize; i++)
    {
        file >> myArray[i][0];          
        file >> myArray[i][1];
    }
}

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

  • 0
    На какой операционной системе? С каким компилятором? Как вы скомпилировали свой код (с какими флагами оптимизации)? Рассматривали ли вы использование простого C с <stdio.h> (в некоторых системах это может быть немного быстрее). Ваш код работает намного медленнее, чем, например, утилита wc (count)?
  • 0
    Просто предложение: если ваши данные не нуждаются в хранении в непрерывном блоке памяти (например, в пуле памяти), избегайте использования массива и используйте вместо него вектор .
Показать ещё 7 комментариев
Теги:
arrays
file

2 ответа

0

Да, вы определенно делаете это медленным (но красивым) способом. У вас есть 2 варианта быстрее:

если (у вас достаточно памяти) { Прочитайте весь файл в памяти и затем проанализируйте файл }

else { Прочитайте большие куски файла за раз в памяти, а затем проанализируйте файл }

В любом случае, загрузка выглядит примерно так...

std::ifstream is(filename);
is.seekg(0, std::ios::end);
auto length = is.tellg();

std::string buffer;

if(length > 0)
{
    buffer.resize(static_cast<std::string::size_type>(length));
    is.seekg(0);
    is.read(&buffer.front(), length);
}

И тогда вы поместите его в строковый поток...

std::stringstream ss(buffer);

и проанализировать его, потенциально точно, как вы делали это раньше...

for(int i = 0; i < mysize; i++)
{
    ss >> myArray[i][0];          
    ss >> myArray[i][1];
}
  • 1
    Но std::ifstream буферизуется, поэтому в любом случае регистр "else" используется по умолчанию.
  • 1
    @JoachimPileborg Это деталь реализации. По своему опыту, по крайней мере в Windows, я могу сказать, что какая бы буферизация в ней ни была, она недостаточно хороша, если вы собираетесь выполнять так много операций чтения. Я уже не раз получал на порядок лучше производительность при явном чтении больших кусков, чем при использовании >>
Показать ещё 1 комментарий
0

Да, возможно, при условии профилирования, но вам не понравится ответ. Если вы уменьшите размер файла, его можно будет быстрее прочитать. Как? Сохраните его как двоичный, а не текстовый. Помните, что это остановит вас на использовании хороших операторов потоковой передачи высокого уровня. Вместо этого вам придется использовать вещи нижнего уровня, что может дать вам еще больше ускорения.
Возможно, было бы лучше, если бы вы спросили себя, почему вы читаете весь файл в памяти. Опять же, если вы создали двоичный файл, вы можете seek конкретные строки, которые вы используете.
Если вы выполняете расчет в файле, возможно, вы можете обработать его по ходу дела или в кусках.

  • 2
    Ты уверен? Держу пари, что узким местом является дисковый ввод-вывод ....
  • 1
    Конечно нет, но это дает некоторые альтернативы, чтобы попробовать. Мой главный вопрос действительно, почему мы пытаемся прочитать такой большой файл за один раз. Но это вопрос, а не ответ
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню