【问题标题】:Why does Lucene use arrays instead of hash tables for its inverted index?为什么 Lucene 的倒排索引使用数组而不是哈希表?
【发布时间】:2017-12-26 23:41:21
【问题描述】:

我正在观看 Adrien Grand 的 talk on Lucene's index architecture,他指出 Lucene 使用排序数组来表示其倒排索引的字典部分。使用排序数组而不是哈希表(“经典”倒排索引数据结构)背后的原因是什么?

哈希表提供 O(1) 的插入和访问,在我看来这对快速处理查询和合并索引段有很大帮助。另一方面,排序数组只能提供 O(logN) 访问和 (gasp) O(N) 插入,尽管合并 2 个排序数组与合并 2 个哈希表的复杂性相同。

我能想到的哈希表的唯一缺点是更大的内存占用(这确实可能是一个问题)和缓存友好性较低(尽管查询排序数组之类的操作需要二进制搜索,这与缓存不友好一样)。

那么怎么了? Lucene 开发人员一定有充分的理由使用数组。它与可扩展性有关吗?磁盘读取速度?完全不同的东西?

【问题讨论】:

标签: arrays indexing lucene hashmap hashtable


【解决方案1】:

好吧,我将在这里推测(可能应该是一个评论 - 但它会太长)。

  1. HashMap 通常是一种快速查找结构,其搜索时间为O(1) - 意味着它是恒定的。但这是一般情况;因为(至少在 Java 中)HashMap 使用 TreeNodes - 在该存储桶内搜索是 O(logn)。即使我们认为他们的搜索复杂度是O(1),这并不意味着它在时间上是相同。它只是意味着它对于每个单独的数据结构都是恒定的。

  2. Memory Indeed - 我将举一个例子here。简而言之,存储15_000_000 条目将需要多于1GB 的RAM;排序后的数组可能更紧凑,特别是因为它们可以保存基元,而不是对象。

  3. 将条目放入HashMap(通常)需要所有重新散列的键,这可能会对性能造成重大影响,因为它们都必须潜在地移动到不同的位置。

  4. 这里可能有一个额外的点 - 在范围内搜索,这可能需要一些 TreeMap,其中数组更适合这里。我正在考虑对索引进行分区(可能是他们在内部进行的)。

  5. 我的想法和你一样——数组通常是连续的内存,可能更容易被 CPU 预取。

  6. 最后一点:设身处地为他们着想,我会先从HashMap 开始...我相信他们的决定有令人信服的理由。我想知道他们是否有实际测试来证明这种选择。

【讨论】:

  • 感谢您的回答!我认为这也可能与 Lucene 必须泛化到的不仅仅是文本术语有关,并且散列任意术语可能会很受欢迎。但我会看看我是否可以做一些实验,看看HashMap 和数组如何比较文本索引。
  • 不要忘记他们设置的不变性。
  • @AnthonyDeMeulemeester 我不知道 lucene 是如何设置的,比如零知识,谢谢反馈
  • Lucene 为您索引的每个文档创建一个段,当段太多时,它们会将它们合并为一个段。这使其不可变,因为它们不会更新现有内存。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-07
  • 2011-08-15
  • 2019-08-05
  • 2011-07-12
  • 1970-01-01
  • 2023-03-11
  • 2014-08-09
相关资源
最近更新 更多