【问题标题】:Optimizing string comparison in a Prolog implementation embedded in Java在嵌入 Java 的 Prolog 实现中优化字符串比较
【发布时间】:2013-12-28 22:54:24
【问题描述】:

我正在用 Java 实现 Prolog 引擎的一个(目前很小)子集。 我正在努力加快术语的统一。特别是关于字符串比较的问题。

我的想法是实习(通过String.intern() 方法)所有代表原子的字符串,因此可以使用参考比较(==)而不是调用String.equals() 方法将两个原子视为相等。

阅读本网站中类似问题的答案(例如,When should we use intern method of String on String constants)后,我得出以下结论:

  • 我应该在原子比较方面的性能有所提高。
  • 使用 intern 方法时,内存占用也应该稍微低一些。
  • Atom 实例化可能会减慢一点。

有没有我没有预见到的缺点?或者在涉及大量数据的情况下,是否有更好的替代方案来提高性能并减少内存占用?

【问题讨论】:

    标签: java string performance prolog


    【解决方案1】:

    intern 的问题在于它只适用于您创建的字符串,因为您无法保证输入的其他字符串会使用实习生字符串。您可以通过实习所有字符串来解决这个问题,但这本身就很慢。你需要衡量这种影响,看看你是否在大局中节省了任何东西。

    更好的方法可能是定义对象来表示原子并对这些对象进行自己的映射/缓存,以确保它们对于您正在进行的比较是正确的。

    使用工厂:

     public class AtomFactory {
          Map<String, Atom> atoms;
          public static Atom buildAtom(String atom) {
              return atoms.get(atom);
          }
     }
    

    如果您提前知道完整的原子列表,您可以预先填写映射并将方法名称更改为getAtom,否则您需要在继续时向其中添加新条目,并且可能需要同步线程安全访问。

    【讨论】:

    • 我确实有一个表示 Atom 的对象,该对象在其构造函数中接收字符串。我的想法是在这样的字符串上调用 intern() 以便所有原子都使用实习生表示。
    • 改用工厂,每个字符串只有一个 Atom 对象。见编辑。
    • 但是为什么确保原子具有单一表示应该比使用内部字符串更快?我的意思是,在内部使用依赖于原子图的工厂也会有性能损失。另外,正如我在之前的评论中所说,如果我在 Atom 构造函数中调用 intern(),我不需要担心字符串是如何实例化的,因为我将始终保留实习字符串。
    【解决方案2】:

    对原子使用内部字符串看起来非常合适。

    但是,对于每个原子,无论如何,您可能都有一个唯一的 Atom 对象。因此,当您在 Prolog 级别比较原子时,您只会比较 Atom 对象引用,而不是其中包含的字符串。所以在原子比较中你不会有任何收获。

    在 Prolog 系统中,您必须在给定名称字符串的情况下找到 Atom 对象的位置非常有限:基本上是读取谓词和 atom_codes/chars/string 转换原语。这些将受益于字符串的实习。

    在您的系统中,您可能还会为每个仿函数创建一个对象,即名称/Arity 对。一些谓词,特别是 functor/3,必须从相应的 atom 中找到一个 functor,反之亦然。根据您组织数据结构的方式,这可能涉及也可能不涉及比较字符串。

    【讨论】:

      猜你喜欢
      • 2013-08-12
      • 2011-04-22
      • 2022-11-21
      • 1970-01-01
      • 1970-01-01
      • 2011-05-03
      • 2013-01-26
      • 2014-11-11
      • 2012-06-28
      相关资源
      最近更新 更多