我的应用程序首先从 SD 卡解析约 100MB 的文件,并且需要几分钟才能完成。从这个角度来看,在我的 PC 上,解析同一个文件需要几秒钟的时间。
我开始天真地使用Matcher和Pattern实现解析器,但 DDMS 告诉我,90% 的时间都花在了计算正则表达式上。而且解析文件用了半个多小时。该模式非常简单,一行包括:
ID (a number) <TAB> LANG (a 3-to-5 character string) <TAB> DATA (the rest)
我决定尝试使用String.split。它没有显示出显着的改进,可能是因为这个函数本身可能使用正则表达式。那时我决定完全重写解析器,结果是这样的:
protected Collection<Sentence> doInBackground( Void... params ) {
BufferedReader reader = new BufferedReader( new FileReader( sentenceFile ) );
String currentLine = null;
while ( (currentLine = reader.readLine()) != null ) {
treatLine( currentLine, allSentences );
}
reader.close();
return allSentences;
}
private void treatLine( String line, Collection<Sentence> allSentences ) {
char[] str = line.toCharArray();
// ...
// treat the array of chars into an id, a language and some data
allSentences.add( new Sentence( id, lang, data ) );
}
我注意到一个巨大的提升。花了几分钟而不是半小时。但我对此并不满意,所以我分析并意识到瓶颈是BufferedReader.readLine。我想知道:它可能是受 IO 限制的,但也可能是需要花费大量时间来填充我并不真正需要的中间缓冲区。所以我直接使用 FileReader 重写了整个事情:
protected Collection<Sentence> doInBackground( Void... params ) {
FileReader reader = new FileReader( sentenceFile );
int currentChar;
while ( (currentChar = reader.read()) != -1 ) {
// parse an id
// ...
// parse a language
while ( (currentChar = reader.read()) != -1 ) {
// do some parsing stuff
}
// parse the sentence data
while ( (currentChar = reader.read()) != -1 ) {
// parse parse parse
}
allSentences.add( new Sentence( id, lang, data ) );
}
reader.close();
}
我很惊讶地意识到性能非常糟糕。显然,大部分时间都花在了FileReader.read上。我想只阅读一个字符会花费很多。
现在我有点没有灵感了。任何提示?