Chromium ICU库定制裁剪

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环境成功编译:

  1. Chromium中ICU工程可独立于Chromium源代码编译。我们从https://chromium.googlesource.com/chromium/deps/icu 中获取一份最新的代码,然后切到与我们工程一致的提交。假定我们把ICU代码存到$CHROME_ICU_TREE_TOP目录。
  2. 运行${CHROME_ICU_TREE_TOP}/source/runConfigureICU Linux –disable-layout,会生成一些编译配置文件。
  3. 运行 make命令开始编译。这次编译到一半会失败,提示缺少css3transform.res文件,这是已知bug。
  4. 运行${CHROME_ICU_TREE_TOP}/scripts/make_n_copy_data.sh。运行这个脚本会生成第3步所需的文件。
  5. 再次运行make命令编译代码,待编译完成会生成${CHROME_ICU_TREE_TOP}/data/out/temp/icudt*l.dat文件。这个icudt*l.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。

这个文件裁剪是比较保守的,更激进的剪裁就不赘述了。

发表评论

电子邮件地址不会被公开。 必填项已用*标注