提问人: 提问时间:4/10/2009 最后编辑:skaffman 更新时间:6/15/2015 访问量:24067
Java 的 Scanner vs String.split() vs StringTokenizer;我应该使用哪个?
Java's Scanner vs String.split() vs StringTokenizer; which should I use?
问:
我目前正在使用扫描一个文件,其中每行都有用 分隔的字符串数。我在某处读到,在性能方面,长文件可以做得更好,所以我想检查一下。split()
'~'
Scanner
我的问题是:我是否必须创建两个实例?也就是说,一个用于读取一行,另一个基于该行来获取分隔符的令牌?如果我必须这样做,我怀疑我是否会从使用它中获得任何好处。也许我在这里遗漏了什么?Scanner
答:
我会说这是最快的,而且可能足以满足你正在做的事情。它不如它那么灵活。 已弃用,仅适用于向后兼容,因此请勿使用它。split()
scanner
StringTokenizer
编辑:您可以随时测试这两种实现,看看哪一个更快。我很好奇自己是否可以比.对于给定大小的 VS,拆分可能会更快,但我不能确定这一点。scanner
split()
Scanner
评论
对于处理行,您可以使用扫描器,对于从每行获取令牌,您可以使用拆分。
Scanner scanner = new Scanner(new File(loc));
try {
while ( scanner.hasNextLine() ){
String[] tokens = scanner.nextLine().split("~");
// do the processing for tokens here
}
}
finally {
scanner.close();
}
您可以使用该方法让 使用 遍历每行上的标记,同时仍用于遍历行本身。useDelimiter("~")
hasNext()/next()
hasNextLine()/nextLine()
编辑:如果你要做一个性能比较,你应该在做split()测试时预编译正则表达式:
Pattern splitRegex = Pattern.compile("~");
while ((line = bufferedReader.readLine()) != null)
{
String[] tokens = splitRegex.split(line);
// etc.
}
如果使用 ,则每次都会重新编译正则表达式。(Scanner 在首次编译所有正则表达式时会自动缓存它们。如果你这样做,我不希望看到性能有太大差异。String#split(String regex)
你在这里实际上不需要正则表达式,因为你是在固定的字符串上拆分。Apache split 对纯字符串进行拆分。StringUtils
对于大容量拆分,其中拆分是瓶颈,而不是说文件 IO,我发现这比 .但是,我没有针对编译的正则表达式对其进行测试。String.split()
Guava 也有一个拆分器,以更 OO 的方式实现,但我发现它比 StringUtils 慢得多,用于大容量拆分。
在单线程模型中围绕这些做了一些指标,这是我得到的结果。
~~~~~~~~~~~~~~~~~~Time Metrics~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~ Tokenizer | String.Split() | while+SubString | Scanner | ScannerWithCompiledPattern ~ ~ 4.0 ms | 5.1 ms | 1.2 ms | 0.5 ms | 0.1 ms ~ ~ 4.4 ms | 4.8 ms | 1.1 ms | 0.1 ms | 0.1 ms ~ ~ 3.5 ms | 4.7 ms | 1.2 ms | 0.1 ms | 0.1 ms ~ ~ 3.5 ms | 4.7 ms | 1.1 ms | 0.1 ms | 0.1 ms ~ ~ 3.5 ms | 4.7 ms | 1.1 ms | 0.1 ms | 0.1 ms ~ ____________________________________________________________________________________________________________
结果是 Scanner 提供了最好的性能,现在需要在多线程模式下进行评估!我的一位前辈说 Tokenizer 会给出 CPU 峰值,而 String.split 不会。
评论