Java的Scanner vs String.split()vs StringTokenizer; 我该用哪个?

10 java regex split java.util.scanner

我目前正在使用split()扫描文件,其中每行包含多个字符串'~'.我读到某个地方Scanner可以用一个长文件做得更好,性能方面,所以我考虑检查出来.

我的问题是:我是否必须创建两个实例Scanner?也就是说,一个读取一行而另一个基于该行来获取分隔符的标记?如果我必须这样做,我怀疑我是否会从使用它中获得任何好处.也许我在这里错过了一些东西?

小智 8

在单线程模型中有一些关于这些的指标,这是我得到的结果.

~~~~~~~~~~~~~~~~~~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则没有.


Jer*_*ese 6

对于处理线,您可以使用扫描仪,并从您可以使用拆分的每一行获取令牌.

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();
}
Run Code Online (Sandbox Code Playgroud)


Ala*_*ore 5

您可以使用该useDelimiter("~")方法让您遍历每行上的标记hasNext()/next(),同时仍然使用hasNextLine()/nextLine()迭代遍历行本身.

编辑:如果你要进行性能比较,你应该在进行split()测试时预编译正则表达式:

Pattern splitRegex = Pattern.compile("~");
while ((line = bufferedReader.readLine()) != null)
{
  String[] tokens = splitRegex.split(line);
  // etc.
}
Run Code Online (Sandbox Code Playgroud)

如果使用String#split(String regex),每次都会重新编译正则表达式.(扫描程序在第一次编译它们时会自动缓存所有正则表达式.)如果你这样做,我不希望看到性能上有太大差异.


Coo*_*une 3

我想说的split()是最快的,并且对于你正在做的事情来说可能已经足够好了。它的灵活性比不过scannerStringTokenizer已弃用,仅用于向后兼容,因此请勿使用它。

编辑:您始终可以测试这两种实现,看看哪一种更快。我自己很好奇是否scanner可以比split(). 对于给定大小的 VS , Split 可能会更快Scanner,但我不能确定这一点。