【发布时间】:2013-05-26 18:40:38
【问题描述】:
我正在做一个项目,我正在使用由向量编码的单词,这些单词大约有 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 非常慢,因为它逐字节读取。这给了我一些不错的改进。
【问题讨论】:
-
以二进制文件格式存储数据怎么样?
-
需要更多信息来回答这个问题。你只需要检索,存储新数据,删除和更新数据呢?您是每个请求只检索一个,还是有应该检索多个结果的查询?就速度而言,什么对您来说更重要?获取数据还是更新数据?更多信息,否则这是一个悬而未决的问题..
-
如果您创建适当的索引,数据库应该最适合您。我会选择 SQLite。
-
为什么要保存整个单词?您不能只保存单独的字母,然后根据某些元数据创建单词吗?
-
@G.Y 是的,我只需要检索 - 无需更新。现在我一次检索一个,尽管我可以要求多个(即一个句子中的所有单词)。