1

我有一个程序可以String使用原始文本读取和处理数据StringTokenizer

最初StringTokenizer包含大约 1,500 个令牌,程序运行良好。但是原始内容增加了,现在它变成了大约 12,000 个令牌,并且 CPU 消耗大大增加。

我正在调查问题并尝试找出根本原因。该程序使用一个while循环来检查是否有任何令牌剩余,并且根据读取的令牌,将采取不同的操作。我正在检查这些不同的操作,看看是否可以改进这些操作。

同时,我想问一下,StringTokenizer与处理 10 个 short 相比,处理一个 long 长度是否会花费更多的 CPU StringTokenizer

4

3 回答 3

1

根据StringTokenizer java doc ,不鼓励使用 StringTokenizer 。虽然它没有被弃用,所以它可以使用。只是不推荐。这是写的:

“StringTokenizer 是一个遗留类,出于兼容性原因,尽管不鼓励在新代码中使用它。建议任何寻求此功能的人使用 String 的 split 方法或 java.util.regex 包。”

请检查以下帖子。它有一个很好的例子,说明了做同样事情的各种方法。

stringtokenizer-class-vs-split-method-in-java 的性能

您可以尝试那里提供的示例,看看最适合您的示例。

于 2011-09-14T10:50:43.927 回答
1

首先,感谢您的意见。上周末,我使用修改后的程序对真实数据进行了压力测试,很高兴我的问题得到了解决(非常感谢 AJ ^_^)。我想分享我的发现。

在研究了 AJ 提到的示例之后,我运行了一些测试程序来使用 StringTokenizer 和“indexOf”读取和处理数据(在我的情况下,Regex 比 StringTokenizer 更差)。我的测试程序将计算处理 24 条消息(每个约 12000 个令牌)需要多少微秒。

StringTokenizer 需要约 2700 毫秒才能完成,而“indexOf”只需要约 210 毫秒!

然后,我像这样修改了我的程序(更改最少),并在上周末用实际音量进行了测试:

原程序:

public class MsgProcessor {
    //Some other definition and methods ...

    public void processMessage (String msg) 
    {
        //...

        StringTokenizer token = new StringTokenizer(msg, FieldSeparator);
        while (token.hasMoreTokens()) {
            my_data = token.nextToken();
            // peformance different action base on token read
        }
    }
}

这里是使用“indexOf”更新的程序:

public class MsgProcessor {
    //Some other definition and methods ...
    private int tokenStart=0;
    private int tokenEnd=0;

    public void processMessage (String msg) 
    {
        //...
        tokenStart=0;
        tokenEnd=0;

        while (isReadingData) {
            my_data = getToken(msg);
            if (my_data == null)
                break;
            // peformance different action base on token read ...
        }
    }

    private String getToken (String msg)
    {
        String result = null;
        if ((tokenEnd = msg.indexOf(FieldSeparator, tokenStart)) >= 0) {
            result = msg.substring(tokenStart, tokenEnd);
            tokenStart = tokenEnd + 1;
        }
        return result;
    }
}
  • 请注意,原始令牌中没有“空”数据。如果没有找到 FieldSeparator,“getToken(msg)”将返回 null(作为“没有更多令牌”的信号)。
于 2011-09-19T04:06:36.117 回答
0

你为什么不试试更新的 Scanner 类呢?可以使用流和文件构建扫描器。不过,不确定它是否比旧的 StringTokenizer 更有效。

于 2011-09-14T10:41:12.283 回答