@slovo

Как улучшить мой алгоритм сохранения данных на жесткий диск? (C#)

Вкратце, необходимо обрабатывать очень большой объем текстовой информации, после чего сохранять на жесткий диск в виде zip архивов. Задача усложняется тем, что обработка должна происходить многопоточно.
Пользователь класса ZipSaver
...
ZipSaver saver = new ZipSaver(10000); // 10000 - это количество элементов, когда надо сохранять архив на жесткий диск
Parallel.ForEach(source, item => {
    string workResult = ModifyItem(item);
    saver.AddItem(workResult);
});

Часть класса ZipSaver (использует библиотеку Ionic ZipFile)
private ConcurrentQueue<ZipFile> _pool;
public void AddItem(string src){
    ZipFile currentZipFile;
    if(_pool.TryDequeue(out currentZipFile) == false){
        currentZipFile = InitNewZipFile(); // если в пуле нет свободных архивов, создаем новый
    }
    currentZipFile.AddEntry(path, src); // добавление элемента в архив. path - просто путь в архиве
    // если после добавления элемента в архив, достигнуто максимальное количество элементов,
    // которое задается в конструкторе, сохраняем этот архив на жесткий диск,
    // иначе - возвращаем архив в общий пул
    if(currentZipFile.Enties.Count > _maxEntries){
        SaveZip(currentZipFile); // выполняется порядочно времени
    }else{
         _pool.Enqueue(currentZipFile);
    }
}

Можно, конечно, поиграть с цифрой максимального количества элементов в архиве, но от этого напрямую зависит и размер выходных архивов, что, в идеале, должно настраиваться. Сейчас ситуация такова, что при большом количестве элементов в исходной коллекции, которая обрабатывается в цикле, создается множество потоков, практический каждый из которых имеет "свой" инстанс ZipFile, что, естественно, приводит к переполнению оперативной памяти. Все работает неплохо, когда элементов мало, но, скажем с миллионом, оперативы может изыматься до 10 Гб.

Страшно подумать, что произойдет, если приложение запустить на машине с 4 Гб...
Вопрос к более опытным коллегам: как улучшить данный механизм сохранения, учитывая перечисленные недостатки?
  • Вопрос задан
  • 3353 просмотра
Пригласить эксперта
Ответы на вопрос 1
GrigoryPerepechko
@GrigoryPerepechko
IO лучше в нескольких потоках не делать. Seek'и будут долгими.
Попробуйте реализовать сжатие многопоточно в памяти, а запись в файл сжатой информации уже последовательно, по одному файлу.

Посмотрите в сторону чего нибудь вроде TPL Dataflow. Он как раз для задач подобной вашей создавался.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

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