Быстро кросс-платформенный алгоритм для чтения/записи файла в C++

Я хочу поставить на вид простой вопрос, что я не могу найти ответ нигде. Существует ли FAST современный алгоритм для входа файла и/или произвел, который может быть скомпилирован со всеми стандартными совместимыми компиляторами C++ и работами для всех операционных систем без требования внешних библиотек?

  1. я нашел, что самый быстрый путь состоит в том, чтобы использовать файлы с отображенной памятью, но так не пойдет, вызывают, мы хотим ту же часть кода, работающего над всеми платформами
  2. мы не можем использовать пчелу как Win32 причина API, которая сделает это платформой конкретный
  3. я не хочу использовать c, я хочу, чтобы алгоритм был просто чистым кодом C++ с stl по возможности, не некоторым ужасным c со смешанным взломом/приемом asm
  4. платформы или внешние библиотеки, которые не принадлежат стандартного C++, не должны использоваться как wxWidgets, QT, MFC и т.д.
  5. Большой акцент этого целого вопроса - то, что алгоритм максимально быстро, что-то вроде скорости выполнения его с файлами с отображенной памятью, еще быстрее было бы большим, но я знаю, что это не возможно

Вы когда-либо видели что-то, таким образом, сумасшедшее исследуемый кем-либо еще кроме меня? Такой алгоритм даже возможен?

Спасибо за любые рекомендации

5
задан user258883 26 January 2010 в 00:29
поделиться

7 ответов

Это не имеет ничего общего с «алгоритмом».

Когда речь идет о записи данных в файл, вы во власти операционной системы - отображаемые памятью файлы «быстры», потому что вы просто пишете в память, и ОС синхронизируется на его Собственное время. Если ОС не поддерживает ее, вам не удача в этом отношении - если вы не хотите реализовать свой собственный слой сопоставления памяти.

Кстати, POSIX имеет MMAP , поэтому, если вы ограничиваете себя по POSIX-совместимые системы, вы в порядке.

9
ответ дан 18 December 2019 в 06:11
поделиться

Чтобы по-другому взглянуть на "милосердие ОС", большая часть накладных расходов при копировании файлов ложится на операционную систему. Фрагментированный файл займет больше времени на чтение, чем дефрагментированный. Для обнаружения фрагментированных файлов не существует ни общих, ни стандартных С++ функций.

Самый быстрый метод в C++:

std::ifstream in_file;
std::ofstream out_file;

out_file << in_file.rdbuf();

Более подробную информацию можно найти, проведя поиск в Интернете по ключевым словам "копирование файла rdbuf". Приведенный выше фрагмент оставляет копирование в операционной системе, но переносится на все платформы. Читая в потоки C++ i/o, можно задать размер буфера для чтения или использовать собственный буфер.

Для более быстрого копирования файлов требуется функциональность, специфичная для платформы, например, передача DMA. Использование потоков и многократной буферизации может ускорить это; однако С++ не поддерживает потоки (существует стандарт де-факто POSIX, который действительно поддерживает потоки). Один поток будет читать в буферы, в то время как другой будет записывать из буферов.

4
ответ дан 18 December 2019 в 06:11
поделиться

со следующими ограничениями:

можно скомпилировать со всеми стандартными соответствующими компиляторами C ++ и работает для всех операционных систем без требования внешних библиотек?

Вы почти ограничены к стандартным функциям файла библиотеки IO. Возможно, POSIX функции (в зависимости от того, какое подмножество «всех стандартных совместимых компиляров C ++» вы рассматриваете).

Если они недостаточно быстро для вас, вам придется начать сбрасывать некоторые ограничения.

9
ответ дан 18 December 2019 в 06:11
поделиться

Некоторые очки:

  • Это не имеет ничего общего с алгоритмами.
  • Желание нацеливаться на все операционные системы, не очень продуктивная цель (и невозможно
  • Ваш код не работает на определенной платформе, пока вы не тестируете его). Вместо этого я бы сосредоточился на некоторых наборах операционных систем, которые возможны - скажем, POSIX + Win32.
  • В этом случае вы можете сделать отображение памяти, например, путем реализации MMAP () для Windows (в верхней части MapViewoffile () и т. Д. - Исходный код GIT имеет реализацию MMAP для Windows, если вам нужно некоторое вдохновение)
  • Если вы не можете использовать отображение памяти, я бы порекомендовал использовать нормальный API файла C, вместо потоков файлов C ++, если производительность является большой сделкой. Несмотря на то, что потоки C ++ имеют потенциал более высокой производительности для некоторых операций, на практике довольно медленнее.
  • Но чтобы получить хорошую производительность, он часто может быть «достаточно хорош», чтобы убедиться, что вы обрабатываете свои данные в здравом пути. Прочитайте данные последовательно, не перечитайте и т. Д. Идеальный враг добра;)
2
ответ дан 18 December 2019 в 06:11
поделиться

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

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

В любом случае, если вы дадите эти идеи попробовать, пожалуйста, сообщите нам об этом, если вы заметите разницу. Фактические результаты ваших тестов по тестам будут интересны.

1
ответ дан 18 December 2019 в 06:11
поделиться

Другие плакаты верны в том, что производительность всегда наступает в шансы с помощью общества (кроссплатформенная).

Однако в целом вы получите лучшие результаты по «буферизации» вашего ввода - используя FRAD (), чтобы прочитать относительно большие куски данных и обработки тем.

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

0
ответ дан 18 December 2019 в 06:11
поделиться

Быстрый IO обычно сводится к двум вещам:

  1. Минимизируйте копирование данных
  2. Минимизируйте переключение контекста данных / пользователей

Больше всех методов IO, пытается обратиться к одному или другому. Самый быстрый кроссплатформенный код для IO, который я знаю, это система Perl IO. Я бы предложил взглянуть на источник . Хакеры Perl провели десятилетия, получая их как можно быстрее как можно быстрее.

1
ответ дан 18 December 2019 в 06:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: