gpt4 book ai didi

java - Apache MetaModel - 查询电子表格性能不佳

转载 作者:行者123 更新时间:2023-12-01 09:45:14 25 4
gpt4 key购买 nike

我需要用 Java 查询电子表格文件。我正在使用 Apache MetaModel

我使用maven导入它

<dependency>
<groupId>org.apache.metamodel</groupId>
<artifactId>MetaModel-excel</artifactId>
<version>4.5.2</version>
</dependency>

一切正常,但是 next() 指令在应该返回 false 时需要几秒钟,为什么?

import org.apache.metamodel.DataContext;
import org.apache.metamodel.excel.ExcelDataContext;
import org.apache.metamodel.schema.Schema;
import org.apache.metamodel.schema.Column;
import org.apache.metamodel.schema.Table;
import org.apache.metamodel.query.Query;
import org.apache.metamodel.query.OperatorType;
import org.apache.metamodel.data.DataSet;
import org.apache.metamodel.data.Row;
import org.apache.metamodel.MetaModelException;


public class SpreadsheetReader {

private File spreadsheet;


public SpreadsheetReader(String spreadsheetLocation, String spreadsheetName){

this.spreadsheet = new File( spreadsheetLocation + spreadsheetName );

if( !"OK".equals( checkSpreadSheet() ) ){
throw new IllegalStateException("Error in spreadsheet. Cause: "+spreadsheetStatus);
}

}


/** query the excel spreadsheet for the given ID
*/
public List<String> query( String givenProgId ){

List<String> linksArray = new ArrayList<String>();
int rowCount = 0;

ExcelConfiguration conf = new ExcelConfiguration( 1, true, true ); // columnNameLineNumber, skipEmptyLines, sEColumns
DataContext dataContext = new ExcelDataContext( this.spreadsheet, conf );

System.out.println( "PROFILING >>> "+(new org.joda.time.DateTime())+" START-1" ); // ##

Schema schema = dataContext.getDefaultSchema();

System.out.println( "PROFILING >>> "+(new org.joda.time.DateTime())+" STOP-1" ); // ##
// Takes 2 seconds. Will be moved into constructor.

Table table = schema.getTables()[0];

Column idsColumn = table.getColumnByName("ProgID");
Column titlesColumn = table.getColumnByName("Titles");

Query query = new Query().select(titlesColumn)
.from(table)
.where(idsColumn, OperatorType.EQUALS_TO, givenProgId);

try( DataSet dataSet = dataContext.executeQuery(query) ){ // try-with-resource, no need to close dataset

while (dataSet.next()) {

// the rows are read quite quickly, problem will be when next() is false

++rowCount;

Row currentRow = dataSet.getRow();
String currentTitle = (String)currentRow.getValue(0);

linksArray.add( "my-service/titles/"+currentTitle );

System.out.println( "PROFILING >>> "+(new org.joda.time.DateTime())+" START-2" ); // @@@@@@@
}
System.out.println( "PROFILING >>> "+(new org.joda.time.DateTime())+" STOP-2" ); // @@@@@@@
// TAKES ABOUT 6 SECONDS - (Excel file has just 14.779 rows and 114 columns)

}catch(MetaModelException xx){
//logger
throw xx;
}

return linksArray;
}
}}

更新:使用只有 3 个条目的电子表格文档进行更多分析:

现在的代码是:

try( DataSet dataSet = this.dataContext.executeQuery(query) ){


// FIRST NEXT() with result => quite fast

System.out.println( "\n PROFILING >>> "+(new org.joda.time.DateTime())+" START a\n" );
System.out.println( "\n 88888 NEXT >>> "+(dataSet.next())+" <<<< \n" );
Row currentRow = dataSet.getRow();
String currentTitle = (String)currentRow.getValue(0);
System.out.println( "\n READ: "+(new org.joda.time.DateTime())+" >>> "+currentTitle+" \n" );

System.out.println( "\n PROFILING >>> "+(new org.joda.time.DateTime())+" STOP a\n" );


// SECOND AND LAST NEXT() => very SLOW

System.out.println( "\n PROFILING >>> "+(new org.joda.time.DateTime())+" START b\n" );
System.out.println( "\n 88888 NEXT >>> "+(dataSet.next())+" <<<< \n" );
System.out.println( "\n PROFILING >>> "+(new org.joda.time.DateTime())+" STOP b\n" );

}

电子表格已预先加载到类构造函数中。

一系列后续相同查询中最后一个查询的日志(带时间)为:

Jun 30, 2016 10:59:38 AM log my-project.logging.ITVLogger
INFO: CODE00012 - Query on spreadsheet started for ID 123456



PROFILING >>> 2016-06-30T10:59:38.651+01:00 START a

10:59:38.652 [main] INFO o.a.m.d.RowPublisherDataSet -
Starting separate thread for publishing action: org.apache.metamodel.excel.XlsxRowPublisherAction@4977e527

88888 NEXT >>> true <<<<

READ: 2016-06-30T10:59:39.756+01:00 >>> A_TITLE

PROFILING >>> 2016-06-30T10:59:39.756+01:00 STOP a



PROFILING >>> 2016-06-30T10:59:39.756+01:00 START b

88888 NEXT >>> false <<<<

PROFILING >>> 2016-06-30T10:59:44.735+01:00 STOP b

因此,回顾一下,检索结果大约需要 1 秒,最后一次执行 next() 需要 4~6 秒。

最佳答案

Excel DataContext 实现在后台解包和解析压缩的 .xlsx 文件。这意味着 DataContext.executeQuery(...) 方法会快速返回,但紧随其后的 DataSet.next() 调用必须等待数据被返回。内存中可用。我看不出有什么方法可以避免这种情况,这只是 Excel 文件处理起来相当复杂的结果。

关于java - Apache MetaModel - 查询电子表格性能不佳,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38105932/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com