gpt4 book ai didi

java - StringTokenizer - 读取带有整数的行

转载 作者:行者123 更新时间:2023-11-30 09:16:39 25 4
gpt4 key购买 nike

我有一个关于优化我的代码的问题(它有效但太慢......)。我正在阅读表单中的输入

X1 Y1
X2 Y2
etc

其中 Xi、Yi 是整数。我使用 bufferedReader 读取行,然后使用 StringTokenizer 处理这些数字,如下所示:

StringTokenizer st = new StringTokenizer(line, " ");

int x = Integer.parseInt(st.nextToken());
int y = Integer.parseInt(st.nextToken());

问题是这种方法在处理大型数据集时似乎效率低下。你能建议我一些简单的改进(我听说可以使用一些整数解析 int 或正则表达式)来提高性能吗?感谢您的任何提示

编辑:也许我误判了自己,必须在代码的其他地方进行一些改进......

最佳答案

(更新的答案)

我可以说,无论您的程序速度有什么问题,分词器的选择都不是其中之一。在初始运行每种方法以平衡初始化怪癖之后,我可以在几毫秒内解析 1000000 行“12 34”。如果你愿意,你可以切换到使用 indexOf,但我真的认为你需要查看其他代码来寻找瓶颈,而不是这种微优化。拆分对我来说是一个惊喜 - 与其他方法相比,它真的非常慢。我在 Guava 拆分测试中添加了它,它比 String.split 快,但比 StringTokenizer 稍慢。

  • 拆分:371 毫秒
  • IndexOf:48 毫秒
  • StringTokenizer:92 毫秒
  • Guava Splitter.split():108 毫秒
  • CsvMapper 构建一个 csv 文档并解析为 POJOS:237 毫秒(如果将行构建到一个文档中,则为 175 毫秒!)

即使在数百万行中,这里的差异也可以忽略不计。

现在我的博客上写了这篇文章:http://demeranville.com/battle-of-the-tokenizers-delimited-text-parser-performance/

我运行的代码是:

import java.util.StringTokenizer;
import org.junit.Test;

public class TestSplitter {

private static final String line = "12 34";
private static final int RUNS = 1000000;//000000;

public final void testSplit() {
long start = System.currentTimeMillis();
for (int i=0;i<RUNS;i++){
String[] st = line.split(" ");
int x = Integer.parseInt(st[0]);
int y = Integer.parseInt(st[1]);
}
System.out.println("Split: "+(System.currentTimeMillis() - start)+"ms");
}

public final void testIndexOf() {
long start = System.currentTimeMillis();
for (int i=0;i<RUNS;i++){
int index = line.indexOf(' ');
int x = Integer.parseInt(line.substring(0,index));
int y = Integer.parseInt(line.substring(index+1));
}
System.out.println("IndexOf: "+(System.currentTimeMillis() - start)+"ms");
}

public final void testTokenizer() {
long start = System.currentTimeMillis();
for (int i=0;i<RUNS;i++){
StringTokenizer st = new StringTokenizer(line, " ");
int x = Integer.parseInt(st.nextToken());
int y = Integer.parseInt(st.nextToken());
}
System.out.println("StringTokenizer: "+(System.currentTimeMillis() - start)+"ms");
}

@Test
public final void testAll() {
this.testSplit();
this.testIndexOf();
this.testTokenizer();
this.testSplit();
this.testIndexOf();
this.testTokenizer();
}

}

eta:这是 Guava 代码:

public final void testGuavaSplit() {
long start = System.currentTimeMillis();
Splitter split = Splitter.on(" ");
for (int i=0;i<RUNS;i++){
Iterator<String> it = split.split(line).iterator();
int x = Integer.parseInt(it.next());
int y = Integer.parseInt(it.next());
}
System.out.println("GuavaSplit: "+(System.currentTimeMillis() - start)+"ms");
}

更新

我也添加了 CsvMapper 测试:

public static class CSV{
public int x;
public int y;
}

public final void testJacksonSplit() throws JsonProcessingException, IOException {
CsvMapper mapper = new CsvMapper();
CsvSchema schema = CsvSchema.builder().addColumn("x", ColumnType.NUMBER).addColumn("y", ColumnType.NUMBER).setColumnSeparator(' ').build();

long start = System.currentTimeMillis();
StringBuilder builder = new StringBuilder();
for (int i = 0; i < RUNS; i++) {
builder.append(line);
builder.append('\n');
}
String input = builder.toString();
MappingIterator<CSV> it = mapper.reader(CSV.class).with(schema).readValues(input);
while (it.hasNext()){
CSV csv = it.next();
}
System.out.println("CsvMapperSplit: " + (System.currentTimeMillis() - start) + "ms");
}

关于java - StringTokenizer - 读取带有整数的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19356021/

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