在java中分离String的最快方法

时间:2014-02-22 09:02:18

标签: java string performance

程序需要许多命令,然后需要将命令分解为部分以便它可用,目前有一个非常粗略的版本。希望尽可能快地完成它。这里有一些代码,这是可以理解的:

String keyCommands[] = new String[]{"me","a","new","word","text", "document","notepad"};
String optional[] = new String[]{"hi","Hey","Please","Do you mind"};
String keyWords[] = new String[]{"open","opening","open up","log in", "login","email","quit"};

如果我输入的内容如下:"嘿,请打开一个新的记事本" 什么是从字符串中剥离可选数组中的东西的最快方法,然后将字符串拆分为键命令和关键字。

奖金,但不是必需的:如果在示例中它是开放的,我怎么能得到它只是记录这意味着打开(记住,所有这些数组在我的程序中更大,所以只是检查是否单词open就在其中只适用于这个特定的情况)。

我希望这个问题不要混淆。效率对我来说非常重要。

3 个答案:

答案 0 :(得分:1)

您正在使用的关键字/命令集有多大?输入字符串有多大?你需要多少次这样做一秒钟?你说性能对你来说很重要,但可能性能并不像你想象的那么重要。

是否可以将不是命令或关键字的任何解释为“可选”?这样可以简化问题。

如果您真的想知道绝对最快的方式以您描述的方式处理输入字符串,首先,如果输入作为char输入最好数组,而不是String。根据您从中读取输入的位置,您可以将char s(或byte s,如果在您的情况下更合适)直接读入预分配的数组,处理它,然后重复使用读取下一个输入时的数组。您需要在数组中保留一个索引,指示输入结束的位置。

接下来,假设您确实需要绝对最大性能,下一步可能是手动编码DFA(状态机),它对输入进行单次传递,挑选出你的部分需要并复制它们。这类似于基于DFA的正则表达式引擎在内部执行的操作,但通过仔细的手动编码,您应该能够提供比正则表达式引擎更快的功能。

对于类似的结果,工作少得多,制作一个正则表达式,它是所有命令/关键字/可选短语的联合。正则表达式应以\G开头,以便在上一场比赛结束时将其锚定。 (您可以查找有关在正则表达式中使用\G锚点的信息。)由于您需要高性能,请确保重用单个Pattern对象。在一个循环中,反复匹配输入字符串以拉出碎片。然后,在几个集合中进行成员资格测试,以确定匹配是命令,关键字还是其他内容。

您可以尝试使用哈希集或其他方式查看成员资格测试是否会更快。实际上,trie可能是最快的,但我不认为Java平台中有任何标准类用于搜索trie。

如果您编写自己的trie类,作为奖励,您可以将它与命令集的组合在一起,并且它可以识别给定字符串中的哪一个。

如果你写自己的特里,我想看到它!

另一个想法,再次假设您需要荒谬的性能级别,将使用完美哈希进行成员资格测试,因为您的关键字/命令集是事先知道的。

答案 1 :(得分:0)

分开一个单词用空格分隔的句子,你可以尝试类似的东西:

String input = "Hey please open up a new notepad";
String[] words = input.split("\\s+");

现在单词具有以下结构:

words[0] = "Hey", words[1] = "please", words[2] = "open" and so on.

如果您有复杂的语句,还可以在Java中查看Regular Expressions,以便您可以识别输入语句中的模式并执行适当的命令。

答案 2 :(得分:0)

  

效率对我来说非常重要。

可能是这样。但是,参数解析的效率可能不大。

  • 在程序执行期间只发生一次。

  • 除非它非常复杂(或设计非常糟糕),否则解析可能比引导JVM所需的时间少得多,加载应用程序和其他各种“预热”开销。基于JVM的应用程序,无法快速启动。

所以我建议推迟尝试解析/处理命令参数,直到你的应用程序的其余部分编码,测试并运行。然后执行以下操作:

  1. 基准测试应用程序执行典型任务。如果它“足够快”,那么你就完成了。

  2. 使用CPU性能分析器对应用程序进行概要分析,以计算“大部分”时间内的性能热点。

  3. 确定一个最大热点的潜在优化,并对其进行编码并对其进行测试,然后重新运行您的基准测试,看看您是否实际改进了性能。

    < / LI>
  4. 从步骤2开始重复......直到您用完了有价值的热点和潜在的优化。

  5. 我希望你会发现,尽管你的直觉,你的论证处理永远不会成为性能热点的“头版”。这意味着优化该代码的收益不会大到足以证明这一努力的合理性。


    另一件事是你似乎在做的是某种自然语言处理。如果你正在进行“真实的”语言处理(与简单和启发式的不同),那么这是一个非常困难和技术领域。您最好寻找现有的库并使用它...并依靠库实现者来处理效率问题。