用 DAT 重实现 CppJieba 中文分词算法,降低 99% 内存消耗

一,问题背景

中文分词应用比较广泛的开源算法,是 jieba 结巴分词,结巴分词较高性能的实现是 C++ 版本的 CppJieba : https://github.com/yanyiwu/cppjieba

在实际使用 CppJieba 的过程中,我们发现 CppJieba 的内存占用比较高。

比如对一个 76W 词 大小 11MB 的词典 ,加载 2份 (比如为了支持平滑改动用户词典)就需要耗费 505MB内存。

这对一些多进程的后台服务,浪费大量内存,难以接受,因此这里希望削减内存耗费。

经过初步调查,确定改进方法,然后动手改造,最终把 505MB 缩减到了 4.7MB ,实现了 99% 内存降低

此处也有 issue 讨论 https://github.com/yanyiwu/cppjieba/issues/3

代码在 https://github.com/byronhe/cppjieba

GB 规模语料上的高性能新词发现算法

分词是中文搜索的重要环节,目前分词算法已经比较成熟,分词错误的主要是由于未登录词。

因此发现业务领域语料库中的新词,减少未登录词,对改善搜索引擎的用户体验有重要意义。

新词发现的一种常用算法,是 matrix67 大神 2012 年提出的 《互联网时代的社会语言学:基于SNS的文本数据挖掘》 https://www.matrix67.com/blog/archives/5044

其主要思路,是统计语料中出现的所有 ngram 子字符串的凝固度,自由度,信息熵。

算法中需要统计所有 ngram 子字符串的 左熵右熵,实现该算法时,一般以子字符串为 key,用哈希表来存。

但随着语料库变大时,内存消耗变大,

比如之前的 python 版本实现,对 200MB 的语料,就需要约 30G 内存来存哈希表,

导致单机内存不足无法运行,而且对这样规模的语料库,算法需要跑一两天才能出结果。

这里我应用一些工程实现方面的技巧, 把用哈希表统计左熵右熵的计算,拆分成多个子哈希表,分批计算,并利用多核并行,大幅度优化了算法的性能。

gif 缩放算法及相关资料

http://giflib.sourceforge.net/whatsinagif/index.html http://giflib.sourceforge.net/whatsinagif/bits_and_bytes.html https://gif.ski/ gifski 可以从视频生成高质量的 gif 浓缩的才是精华:浅析 GIF 格式图片的存储和压缩 https://cloud.tencent.com/developer/article/1004763 用av1视频替代 gif https://www.singhkays.com/blog/its-time-replace-gifs-with-av1-video “Replace animated GIFs with video for faster page loads” : https://web.dev/replace-gifs-with-videos/ https://web.dev/efficient-animated-content/ http://blog.pkh.me/p/21-high-quality-gif-with-ffmpeg.html 每帧一个调色板,就

借助 ext4 文件系统的 打洞 功能实现消息队列

借助 ext4 文件系统的 打洞 功能,可以实现一个消息队列 https://gist.github.com/CAFxX/571a1558db9a7b393579 1 fallocate(fd, FALLOC_FL_PUNCH_HOLE|FALLOC_FL_KEEP_SIZE, offset, length); Punching holes in files https://lwn.net/Articles/415889/ 怎样对大文件的中间部分进行增删? 首先,如果复制/写文件的后半段的话,肯定

Proxygen http2 代码分析

Proxygen 的整体架构 image

一个 HTTPSession 对应一个 tcp 连接。

HTTPSession 中包含HTTPCodec ,HTTPCodec用来在 HTTPMessage(Request/Response) 和 字节流之间做转换(就是解析/序列化)。

一个 HTTPTransaction 对应一个 HTTP2 的Stream ,也就是一次 Req/Resp Handler 是业务逻辑处理的基类。