java - 操作系统之间的Java性能差异太大
问题描述
我测试了我开发的程序。
但是,Java 的每个操作系统的性能存在显着差异。
我整天都在寻找原因,但没有找到。
我开发的逻辑如下:
- 用户在浏览器中上传 Excel。
- 使用 poi 库读取 excel。
- 通过解析将读取的字符串数据转换为对象。
- 将转换后的对象保存到 Cassandra 数据库。
在demo源码中,只有解析数据的部分附在底部。
数据解析逻辑也有严重的性能差异。
环境配置如下。
- SpringBoot-2.2.2.Release
- JVMOptions 是 -Xms16g -Xmx16g
- Cassandra-3.11.7
- OpenJDK1.8
我进行了 3 次测试,结果是:
测试 1
- SpringBoot-2.2.2.Release
- JVMOptions 是 -Xms16g -Xmx16g
- Cassandra-3.11.7
- OpenJDK1.8
视窗操作系统
- poi excel读取:2秒
- 数据解析:42秒
- 数据库保存:31 秒
操作系统
- poi excel读取:2秒
- 数据解析:4秒
- 数据库保存:5 秒
测试 2(已删除保存逻辑)
- SpringBoot-2.2.2.Release
- JVMOptions 是 -Xms16g -Xmx16g
- Cassandra-3.11.7
- OpenJDK1.8
视窗操作系统
- poi excel读取:2秒
- 数据解析:40秒
操作系统
- poi excel读取:1秒
- 数据解析:6秒
测试 3
进行此测试是因为确定在解析数据的过程中存在性能下降。
- JVMOptions 是 -Xms16g -Xmx16g
- OpenJDK1.8
视窗操作系统
- poi excel读取:2秒
- 数据解析:2秒
操作系统
- poi excel读取:2秒
- 数据解析:1秒
然而,结果出乎意料。通过去除所有之前开发的逻辑并执行数据解析,速度大大提高。
我是通过浏览器中的一个简单的 restAPI 请求来完成的。
不知道该从哪一点做起因分析。帮助。
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("검색어", "분리정보", "외래어");
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;
}
}
解决方案
推荐阅读
- powershell - 有没有办法从 PowerShell 中的数字签名中获取一个人的姓名/电子邮件?
- pine-script - 是否有解决方案将系列转换为 pine 编辑器中的单个数据?
- node.js - React 正在获取系统 .env 文件 .. 而不是我在根目录中创建的 .env 文件
- flutter - Flutter:使用带有 ToggleButtons 的工具提示
- html - 添加多个字段时,HTML多选下拉菜单Jquery和样式不起作用
- python - warnings.warn("Estimator fit failed. the score on this train-test"
- python - Django:关系的“id”列中的空值违反了非空约束
- angular - Reddit OAuth 隐式授权流程是不断征求对每个令牌请求的同意。我究竟做错了什么?
- python - Beautifulsoup / Selenium如何抓取网站直到下一页被禁用?
- python - GLSL,基于 SDF 的圆角矩形