首页 > 解决方案 > 操作系统之间的Java性能差异太大

问题描述

我测试了我开发的程序。

但是,Java 的每个操作系统的性能存在显着差异。

我整天都在寻找原因,但没有找到。


我开发的逻辑如下:

  1. 用户在浏览器中上传 Excel。
  2. 使用 poi 库读取 excel。
  3. 通过解析将读取的字符串数据转换为对象。
  4. 将转换后的对象保存到 Cassandra 数据库。

在demo源码中,只有解析数据的部分附在底部。
数据解析逻辑也有严重的性能差异。


环境配置如下。

  1. SpringBoot-2.2.2.Release
  2. JVMOptions 是 -Xms16g -Xmx16g
  3. Cassandra-3.11.7
  4. OpenJDK1.8

我进行了 3 次测试,结果是:

测试 1

  1. SpringBoot-2.2.2.Release
  2. JVMOptions 是 -Xms16g -Xmx16g
  3. Cassandra-3.11.7
  4. OpenJDK1.8

测试 2(已删除保存逻辑)

  1. SpringBoot-2.2.2.Release
  2. JVMOptions 是 -Xms16g -Xmx16g
  3. Cassandra-3.11.7
  4. OpenJDK1.8

测试 3

进行此测试是因为确定在解析数据的过程中存在性能下降。

  1. JVMOptions 是 -Xms16g -Xmx16g
  2. OpenJDK1.8

然而,结果出乎意料。通过去除所有之前开发的逻辑并执行数据解析,速度大大提高。

我是通过浏览器中的一个简单的 restAPI 请求来完成的。

不知道该从哪一点做起因分析。帮助。

要解析的 Excel 示例数据下载

package com.example.demo;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class DemoApplication {

    public static final List<String> TABLE_USERNOUN_EXCEL_FIELD = Arrays.asList("keyword", "separation", "foreign");
    public static final List<String> TITLE_USERNOUN_EXCEL_FIELD = Arrays.asList("검색어", "분리정보", "외래어&quot;);


    public static void main(String[] args) {
        try {
            Long start = new Date().getTime();
            List<Map<String, Object>> data = readFileData();
            Long end = new Date().getTime();
            System.out.println(data.toString());
            System.out.println("finish time : " +(end-start)/1000+ "seconds");

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static List<Map<String, Object>> readFileData() throws IOException {
        List<String> tableColumns = TABLE_USERNOUN_EXCEL_FIELD;
        List<String> columnNames = TITLE_USERNOUN_EXCEL_FIELD;
        List<Map<String, Object>> contents = new ArrayList(); // contents array
        List<Integer> requiredList = Arrays.asList(0,1);

        Path targetLocation = Paths.get("D:","usernoun_dic_10000.xlsx");
        InputStream inputStream = new FileInputStream(new File(targetLocation.toString()));
        SXSSFWorkbook workbook = new SXSSFWorkbook(new XSSFWorkbook(inputStream));

        Sheet sheet = workbook.getXSSFWorkbook().getSheetAt(0);
        int rows = sheet.getPhysicalNumberOfRows();
        if (rows<2){
            workbook.close();
            inputStream.close();

            return contents;
        }

        Row checkRow = sheet.getRow(0);
        int cellCnt = checkRow.getPhysicalNumberOfCells();
        if (cellCnt<columnNames.size()){
            workbook.close();
            inputStream.close();

            return contents;
        }else if (cellCnt>columnNames.size()){
            Object check = getCellValue(checkRow.getCell(tableColumns.size()));

            if (check!=null){
                if (!check.toString().equals("")){
                    workbook.close();
                    inputStream.close();

                    return contents;
                }
            }
        }else{
            for (int i=0; i<cellCnt; i++){
                Object cellVal = getCellValue(checkRow.getCell(i));
                String columnName = "";

                if (cellVal!=null){
                    columnName = cellVal.toString();
                }

                if (columnName.equals("")||!columnName.equals(columnNames.get(i))){
                    workbook.close();
                    inputStream.close();

                    return contents;
                }
            }
        }

        sheet.removeRow(checkRow);
        List<String> finalTableColumns = tableColumns;
        List<Integer> finalRequiredList = requiredList;

        sheet.forEach(row -> {
            Map<String, Object> content = new HashMap<>(); //contents object
            AtomicReference<Boolean> skip = new AtomicReference<>(false);

            row.forEach(cell -> {
                int cellIdx = cell.getColumnIndex();
                if (cellIdx< finalTableColumns.size()){
                    Object value = getCellValue(cell);

                    boolean require = finalRequiredList.stream().anyMatch(integer -> integer==cellIdx);

                    if (require){
                        if (value!=null){
                            if (value.toString().equals("")){
                                skip.set(true);
                            }
                        }else{
                            skip.set(true);
                        }
                    }

                    content.put(finalTableColumns.get(content.size()), value);
                }
            });

            if (!skip.get()){
                contents.add(content);
            }
        });

        workbook.close();
        inputStream.close();
        return contents;
    }

    public static Object getCellValue(Cell cell) {

        switch (cell.getCellType()) {
            case BLANK: //Null exception
                return "";
            case ERROR:
                return cell.getErrorCellValue();
            case STRING:
                return cell.getStringCellValue();
            case BOOLEAN:
                return cell.getBooleanCellValue();
            case NUMERIC:
                return cell.getNumericCellValue();
            case FORMULA:
                return cell.getCellFormula();
        }
        return null;
    }
}

标签: javaperformanceparsingapache-poi

解决方案


推荐阅读