美文网首页
easy poi导出100wexcel性能对比

easy poi导出100wexcel性能对比

作者: luncene_e110 | 来源:发表于2021-06-09 15:14 被阅读0次

方式1:通过工具类ExcelExportUtil.exportExcel导出

        //常驻内存:HSSFCell等
         ExportParams params = new ExportParams();
         params.setAddIndex(true);
         Workbook workbook=null;
         Date start = new Date();
         FileOutputStream out = new FileOutputStream("ooxml-scatter-chart_SXSSFW_.xlsx");
         List<MsgClient> list = new ArrayList<MsgClient>();
         for (int i = 0; i < 1000000; i++) {  //一百万数据量
             MsgClient client = new MsgClient();
             client.setBirthday(new Date());
             client.setClientName("小明" + i);
             client.setClientPhone("18797" + i);
             client.setCreateBy("JueYue");
             client.setId("1" + i);
             client.setRemark("测试" + i);
             MsgClientGroup group = new MsgClientGroup();
             group.setGroupName("测试" + i);
             client.setGroup(group);
             list.add(client);
         }
         workbook = ExcelExportUtil.exportExcel(new ExportParams(), MsgClient.class, list);
         workbook.write(out);
         out.close();
         System.out.println(new Date().getTime() - start.getTime());

通过jvisualvm观察内存和cpu使用情况:


image.png

从图上可以看到cpu和内存使用情况,最坏的情况下可能需要接近3个G的内存,除了本身list的对象没有释放外,还有很多是跟esaypoi相关的对象没有被释放。
可以看下第二个图,堆dump:


image.png
从图中可以看到本身MsgClient对象大概40w个,,但是和easypoi的对象400w个
时间往后再看:
image.png

这个时候我们的MsgClient对象已被回收,但是easypoi的对象达到了700w。
所以这种方式下的导出,cpu和内存需求都比较大。
这种方式导出100w条数据花费时间92s。

方式2:通过工具类ExcelExportUtil.exportBigExcel导出。
这种方式下,实例化的workbook为,SXSSFWorkbook,他本身默认只保持100条只读的数据在内存中,其他的会写到磁盘临时文件。直接看代码:

List<MsgClient> list = new ArrayList<MsgClient>();
        Workbook workbook = null;
        Date start = new Date();
        ExportParams params = new ExportParams("大数据测试", "测试");
        for (int i = 0; i < 1000000; i++) {  //一百万数据量
            MsgClient client = new MsgClient();
            client.setBirthday(new Date());
            client.setClientName("小明" + i);
            client.setClientPhone("18797" + i);
            client.setCreateBy("JueYue");
            client.setId("1" + i);
            client.setRemark("测试" + i);
            MsgClientGroup group = new MsgClientGroup();
            group.setGroupName("测试" + i);
            client.setGroup(group);
            list.add(client);
            if(list.size() == 10000){
                workbook = ExcelExportUtil.exportBigExcel(params, MsgClient.class, list);
                list.clear();
            }
        }
        ExcelExportUtil.closeExportBigExcel();
        System.out.println(new Date().getTime() - start.getTime());
        File savefile = new File("D:/excel/");
        if (!savefile.exists()) {
            savefile.mkdirs();
        }
        FileOutputStream fos = new FileOutputStream("D:/excel/ExcelExportBigData.bigDataExport.xlsx");
        workbook.write(fos);
        fos.close();

从代码上可以看出,首先MsgClient的对象可以分段去写到workbook中,这样可以进一步降低内存的使用情况。
通过jvisualvm监控,我们看下内存和cpu的使用情况


image.png

从cpu和内存使用情况上看,使比方式一,cpu能够比较平稳,内存使用接近在1G的水平,当然可以通过限制堆内存大小来随时进行垃圾回收(亲测512m或者256m都是没问题的)。
然后看看dump文件的数据:


image.png
主要还是我们自定义的对象占据了比较多的实例和内存。
image.png
再看看easypoi的对象实例数,想SXSSFCELL,为什么是700,这里我的列是7列,然后100行在内存,最终就是700个对象,这样反向证明了默认是100个行数据在内存。

该方式下,导出100w条数据耗时14s。

相关文章

网友评论

      本文标题:easy poi导出100wexcel性能对比

      本文链接:https://www.haomeiwen.com/subject/wseeeltx.html