2010-03-23 2 views
17

Я использую POI в своем веб-приложении J2EE для создания книги. Однако я обнаружил, что POI занимает около 3 минут, чтобы создать книгу с 25-килобайтными рядами (по 15 столбцов каждая). Является ли это проблемой производительности POI, или это оправдано для того, чтобы занять много времени? Известны ли другие API-интерфейсы для лучшей производительности?POI performance

+0

@Gugusse, принимается ответы являются индикатором для тех, кто читает вопрос, что _asker_ считается правильный ответ на его/ее актуальную проблему. Это очень важная информация. Тем не менее, по какой-либо причине вы не прокомментировали необходимость того, чтобы попросивца предоставить минимальный фрагмент кода, показывающий описанное поведение? –

+0

@ Gugussee, он просто догадывается. Фактической причиной может быть все, что образец кода будет отображаться немедленно. Было бы разумным предложить вам улучшить вашу мета-полицейскую деятельность? –

+0

@ Thorbjørn Ravn Andersen: Было бы разумным предложить вам улучшить вашу мета-мета-полицейскую деятельность? ;) – Gugussee

ответ

12

Я был бы очень удивлен, увидев, что POI занимает много времени для создания такого файла. Я только что сгенерировал лист с 30000 строк x 10 ячеек примерно за 18 секунд (без форматирования, если быть справедливым). Причина может быть один из следующих:

  • регистрация POI может быть включена, как описано here
  • вы работаете с подкачкой памяти
  • виртуальная машина доступна куча может быть очень низкой
+0

Будут ли международные символы делать обработку медленнее? И еще один вопрос, как повысить производительность памяти VM? –

+0

Я не верю, что международные символы сделают такой вид обработки медленнее: в основном это объем данных. Что касается доступной кучи VM, так как необходимый объем памяти приближается к доступной куче, сборщик мусора должен чаще пинать: в крайних случаях большая часть времени процессора тратится на сбор мусора. Это конкретная ситуация: маловероятно, что вы серьезно повлияли на нее. –

+3

в моем опыте POI немного медленный, и если POI нуждается в загрузке памяти s *** или требуется, чтобы протоколы были отключены, тогда это определенно ** ** - проблема POI. Мы генерируем отчеты с использованием POI, и как только мы создаем более чем несколько электронных таблиц, он становится очень медленным. Кроме того, 30000 рядов x 10 ячеек действительно представляют собой тривиально крошечный объем данных для процессора, выполняющего миллиарды циклов в секунду. Итак, yup, POI - довольно медленный API. – Gugussee

1

Мы также используем POI в нашем веб-приложении и не имеем никаких проблем с производительностью, хотя наши сгенерированные документы намного меньше ваших. Сначала я должен проверить, действительно ли POI является настоящей проблемой. Попытайтесь сгенерировать эти документы без накладных расходов J2EE (Unit-Test) и измерьте производительность. Вы также можете отслеживать нагрузку и использование памяти на вашем сервере J2EE, чтобы узнать, возникают ли проблемы из некоторых субоптимальных системных настроек.

3

Если ни один из других ответов не работает, посмотрите, будет ли лучше, если JExcel от Andy Khan будет лучше. Я нашел, что он намного превосходит POI для работы с Excel на Java.

1

Я сравнил POI Apache с библиотекой JExcel. Кажется, что JExcel примерно в 4 раза быстрее, чем Apache POI, но потребление памяти, кажется, более или менее то же самое:

@Test 
public void createJExcelWorkbook() throws Exception { 
     WritableWorkbook workbook = Workbook.createWorkbook(new File("jexcel_workbook.xls")); 
     WritableSheet sheet = workbook.createSheet("sheet", 0); 
     for (int i=0; i < 65535; i++) { 
      for (int j=0; j < 10; j++) { 
       Label label = new Label(j, i, "some text " + i + " " + j); 
       sheet.addCell(label); 
      } 
     } 
     workbook.write(); 
     workbook.close(); 
} 

@Test 
public void createPoiWorkbook() throws Exception { 
    Workbook wb = new HSSFWorkbook(); 
    Sheet sheet = wb.createSheet("sheet"); 
    for (int i=0; i < 65535; i++) { 
     Row row = sheet.createRow(i); 
     for (int j=0; j < 10; j++) { 
      Cell cell = row.createCell(j); 
      cell.setCellValue("some text " + i + " " + j); 
     } 
    } 
    FileOutputStream fileOut = new FileOutputStream("poi_workbook.xls"); 
    wb.write(fileOut); 
    fileOut.close(); 
} 

Я проверил его с JExcel версии 2.6.12 и Apache POI версии 3.7. Вам необходимо загрузить самые последние версии библиотеки и выполнить простые тесты выше, чтобы получить более точные цифры.

<dependency org="org.apache.poi" name="poi" rev="3.7"/> 
<dependency org="net.sourceforge.jexcelapi" name="jxl" rev="2.6.12"/> 

Примечание: существует ограничение в Apache POI 65535 строк на листе.

+4

Ограничение строки - это ограничение формата файла Excel .xls, а не POI. Если вы используете формат файла .xlsx (используя XSSF из Apache POI), вы можете создать больше строк – Gagravarr

9

Производительность записи больших файлов с помощью POI может быть значительно уменьшена, если вы использовали «потоковый» API POI вместо стандартного. Действительно, по умолчанию POI будет хранить все ваши данные в памяти, прежде чем писать все за один раз в конце. Объем памяти в этом случае может быть смехотворным для больших файлов. Вместо этого с помощью потокового API вы можете контролировать, как используется память, и данные записываются на диск постепенно.

Для создания потоковой книги, использовать что-то вроде:

SXSSFWorkbook book = new SXSSFWorkbook(); 
    book.setCompressTempFiles(true); 

    SXSSFSheet sheet = (SXSSFSheet) book.createSheet(); 
    sheet.setRandomAccessWindowSize(100);// keep 100 rows in memory, exceeding rows will be flushed to disk 
    // ...