-
Notifications
You must be signed in to change notification settings - Fork 691
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
可以使用mmap的方式了节约TRIE树或字典的内存吗? #3
Comments
@jannson |
设想优化这个的目的不是加快运行速度,而是节约内存。因为我想把它放到一个云主机去运行,内存有限。很多个进程都需要用到分词,都需要加载这个大的字典,若能通过共享内存的方式来使用这个字典就最好了。 This is a bit similar to constructing an on-disk DAWG, which I did a while back. What made that so very sweet was that it could be loaded directly with mmap instead reading the file. If the hash-space is manageable, say 216 or 224 entries, then I think I would do something like this: Keep a list of free indices. (if the table is empty, each chain-index would point at the next index.) This should allow you to mmap and use the table directly, without modification. (scary fast if in the OS cache!) but you have to work with indices instead of pointers. It's pretty spooky to have megabytes available in syscall-round-trip-time, and still have it take up less than that in physical memory, because of paging. 暂且先放弃了。 |
@jannson |
最近找到一些Double Array Trie 实现的trie树,感觉很节约内存,并且还很快。但是我只是用了没有深入测试与研究。 On Sun, Mar 16, 2014 at 2:59 PM, soe-coe notifications@github.com wrote:
|
Double Array Trie确实是个不错的选择,不过我对c++11标准还不太熟悉,就不好献丑了。祝好。 |
了解了一下Double Array Trie,应该能用来节约内存, @jannson 你用的是Darts那个库吗? |
@soe-coe @jannson 现在将此改动弄在 |
谢谢,作者真是有心啊。这样的项目100个顶! @aszxqw 我用的是这个库: http://www.tkl.iis.u-tokyo.ac.jp/~ynaga/cedar/ |
aho-corasick 这个其实比Double Array Trie更适合分词,一次遍历把所有匹配找出来,导师的分词系统用的这个,可惜代码没看懂。 |
@ultimate010 是的,如果我没记错的话,现在的CppJieba的Trie源码实现就是使用aho-corasick 算法。 |
哦,我还是去年看得源代码,当时没有用,现在改了那就更好了。 |
@jannson 之前我也有调查过 term lookup 的数据结构,听说是中文不太适合字典树,状态机省内存但又比较难以理解(至少我看 whoosh的实现的感觉),所以感觉大家做中文搜索的都在用 DAT,当然我没有确切的统计数据。 |
我用 darts 优化了一下 CppJieba 的内存占用,可以减少到原来的 1/100 : https://byronhe.com/post/2019/11/25/cppjieba-darts-DAT-memory_optimize/ 代码在: 有一些不兼容的改动,估计没法直接提 pull request 合并过来,不兼容改动:
|
Hi @byronhe |
都是标准 C++ ,应该可以跨平台。 |
@byronhe
|
保存成一个文件,然后 mmap (MAP_SHARED) 映射到进程地址空间,多进程共享一份内存。 |
多谢,这个特性太有用了,我之前用python写的一个处理方式是,在主进程里加载数据到内存中,然后在多个线程中去访问共享参数。 |
抽空搞成 win32 兼容了,可以试一下。我在 windows 下用 clang++ 编译没问题,不过 MSVC 编译器还没测试。 |
字典或TRIE树只需要在一个进程当中创建一次就可以了,其它进程再次分词的时候只需要读到此TRIE树的内存,而不需要再一次从文件加载并创建字典。使用mmap方式可以节约内存与进一步减少启动时间。
基于mmap的C++ allocator有类似这样的开源项目:
https://github.com/johannesthoma/mmap_allocator
虽然http方式也可以实现集中处理分词的效果,但若mmap相信效率有更好的提升。
The text was updated successfully, but these errors were encountered: