我有一个小程序,它读取包含类似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类型列表中的宏对象。我可以使用其他类型的数据结构加快进程吗?
答案 0 :(得分:1)
我建议创建一个脚本,例如Perl
实际执行文件处理并使用ProcessBuilder从Java
代码调用该脚本。{
为每个问题使用最好的工具。
答案 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)时间。总的来说,一旦创建了一组宏名称,它就需要(令牌数)时间。