3

我正在做一个项目,我正在使用由向量编码的单词,这些单词大约有 2000 个浮点数。现在,当我将这些与原始文本一起使用时,我需要检索每个单词遇到的向量并对其进行一些计算。不用说,对于大量词汇(约 100k 单词),这需要大量存储空间(文本文件中大约 8 GB)。

我最初有一个系统,我将大文本文件拆分为较小的文件,然后对于特定的单词,我读取它的文件,并检索它的向量。正如你想象的那样,这太慢了。

接下来我尝试将所有内容读入 RAM(大约需要 40GB RAM),因为一旦读入所有内容,它会非常快。但是,读入需要很长时间,缺点是我只能使用某些具有足够空闲 RAM 的机器来执行此操作。但是,一旦加载数据,它就会比其他方法快得多。

我想知道数据库将如何与这些方法进行比较。检索会比 RAM 方法慢,但不会有开销要求。此外,任何其他想法都会受到欢迎,我自己也有其他想法(即缓存,使用将所有内容加载到 RAM 中的服务器等)。我可能会对数据库进行基准测试,但我想我会在这里发帖看看其他人要说什么。

谢谢!

更新

我使用了泰勒的建议。尽管就我而言,我认为 BTree 是不必要的。我只是散列了单词和它们的偏移量。然后我可以在运行时查找一个单词并读取它的向量。我缓存了文本中出现的单词,因此每个向量最多只读入一次,但这节省了读取和存储不需要的单词的开销,使其优于 RAM 方法。

仅供参考,我使用了 Java 的 RamdomAccessFile 类并使用了 readLine()、getFilePointer() 和 seek() 函数。

感谢所有为这个线程做出贡献的人。

更新 2

如需更多性能改进,请查看缓冲的 RandomAccessFile: http: //minddumped.blogspot.com/2009/01/buffered-javaiorandomaccessfile.html

显然 RandomAccessFile 中的 readLine 非常慢,因为它逐字节读取。这给了我一些不错的改进。

4

2 回答 2

3

作为一项规则,任何自定义编码都应该比通用数据库快得多,前提是您已经对其进行了有效编码。

有特定的 C 库可以使用 B 树来解决此问题。过去有一个著名的图书馆,叫做“B-trieve”,因为速度快而非常受欢迎。在这个应用程序中,B-tree 将比使用数据库更快速、更容易。

如果您想要获得最佳性能,您将使用称为后缀树的数据结构。有些库旨在创建和使用后缀树。这将为您提供最快的单词查找。

在任何一种情况下,都没有理由将整个数据集存储在内存中,只需将 B 树(或后缀树)与内存中数据的偏移量存储在一起。这将需要大约 3 到 5 兆字节的内存。当您查询树时,您会得到一个偏移量。然后打开文件,向前寻找偏移量并从磁盘读取向量。

于 2013-05-26T18:47:56.890 回答
2

您可以使用一个简单的基于文本的索引文件,只将单词映射到索引,另一个文件只包含每个单词的原始矢量数据。最初,您只需将索引读取到哈希映射,该哈希映射将每个单词映射到数据文件索引并将其保存在内存中。如果需要某个单词的数据,则计算数据文件中的偏移量(2000 * 32 * index)并根据需要读取。您可能希望将此数据缓存在 RAM 中(如果您在 java 中,可能只是使用弱映射作为起点)。

这基本上是在实现您自己的原始数据库,但它可能仍然是可取的,因为它避免了数据库设置/部署的复杂性。

于 2013-05-26T19:39:32.150 回答