TinyPinyin
 Introduction:  适用于 Java 和 Android 的快速、低内存占用的汉字转拼音库。
 Tags:  
拼音-适用于 Java 和 Android 的快速、低内存占用的汉字转拼音库。
当前稳定版本:2.0.3
特性
- 生成的拼音不包含声调,均为大写;
 - 支持自定义词典,支持简体中文、繁体中文;
 - 执行效率很高(Pinyin4J 的 4~16 倍);
 - 很低的内存占用(不添加词典时小于 30KB)。
 
原理介绍
打造最好的 Java 拼音库 TinyPinyin(一):单字符转拼音的极致优化
打造最好的 Java 拼音库 TinyPinyin(二):多音字快速处理方案
打造最好的 Java 拼音库 TinyPinyin(三):API 设计和测试实践
使用
汉字转拼音 API
/**
 * 如果 c 为汉字,则返回大写拼音;如果 c 不是汉字,则返回 String.valueOf(c)
 */
String Pinyin.toPinyin(char c)
/**
 * c 为汉字,则返回 true,否则返回 false
 */
boolean Pinyin.isChinese(char c)
/**
 * 将输入字符串转为拼音,转换过程中会使用之前设置的用户词典,以字符为单位插入分隔符
 */
String toPinyin(String str, String separator)
词典 API
// 添加中文城市词典
Pinyin.init(Pinyin.newConfig().with(CnCityDict.getInstance());
// 添加自定义词典
Pinyin.init(Pinyin.newConfig()
            .with(new PinyinMapDict() {
                @Override
                public Map<String, String[]> mapping() {
                    HashMap<String, String[]> map = new HashMap<String, String[]>();
                    map.put("重庆",  new String[]{"CHONG", "QING"});
                    return map;
                }
            }));
添加到工程
buildscript {
  repositories {
    maven {
      url 'https://maven.aliyun.com/repository/public'
    }
    mavenCentral()
  }
  dependencies {
    compile 'com.github.promeg:tinypinyin:2.0.3' // TinyPinyin 核心包,约 80KB
    compile 'com.github.promeg:tinypinyin-lexicons-android-cncity:2.0.3' // 可选,适用于 Android 的中国地区词典
    compile 'com.github.promeg:tinypinyin-lexicons-java-cncity:2.0.3' // 可选,适用于 Java 的中国地区词典
  }
}
详细说明
1. 设计目标
Pinyin4J 的问题
- Jar 文件较大,205KB;
 - Pinyin4J 的 PinyinHelper.toHanyuPinyinStringArray 在第一次调用时耗时非常长(~2000ms);
 - 功能臃肿,许多情况下我们不需要声调、方言;
 - 无法添加自定义词典,进而无法有效处理多音字
 - 内存占用太高;
 
TinyPinyin 特性
- 转换后的结果不包含声调和方言;
 - 支持自定义词典,方便处理多音字;
 - 尽可能低的内存占用;
 - 比 Pinyin4J 更快的转换速度;
 
2. Correctness
以 Pinyin4J 作为基准,确保对所有的字符(Character.MAX_VALUE ~ Character.MIN_VALUE),TinyPinyin 与 Pinyin4J 有相同的返回结果。
(Pinyin4J 采用无声调的输出,多音字取第一个拼音进行对比)
该部分请见 PinyinTest.java
繁体中文的测试请见:PinyinTest.testToPinyin_traditional_chars()
采用以下命令运行 test:
./gradlew clean build :lib:test :tinypinyin-lexicons-android-cncity:test :tinypinyin-android-asset-lexicons:test :android-sample:connectedAndroidTest
3. Effectiveness
速度
使用JMH工具得到 bechmark,对比 TinyPinyin 和 Pinyin4J 的运行速度。
具体测例请见 lib/src/jmh/中的性能测试代码。
采用以下命令运行 benchmark:
./gradlew jmh
生成的报告在 pinyinhelper/build/reports/jmh/ 中。
性能测试结果简要说明:单个字符转拼音的速度是 Pinyin4j 的四倍,添加字典后字符串转拼音的速度是 Pinyin4j 的16 倍。
详细测试结果:
| Benchmark | Mode | Samples | Score | Unit | 
|---|---|---|---|---|
| TinyPinyin_Init_With_Large_Dict(初始化大词典) | thrpt | 200 | 66.131 | ops/s | 
| TinyPinyin_Init_With_Small_Dict(初始化小词典) | thrpt | 200 | 35408.045 | ops/s | 
| TinyPinyin_StringToPinyin_With_Large_Dict(添加大词典后进行 String 转拼音) | thrpt | 200 | 16.268 | ops/ms | 
| Pinyin4j_StringToPinyin(Pinyin4j 的 String 转拼音) | thrpt | 200 | 1.033 | ops/ms | 
| TinyPinyin_CharToPinyin(字符转拼音) | thrpt | 200 | 14.285 | ops/us | 
| Pinyin4j_CharToPinyin(Pinyin4j 的字符转拼音) | thrpt | 200 | 4.460 | ops/us | 
| TinyPinyin_IsChinese(字符是否为汉字) | thrpt | 200 | 15.552 | ops/us | 
| Pinyin4j_IsChinese(Pinyin4j 的字符是否为汉字) | thrpt | 200 | 4.432 | ops/us | 
内存占用
1. 不添加词典时
- 3 个 static byte[7000] 存储所有汉字的拼音的低 8 位,占用 7000 1 3 = 21KB 内存;
 - 3 个 static byte[7000/8] 存储所有汉字的拼音的第 9 位(最高位),占用 7000 / 8 1 3 = 3KB 内存;
 - 一个 String[408] 存储所有可能的拼音,占用 1.7KB 内存;
 
共占用 < 30KB.
2. 添加词典时
使用‘com.github.promeg:tinypinyin-lexicons-java-cncity:2.0.0’时,额外消耗约 43KB 内存。
Todo
支持繁体中文- 支持姓氏拼音
 - 压缩词库
 - 词库生成工具
 
