вторник, 13 марта 2012 г.

Сравнение библиотек для архивации в .Net

Недавно для моего проекта понадобилась мне библиотека для архивирования. С полгода назад по работе я пользовался библиотекой zlibnet и впечатления остались не очень приятные, так что решил поискать альтернативу. После недолгих поисков наткнулся на обзор библиотек для архивации, которая и сподвигла меня написать этот обзор.

Участники
Я буду тестировать четыре библиотеки: ZLibNet, #ZipLib, DotNetZip и ZipStorer. Теперь о каждой поподробней:

ZLibNet
Лицензия: Свободная
Размер: 35 кБ + 137 кБ(ZLib)
Эта библиотека представляет собой обёртку над широко известной сишной библиотекой ZLib. Так как большую часть составляет unmanaged код, то авторы обещают высокую производительность.
Пример кода для архивирования:
Zipper zip = new Zipper();

zip.ItemList.Add(inPath);

zip.ZipFile = outPath;

zip.PathInZip = enPathInZip.None;

zip.Zip();

#ZipLib
Лицензия: Модифицированный GPL. Можно использовать в коммерческих проектах
Размер: 196 кБ
Библиотека полностью написана на C#. Заявлена поддержка так же GZip, Tar, BZip2 форматов.
Пример кода для архивирования:
using (ZipOutputStream s = new ZipOutputStream(File.Create(outPath)))

{

s.UseZip64 = UseZip64.Off;

if (level != -1)

s.SetLevel(level);



byte[] buffer = new byte[4096];

ZipEntry entry = new ZipEntry(Path.GetFileName(inPath));

s.PutNextEntry(entry);

using (FileStream fs = File.OpenRead(inPath))

{

int sourceBytes;

do

{

sourceBytes = fs.Read(buffer, 0, buffer.Length);

s.Write(buffer, 0, sourceBytes);

}

while (sourceBytes > 0);

}

s.Finish();

s.Close();

}

DotNetZip
Лицензия: Ms-Pl
Размер: 277 кБ(урезанная версия)
Библиотека позиционируется как самая удобная для использования в .net и моно проектах. Заявлена поддержка AES шифрования. Полезным так же может оказаться наличие многих версий: полная, уменьшенная версия(оставлен основной функционал и существенно уменьшен размер), для компакт фреймворка, для SilverLight. Имеется также отдельные версии поддерживающие bzip2 и обёртка на ZLib.
Пример кода для архивирования:
using (ZipFile zip = new ZipFile())

{

zip.CompressionLevel = compressionLevel;

ZipEntry ze = zip.AddFile(inPath, "");

zip.Save(outPath);

}

ZipStorer
Лицензия: Ms-Pl
Размер: 33 кБ(исходник)
Строго говоря является не библиотекой, а отдельным классом, в следствии чего крайне просто интегрируется в проект, да и изменения в случае чего произвести будет несложно. Возможности крайне ограничены, но учитывая размер, на это можно закрыть глаза. Старая версия может работать в Silverlight.
Вот вкратце и всё, что можно сказать об испытуемых.
Пример кода для архивирования:
ZipStorer zip = ZipStorer.Create(outPath, "About");

zip.AddFile(compressionLevel, inPath, inputFileName, "");

// Updates and closes the zip file

zip.Close();


Тестирование

Тестирование будет проводиться следующим образом: делается 100 прогонов каждого метода, измеряется время, убираются 20 худших и 20 лучших времён, по остальным рассчитывается среднее. Платформа: основные тесты проводились на процессоре E8400(3.0GHz) с четырьмя гигабайтами DDRII памяти. Все четыре библиотеки тестируются в одной программе, которая логирует все свои действия и отписывает результаты в csv файл, который потом можно легко открыть в редакторе таблиц. IDE — VS2010. Использовался .net 4.0.

Архивирование

Тесты будут проводиться на 3х файлах: первый — большой текстовый файл, второй — база данных SQLite, и третий — книга «История государства Российского» Карамзина в формате pdf.
Для каждого файла проводятся два теста на первом будут тестироваться все библиотеки с настройками обеспечивающими максимальное быстродействие, на втором будет включено максимальное сжатие, к сожалению функцию уровня сжатия поддерживают только #ZipLib и DotNetZip, поэтому во втором этапе будут участвовать только они.

