Chromium ICU 库定制裁剪
发布于 2015-10-22
ICU库是一个支持国际化,本地化的软件库。最近在研究ICU库,有点心得,总结一下。
ICU库功能介绍
- 支持最新的Unicode标准。
- 不同代码页的字符集转换。
- 本地化数据,如:数字、日期、货币等等。
- 语言相关的字符串处理,如:排序、搜索等等。
- 正则表达式支持。
- 语言转换。
- 阿拉伯语、希伯来语、印度语、泰语等文字排版。
- 文本分词。
编译步骤
Chromium项目中的ICU是经过Chromium开发人员精简过的,目前在Windows环境中无法成功编译。Chromium团队也是在Linux下编译,然后把文件Push到代码仓库中。 根据README.chromium文件中“Pre-built data files are checked in with the following steps on Linux”的描述可在Linux环境成功编译:
- Chromium中ICU工程可独立于Chromium源代码编译。我们从https://chromium.googlesource.com/chromium/deps/icu 中获取一份最新的代码,然后切到与我们工程一致的提交。假定我们把ICU代码存到$CHROME_ICU_TREE_TOP目录。
- 运行${CHROME_ICU_TREE_TOP}/source/runConfigureICU Linux –disable-layout,会生成一些编译配置文件。
- 运行 make命令开始编译。这次编译到一半会失败,提示缺少css3transform.res文件,这是已知bug。
- 运行${CHROME_ICU_TREE_TOP}/scripts/make_n_copy_data.sh。运行这个脚本会生成第3步所需的文件。
- 再次运行make命令编译代码,待编译完成会生成${CHROME_ICU_TREE_TOP}/data/out/temp/icudtl.dat文件。这个icudtl.dat文件就是我们所需要的。
定制词条
中文词条是存放在icusourcedatabrkitrcjdict.txt文件中的。新增一个词条然后再赋予一个权重。简单验证增加新词条的方法是在网页的文字上点击这个词条的文字,如果点击词条能够正确的分词选中,则表示新词条增加成功。
裁剪方法
ICU库实现了丰富的国际化和本地化功能支持,其功能大多是基于数据驱动的。在icusourcedata目录下面有大量的数据文件,这些数据文件也是最终组成icudtl.dat文件的大部分。 如果要裁剪ICU库,裁剪功能的难度比较大,要解决代码的编译依赖,编译选项等等。另外如果某个功能被Chromium依赖,裁剪掉会有一定风险。 裁剪ICU库的数据文件比较合适,比如仅仅是为了中文分词的cjdict.txt文件就高达3.99MB,缅甸语分词的文件burmesedict.txt有1.1MB。所以裁剪这类数据文件的效果是比较明显的。即使数据去除,这些功能代码接口还在,影响面较小。
浏览器分析
Chromium 提供的icudtl.dat文件有9.73MB,相对来说还是比较大的。目前看市面上其他的浏览器情况:
- 360安全浏览器(7.1.1.808)的icudt.dll是5.57MB,可以进行精确的中文分词。
- 猎豹浏览器(5.3.108.10480)的icudtl.dat是2.57MB,不能进行精确的中文分词。
- 搜狗浏览器没有icudt.d文件,不能进行精确的中文分词。
- QQ浏览器(9.1.4060.400)的icudtl.dat是10.0MB,可以进行精确的中文分词。
- 百度浏览器(7.6.100.234)的icudtl.dat是9.72MB,可以进行精确的中文分词。
可以推测:
- 360安全浏览器去除了大部分数据文件,仅保留中英文相关数据文件。
- 猎豹浏览器去除所有数据文件。
- 搜狗浏览器不详。
- QQ浏览器几乎没有做裁剪。icudtl.dat文件还稍微大了一点,测试了“腾讯”等特殊相关词,也没有分词效果。可能是跟QQ浏览器icudtl.dat版本有关。
- 百度浏览器对icudtl.dat没有修改。
另外,直接用文本编辑器打开icudt.d文件,也可以看到哪些文件数据文件被编译进来了。
数据文件介绍
只有知道数据文件都是用来做什么,我们才有把握进行剪裁,否则会引入bug。在icusourcedata目录中:
- brkitr目录中的文件是用来断开文本的。以dict.txt命名的文件是词库。line.txt文件是分行规则,word*.txt是分词规则。还有其他文件,只有几K大小,可以忽略。
- coll目录中的文件是语言相关的字符串处理(Unicode Collation Algorithm)的数据文件。
- curr目录中的文件是货币代码数据。
- lang目录中的文件是语言数据。
- locales目录中的文件是文字的本地化数据。
- mappings目录中的文件是文字的code page转换映射数据。
- misc目录中的文件是其他的数据文件,比如时区、日历等等。
- rbnf目录中的文件是数字转换数据文件。
- region是世界地域数据文件。
- sprep目录中的文件是Unicode Code Point数据信息。
- translit目录中的文件是文字转换的数据信息。
- unidata目录中的文件是Unicode数据信息。
- unit目录中的文件是单位数据信息。
- zone目录中的文件是时区数据信息。
文件剪裁
根据编译步骤章节的介绍,运行./source/runConfigureICU Linux –disable-layout 命令就会生成编译配置文件。在icusourcedata的子目录里有个*local.mk文件,编辑这个文件就可以决定哪些数据文件被编译。原始icudtl.dat文件有9.73MB,以下就是每个子目录迭代剪裁的情况:
- brkitr目录:裁掉burmesedict.txt 、khmerdict.txt、 laodict.txt、thaidict.txt文件,去掉cjdict.txt文件的日文词条。最终生成icudtl.dat文件8.76MB。
- coll目录去掉非中英文的大数据文件,最终生成icudtl.dat文件8.32MB。
- curr目录去掉非中英文的大数据文件,最终生成icudtl.dat文件8.21MB。
- lang目录去掉非中英文的大数据文件,最终生成icudtl.dat文件7.88MB。
- locales目录去掉非中英文的大数据文件,最终生成icudtl.dat文件7.08MB。
- mappings目录去掉日语的大数据文件,最终生成icudtl.dat文件6.81MB。
- region目录去掉日语的大数据文件,最终生成icudtl.dat文件6.50MB。
这个文件裁剪是比较保守的,更激进的剪裁就不赘述了。