如何加快列表比较/字符串替换?

时间:2013-04-16 10:36:24

标签: java performance comparison

我有一个小程序,它读取包含类似C的宏的输入文件。处理过程分两次:第一次搜索宏定义并存储它们,第二次搜索宏调用并扩展/替换它们。

这一切都很好用,但这很费时间。目前,我就是这样做的:

foreach token in file:
    foreach macro in macroDefinitions:
        if token equals macro.name:
            expand()
        endif
    end foreach
endforeach

在这个伪示例中,'token'是来自源文件的单词,'macro'是来自第一遍的宏定义。大约有20 000个宏定义和1800个输入文件,总共处理大约600 000行(并且每行被分成n个令牌)。这意味着总比较计数是(令牌数)*(宏定义计数)。我怎么能加快速度呢?我错过了什么,或者我真的必须做所有这些比较吗?

有关其他信息,标记是String []数组中的字符串,并且宏是ArrayList类型列表中的宏对象。我可以使用其他类型的数据结构加快进程吗?

5 个答案:

答案 0 :(得分:1)

我建议创建一个脚本,例如Perl实际执行文件处理并使用ProcessBuilderJava代码调用该脚本。{ 为每个问题使用最好的工具。

答案 1 :(得分:1)

您需要使用从宏名称映射到其定义的Map

在伪代码中:

for each token in file:
    if this is a macro defininition:
        name, definition <- parse definition
        map.put(name, definition)

for each token in file:
    if map.contains(token):
        definition <- map.get(token):
        expand definition

更新 - 您可以摆脱contains来电,只需致电get,然后测试null。值得一读javadoc更好地了解Map,TreeMap和HashMap API的工作原理。)

Map的典型实现使用平衡二叉树或哈希表,并且具有复杂度O(logN)O(1)的查找和插入操作(在正常情况下)。

答案 2 :(得分:0)

将宏定义放在Map中将大大减少查找宏所需的时间。

答案 3 :(得分:0)

编辑:如果您可以添加密钥,KlasLindbäck解决方案会更好。如果你不能像我提出的那样搜索算法将是提高搜索速度的一种方法。

您可以添加一些搜索算法,例如Binary search,这会极大地改善搜索结果

答案 4 :(得分:0)

您可以使用包含宏定义名称的HashSet,并为每个令牌检查它是否包含在集合中:

for(String token : token) {
    if(macroNamesSet.contains(token)) {
        expand();
    }
}

contains方法需要O(1)时间。总的来说,一旦创建了一组宏名称,它就需要(令牌数)时间。