TXT файл.

Это текстовый файл размером в 9 373 180 байт. Документ по структуре — логи переписки по аське из квипа.
Итак, результаты с максимальной скоростью:



Итак, по скорости #ZipLib и zlibnet одинаковы, однако, вторая библиотека показывает куда лучший результат. Остальные библиотеки показывают серьёзное отставание по скорости. Теперь результаты теста на максимальное сжатие:



Тут результаты более ровные.

DB файл.

База данных, размером 19 407 754 байт. Содержимое базы — большое количество строк.



Ситуация идентична текстовому файлу, теперь результаты теста на максимальное сжатие:



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

PDF файл.

ПДФка с отсканированными страницами, размером 19 407 754 байт. Можно ожидать, что сжатие особого толка не даст, однако, давайте это проверим:



Разрывы по размеру оказались несущественны, однако же скорость отличается очень значительно. На этот раз в лидерах ZipStorer, что объяснимо — у него худшее сжатие. DotNetZip и #ZipLib показывают практически одинаковые результаты. Теперь результаты теста на максимальное сжатие:



Ситуация изменилась несильно, разве что, несколько увеличилась разница по времени.
Стоит отметить что изначально название файла содержало кириллицу и только ZipStorer достойно справилась с ним(для этого нужно было добавить строчку: zip.EncodeUTF8 = true), ZlibNet вообще отказалась с ним работать(выбрасывало исключение в котором говорилось что поддерживаются только ASCII символы в названии), а #ZipLib и DotNetZip упаковали странно: стандартный windows просмотрщик показывал пустой архив. Распаковка дала исходный файл, но в названии все кириллические символы были заменены.

Разархивирование.

Для начала я проверил все архивы на чтение. Все библиотеки могут открывать архивы, созданные другими библиотеками, никаких неожиданностей не возникло.
Непосредственно само разархивирование я буду тестировать на двух архивах: первый — база из первого теста запакованная быстрейшим способом, второй — тот же файл, но с ультра сжатием. Оба архива получены с помощью 7-zip. Рассмотрим результаты:



Парадоксально, но факт: все библиотеки распаковывали архив с максимальным сжатием быстрей, чем с минимальным. Удивляют так же гигансткие разрывы между библиотеками.

Сравнение процессоров.

Теперь запущу тест на архивацию тестового файла ещё на двух компьютерах. Первый — годовалый чертырёхядерный i7-870(2.93GHz) 16Gb, и второй — трёхлетний ноутбук Dell 1525 T2370(1.73GHz) 2Gb.
Архивирование базы данных:



Результаты удивляют. Значительный прирост показала только DotNetZip. ZlibNet и ZipStorer показали двухкратный рост производительности при переходе от ноутбука к двухядерному процессору, но вот уже 4х ядерник особого прироста не дал, т.е. можно сделать вывод что они зависят скорее от частоты, чем от количества ядер. Но наиболее поразительным является результат #ZipLib — на i7-870 сжатие занимает больше времени чем на старом ноутбучном процессоре. Объяснить подобную разницу я затрудняюсь.
А вот результаты распаковки архива:



Тут ситуация тоже необычная: и #ZipLib и DotNetZip на i7-870 работают медленней, чем на E8400.
Напоследок, приведу скриншоты диспетчера задач во время работы приложения:



Тут красным выделен период работы ZLibNet, синим — #ZipLib, жёлтым — DotNetZip, и фиолетовым — ZipStorer. Хорошо заметно, что DotNetZip грузит оба ядра на полную катушку. Что и подтверждает результаты теста на сравние.

Итоги.

Тесты получились неоднозначными. У каждой из библиотек имеется свои плюсы и минусы. Лично для себя я выбрал DotNetZip, мне понравился её простой интерфейс и предсказуемый рост производительности относительно мощи процессора.
Исходный код можно посмотреть тут.

Комментариев нет:

Отправить комментарий