2015-09-13 7 views
1

В настоящее время у меня есть проблема, что этот кусок кода будет называться> 500 тыс. Раз. Размер сжатого byte[] составляет менее 1 КБ. Каждый раз, когда вызывается метод, все потоки должны быть созданы. Поэтому я ищу способ улучшить этот код.Как улучшить производительность GZIP

private byte[] unzip(byte[] data) throws IOException, DataFormatException { 

    byte[] unzipData = new byte[4096]; 

    try (ByteArrayInputStream in = new ByteArrayInputStream(data); 
     GZIPInputStream gzipIn = new GZIPInputStream(in); 
     ByteArrayOutputStream out = new ByteArrayOutputStream()) { 

     int read = 0; 
     while((read = gzipIn.read(unzipData)) != -1) { 
      out.write(unzipData, 0, read); 
     } 

     return out.toByteArray(); 
    } 
} 

Я уже tried заменить ByteArrayOutputStream с ByteBuffer, но в момент создания я не знаю, сколько байт мне нужно выделить.

Кроме того, я пытался использовать Inflater, но я наткнулся на описанную проблему here.

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

+0

Попробуйте увеличить размер буфера 'unzipData'. 4096 не очень большой, и я подозреваю, что он увеличит его, что позволит вам писать больше данных с меньшим количеством вызовов для записи. – GiantTree

+0

@GiantTree OP заявила, что 'data' составляет менее 1 КБ, поэтому увеличение размера буфера будет пустой, – Andreas

+0

@ Andreas Я просто просмотрел текст; вы правы, это не поможет с точки зрения производительности. Он мог передать 'новый ByteArrayInputStream (data)' непосредственно в 'новый GZIPInputStream', не создавая промежуточного InputStream. – GiantTree

ответ

1
  1. Профиль вашего приложения, чтобы быть уверенным в том, что вы действительно проводите оптимизированное время в этой функции. Неважно, сколько раз вы называете эту функцию; если на него не приходится значительную долю общего времени выполнения программы, тогда оптимизация будет потрачена впустую.

  2. Предварительный размер ByteArrayOutputStream. Размер буфера по умолчанию - 32 байта, а для изменения размера требуется копирование всех существующих байтов. Если вы знаете, что ваши декодированные массивы будут около 1k, используйте new ByteArrayOutputStream(2048).

  3. Вместо чтения байта за раз, прочитайте блок за раз, используя предварительно выделенный byte[]. Опасайтесь, что вы должны использовать возвращаемое значение от read в качестве входного сигнала для write. Лучше, используйте что-то вроде Jakarta Commons IOUtils.copy(), чтобы избежать ошибок.

+0

Код уже делает # 3. Проголосовать за предложение # 1. – Andreas

+0

Я сделал профиль, и это одно узкое место. –

Смежные вопросы