我正在用Java实现Prolog引擎的一个(当前很小的)子集。 我正在努力加快术语的统一。特别是关于字符串比较的内容。
我的想法是实习(通过String.intern()
方法)所有表示原子的字符串,因此可以使用引用比较(==
)而不是调用{{1来将两个原子视为等于方法。
在阅读本网站中类似问题的答案后(例如When should we use intern method of String on String constants),这些是我的结论:
我有没有预见到的缺点?或者,在涉及大量数据的情况下,是否有更好的替代方案来提高性能并减少内存占用?
答案 0 :(得分:0)
实习生的问题是它只适用于您创建的字符串,因为其他字符串无法保证将使用实习字符串。您可以通过实习所有字符串来解决这个问题,但这本身就很慢。你需要衡量这种影响,看看你是否在整体上保存了任何东西。
更好的方法可能是定义对象来表示原子并对这些对象进行自己的映射/缓存,以确保它们对于您正在进行的比较是正确的。
使用工厂:
public class AtomFactory {
Map<String, Atom> atoms;
public static Atom buildAtom(String atom) {
return atoms.get(atom);
}
}
如果您提前知道完整的原子列表,可以预先确定映射并将方法名称更改为getAtom
,否则您需要在继续操作时添加新条目,并且可能需要同步访问线程安全。
答案 1 :(得分:0)
对原子使用实习字符串看起来非常合适。
但是,对于每个原子,您可能还有一个唯一的Atom对象。因此,当您在Prolog级别比较原子时,您只会比较Atom对象引用,而不是其中包含的字符串。所以你不会在原子比较中获得任何东西。
在给定名称字符串的情况下,必须找到Atom对象的Prolog系统中的位置非常有限:基本上是read-predicates和atom_codes / chars / string转换原语。这些将受益于字符串实习。
在你的系统中,你可能还会为每个仿函数都有一个对象,即Name / Arity对。一些谓词,特别是functor / 3,必须从相应的原子中找到一个仿函数,反之亦然。根据您组织数据结构的方式,这可能涉及也可能不涉及比较字符串。