2010-03-23 6 views
17

내 J2EE 웹 응용 프로그램에서 POI를 사용하여 통합 문서를 생성하고 있습니다. 그러나 POI는 25K 행 (각각 약 15 열)의 통합 문서를 만드는 데 약 3 분이 걸린다는 것을 알았습니다. POI 성능 문제입니까, 아니면 많은 시간을 할애해야할까요? 더 나은 성능을 위해 알려진 다른 API가 있습니까?POI 성능

+0

@Gugusse : 스트리밍 통합 문서를 생성하기 위해

는 같은 것을 사용합니다. 그것은 매우 중요한 정보입니다. 즉, 질문자가 설명 된 동작을 보여주는 최소 코드 스 니펫을 제공 할 필요성을 언급하지 않은 이유는 무엇입니까? –

+0

@ Gugussee, 그는 단지 추측입니다. 실제 이유는 코드 샘플이 즉시 표시 할 수있는 모든 것일 수 있습니다. 메타 폴리싱을 개선 할 것을 제안하는 것이 합리적입니까? –

+0

@ Thorbjørn Ravn Andersen : 메타 메타 폴리싱을 개선 할 것을 제안하는 것이 합리적일까요? ;) – Gugussee

답변

12

POI가 그런 파일을 생성하는 데 많은 시간이 걸리는 것을 보니 매우 놀랐습니다. 방금 약 18 초에 30000 행 x 10 셀의 시트가 생성되었습니다 (형식이 지정되지 않아야 함). 원인은 다음 중 하나 일 수 있습니다 here

  • 당신의 VM을 사용할 수 힙이 매우 낮은 수 있습니다 스왑 메모리에서 실행을 설명

    • POI 로깅이 켜져있을 수 있습니다
  • +0

    국제 문자가 있으면 처리 속도가 느려 집니까? 또 다른 질문은 VM 메모리를 늘리면 성능이 어떻게 향상 될 수 있습니까? –

    +0

    저는 국제적인 캐릭터가 이런 종류의 프로세싱을 더 느리게 만들 것이라고 생각하지 않습니다. 대부분 데이터 양에 관한 것입니다. VM 사용 가능 힙과 관련하여 필요한 메모리 양은 사용 가능한 힙에 가깝기 때문에 가비지 수집기가 더 자주 시작해야합니다. 극단적 인 경우 대부분의 CPU 시간이 가비지 수집에 소요됩니다. 이는 특정 상황입니다. 귀하가 그 영향을 크게받지 않았을 가능성은 없습니다. –

    +3

    내 경험 POI는 좀 느리고 POI에 메모리가 필요하거나 로깅을 해제해야하는 경우 POI 문제가 발생합니다. POI를 사용하여 보고서를 생성하고 몇 가지 스프레드 시트 이상을 생성하자마자 매우 느립니다. 또한 30000 개의 행 x 10 셀은 실제로 초당 수십억 개의 사이클을 처리하는 CPU를위한 아주 작은 양의 데이터입니다. 그래서, POI는 상당히 느린 API입니다. – Gugussee

    1

    웹 응용 프로그램에서도 POI를 사용하며 성능 문제는 없습니다. 생성 된 문서는 귀하의 것보다 훨씬 작습니다. 먼저 POI가 진짜 문제인지 확인해 보겠습니다. J2EE 오버 헤드 (단위 테스트)없이 이러한 문서를 생성하고 성능을 측정하십시오. 또한 J2EE 서버의로드 및 메모리 사용량을 모니터링하여 일부 최적의 시스템 설정에서 문제가 발생하는지 확인할 수 있습니다.

    3

    다른 답변이 없으면 Andy Khan의 JExcel이 더 좋을지 확인하십시오. 나는 Java에서 Excel을 다루는 POI보다 훨씬 뛰어나다는 것을 알게되었습니다.

    1

    나는 Apache POI를 JExcel 라이브러리와 비교했다. JExcel가에 대해 아파치 POI보다 빠른 4 배 것 같다하지만, 메모리 소비는 더 많거나 적은 동일한 것으로 보인다

    내가 JExcel 버전 2.6.12와 아파치 POI 버전 3.7을 테스트했습니다
    @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(); 
    } 
    

    . 최신 라이브러리 버전을 직접 다운로드하고 위의 간단한 테스트를 실행하여 더 정확한 숫자를 얻어야합니다.

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

    참고 : 장에 65,535 행의 아파치 POI에 한계가있다.

    +4

    행 제한은 POI가 아닌 Excel .xls 파일 형식 제한입니다. .xlsx 파일 형식 (Apache POI의 XSSF 사용)을 사용하는 경우 더 많은 행을 만들 수 있습니다 – Gagravarr

    9

    표준 파일 대신 '스트리밍'POI API를 사용하면 큰 파일을 POI로 작성하는 성능을 크게 떨어 뜨릴 수 있습니다. 실제로 기본적으로 POI는 모든 데이터를 한 번에 하나씩 작성하기 전에 메모리에 보관합니다. 이것의 메모리 사용량은 큰 파일에 대해 엄청나게 클 수 있습니다. 스트리밍 API를 사용하는 대신 메모리가 사용되는 방식과 데이터가 디스크에 점진적으로 기록되는 방식을 제어 할 수 있습니다. 답변을 _asker_는 그/그녀의 실제 문제에 대한 정답으로 간주 어떤 질문을 읽는 것과 지표입니다 받아,

    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 
        // ...