Производительность GZIPOutputStream против BufferedOutputStream
Мое приложение записывает кучу видео и данных датчика i2c в файл на диске - как можно быстрее. В настоящее время я конвертирую все в байты, и я пишу с BufferedOutputStream. @Siguza был достаточно любезен, чтобы предложить разобраться в GZIPOutputStream, чтобы завершить дело. мне было интересно, были ли у вас какие-либо мысли о проблемах производительности за и против... я думаю, что процессор намного впереди, а запись на диск является узким местом - поэтому я надеюсь, что сжатие на лету через GZIPOutputStream до записи может быть хорошая стратегия. Любые мысли по этому поводу приветствуются.
Добавлено: в ответ на комментарии...
Оказывается, архивирование - это не то, что процессор дорогой... и способ, которым я задавал оригинальный вопрос, был не велик, как справедливо заметил Эрвин. вопрос о производительности архивирования не находится между BufferedOutputStream и GZIPOutputStream ... и сжатые, и разархивированные потоки должны быть обернуты в BufferedOutputStream, но сколько затрат добавляется, если исходный FileOutputStream обернут в GZIPOutputStream сначала, прежде чем это будет обернутый в BufferedOutputStream. вот ответ. Я использую код
byte[] bs = RHUtilities.toByteArray((int)1);
boolean zipped = false;
FileOutputStream fos = new FileOutputStream(datFile);
BufferedOutputStream bos = null;
if (zipped) {
GZIPOutputStream gz = new GZIPOutputStream(fos);
bos = new BufferedOutputStream(gz);
} else
bos = new BufferedOutputStream(fos);
long startT = System.currentTimeMillis();
for (int i=0; i<1000000; i++)
bos.write(bs);
bos.flush();
System.out.println(System.currentTimeMillis()-startT);
bos.close();
мой ноутбук Macpro 2012 года записывает 1M
zipped=true в 38 мс - размер файла 4 МБ
zipped=false в 21 мс - размер файла 4 КБ
и да, мне нравится сжатие:-)
производительность чтения почти идентична 83 против 86 мс между
FileInputStream fin = new FileInputStream(datFile);
а также
GZIPInputStream gin = new GZIPInputStream(new FileInputStream(datFile));
все хорошо...
1 ответ
Этот вопрос вызывает много вопросов:
я думаю, что процессор далеко вперед, а запись на диск является узким местом
"Я думаю" не является надежной основой для оптимизации работы. Вам нужно сделать несколько измерений, чтобы узнать, где на самом деле находится узкое место. (Если ваше "мышление" неверно, то переход на GZipOutputStream может усугубить ситуацию.)
В качестве альтернативы, просто попробуйте и оцените, улучшает ли это производительность или нет.
С теоретической точки зрения, если существует существенное несоответствие между скоростью процессора и диска, тогда сжатие может помочь. И одним из возможных преимуществ является то, что сжатие также может сэкономить дисковое пространство.
Но минусы:
- Сжатие относительно дорого (как и декомпрессия), так что вы можете использовать больше (затраченного) времени, чем вы получаете за счет сокращения ввода-вывода
- сжатие неэффективно для небольших файлов,
- Форматно-независимое сжатие не очень эффективно для необработанных (несжатых) аудио или видео данных1
- если ваши видеоданные уже сжаты, то второе сжатие ничего не даст.
Наконец, это может быть проблема "большого количества маленьких файлов". Если вы попытаетесь прочитать и записать много маленьких файлов, узким местом, скорее всего, будет не грубая скорость диска. Скорее всего, это будет способность ОС читать и записывать каталоги и / или метаданные файла. Если именно в этом и заключается ваша проблема, то вам следует подумать о том, чтобы объединить "много маленьких файлов" в архивы; например, TAR или ZIP файлы. Есть библиотеки для этого на Java.
И еще одно преимущество архивов заключается в том, что они могут сделать сжатие более эффективным.
1 - Для справки прочитайте https://en.wikipedia.org/wiki/Lossless_compression и https://en.wikipedia.org/wiki/List_of_codecs