zoukankan      html  css  js  c++  java
  • 汉字转拼音,TinyPinyin、Pinyin4j与JPinyin哪个库更快

    1. 介绍

    本文对TinyPinyin、Pinyin4j与JPinyin三个汉字转拼音库的用法、测试代码及转换的结果做一个简单的总结。

    TinyPinyin

    适用于Java和Android的快速、低内存占用的汉字转拼音库。

    在Android项目中使用时,需要在module app下的build.gradle文件中添加依赖(下同):

    1 compile 'com.github.promeg:tinypinyin:2.0.3'
    2 compile 'com.github.promeg:tinypinyin-lexicons-android-cncity:2.0.3'

    Pinyin4j

    A copy of http://sourceforge.net/projects/pinyin4j, then deploy it to maven central repository.

    compile 'com.belerweb:pinyin4j:2.5.0'

    JPinyin

    汉字转拼音的Java开源类库,在PinYin4j的功能基础上做了一些改进。

    1 compile 'com.github.stuxuhai:jpinyin:1.1.8'

    对于开源库,建议使用之前进入其主页了解当前实现的功能和版本号,毕竟别人的文章作为二手资料,目的在于抛砖引玉。 

    2. 测试

    利用Android Studio建立Android项目PinyinTest来测试,具体的库依赖添加和布局文件可以下载后查看。

    代码用Kotlin编写,入门文章:

    应用运行初始界面:

    界面由一个编辑框(TextInputEditText)和按钮(Button)组成,前者供编辑,后者被点击后开始拼音的转换。

    为方便测试,在布局文件中设置编辑框默认文本为"真正的稳定,不是拿着固定不变的工资熬日子,世界每天都在变化,很多时候我们所谓的稳定,其实是自己的异想天开。真正的自由,是内心的自由,明白自己想走的路,明确自己想要的生活。做任何事情都要付出,怕,畏缩不前,什么都干不成。"。可以编辑成别的内容,但这段文字足以测试三个库转换的差异。

    2.1 按钮点击事件绑定

    "转换"按钮在布局文件中的id为convert_btn,Kotlin代码:

     1 convert_btn.setOnClickListener {
     2     var content: String = content_tiet.text.toString()
     3     if (TextUtils.isEmpty(content)) {
     4         Toast.makeText(this, "请输入内容,谢谢", Toast.LENGTH_SHORT).show()
     5     } else {
     6         tinypinyin(content)
     7         pinyin4j(content)
     8         jpinyin(content)
     9     }
    10 }

    不用findViewById和注解,只需关注实现的功能,这就是Kotlin的简洁性。

    Android库方法TextUtils.isEmpty()在参数为null或者length为0时会返回true,所以,编辑框如果没有内容则提示用户先输入;否则调用自定义的方法。

    2.2 TinyPinyin转换

    方法:

     1 fun tinypinyin(content: String) {
     2     val start_time: Long = System.currentTimeMillis()
     3     val stringBuilder = StringBuilder()
     4     stringBuilder.setLength(0)
     5     for (c in content) {
     6         stringBuilder.append(Pinyin.toPinyin(c))
     7     }
     8     val end_time: Long = System.currentTimeMillis()
     9     Log.i("pinyintest", "tinypinyin time: " +  + (end_time - start_time) + "ms")
    10     Log.i("pinyintest", "tinypinyin content: " + stringBuilder.toString().toLowerCase())
    11 }

    主要代码Pinyin.toPinyin(c),如果字符c为汉字,返回对应的拼音;否则返回字符本身。

    结果:

    tinypinyin time: 9ms
    tinypinyin content: zhenzhengdewending,bushinazhegudingbubiandegongziaorizi,shijiemeitiandouzaibianhua,henduoshihouwomensuoweidewending,qishishizijideyixiangtiankai。zhenzhengdeziyou,shineixindeziyou,mingbaizijixiangzoudelu,mingquezijixiangyaodeshenghuo。zuorenheshiqingdouyaofuchu,pa,weisuobuqian,shenmedouganbucheng。

    2.3 Pinyin4j转换

    方法:

     1 fun pinyin4j(content: String) {
     2     val start_time: Long = System.currentTimeMillis()
     3     val stringBuilder = StringBuilder()
     4     stringBuilder.setLength(0)
     5     val hanyuPinyinOutputFormat = HanyuPinyinOutputFormat()
     6     hanyuPinyinOutputFormat.toneType = HanyuPinyinToneType.WITHOUT_TONE
     7     try {
     8         for (c in content) {
     9             val result = PinyinHelper.toHanyuPinyinStringArray(c, hanyuPinyinOutputFormat)
    10             if (result != null) {
    11                 stringBuilder.append(result[0])
    12             } else {
    13                 stringBuilder.append(c)
    14             }
    15         }
    16     } catch (badHanyuPinyinOutputFormatCombination: BadHanyuPinyinOutputFormatCombination) {
    17         badHanyuPinyinOutputFormatCombination.printStackTrace()
    18     }
    19     val end_time: Long = System.currentTimeMillis()
    20     Log.i("pinyintest", "pinyin4j time: " +  + (end_time - start_time) + "ms")
    21     Log.i("pinyintest", "pinyin4j content: " + stringBuilder.toString().toLowerCase())
    22 }

    相比之下,Pinyin4j的使用要繁琐地多,如代码第5-6行先生成一个HanyuPinyinOutputFormat对象,用来指定是否需要声调等信息;还需为转换过程添加异常处理。

    主要代码PinyinHelper.toHanyuPinyinStringArray(c, hanyuPinyinOutputFormat),如果c为汉字,返回的result非null,取[0]为拼音;否则result为null。因此,必须对结果进行判断,对不同情况做处理。

    结果:

    pinyin4j time: 209ms
    pinyin4j content: zhenzhengdewending,bushinazhegudingbubiandegongziaorizi,shijiemeitiandouzaibianhua,henduoshihouwomensuoweidewending,qishishizijideyixiangtiankai。zhenzhengdeziyou,shineixindeziyou,mingbaizijixiangzoudelu,mingquezijixiangyaodeshenghuo。zuorenheshiqingdouyaofuchu,pa,weisuobuqian,shenmedouganbucheng。

    2.4 JPinyin转换

    方法:

    1 fun jpinyin(content: String) {
    2     val start_time: Long = System.currentTimeMillis()
    3     val stringBuilder = StringBuilder()
    4     stringBuilder.setLength(0)
    5     stringBuilder.append(PinyinHelper.convertToPinyinString(content, "", PinyinFormat.WITHOUT_TONE))
    6     val end_time: Long = System.currentTimeMillis()
    7     Log.i("pinyintest", "jpinyin time: " +  + (end_time - start_time) + "ms")
    8     Log.i("pinyintest", "jpinyin content: " + stringBuilder.toString().toLowerCase())
    9 }

    主要代码PinyinHelper.convertToPinyinString(content, "", PinyinFormat.WITHOUT_TONE),从转换过程来看JPinyin是最方便的。因为它是直接对整个字串content进行处理,不用通过迭代操作每个字符。

    同样地,第三个参数表示忽略声调,而第二个参数指定各个字符转换结果的分隔符,这里是空字串。

    结果:

    jpinyin time: 417ms
    jpinyin content: zhenzhengdewending,bushinazhuogudingbubiandegongziaorizi,shijiemeitiandouzaibianhua,henduoshihouwomensuoweidewending,qishishizijideyixiangtiankai。zhenzhengdeziyou,shineixindeziyou,mingbaizijixiangzoudelu,mingquezijixiangyaodeshenghuo。zuorenheshiqingdouyaofuchu,pa,weisuobuqian,shenmedouganbucheng。

    3. 总结

    除了默认文本,还输入过其他字串进行测试,三个库转换所消耗的时间差异类似。JPinyin介绍是说在Pinyin4j的基础上做的改进,虽然调用方法上简单了,但是转换速度方面竟然要差一些。

    因此,TinyPinyin是在三个库中比较理想的选择,如果进一步深入看它们的实现源码,就能明白为什么速度上有那么大的差异。

    如果大家知道更好的汉字转拼音库,请推荐。

  • 相关阅读:
    艾伟_转载:你知道吗?——ASP.NET的Session会导致的性能问题 狼人:
    艾伟_转载:一次挂死(hang)的处理过程及经验 狼人:
    艾伟也谈项目管理,微型项目实践感悟 狼人:
    艾伟_转载:[原创]再谈IIS与ASP.NET管道 狼人:
    艾伟_转载:企业库缓存依赖的实现基于文件依赖 狼人:
    艾伟也谈项目管理,我也发软件开发团队的思考(侧重点是人员) 狼人:
    MYSQL用户名:root
    map 和 unordered_map以char * 为key
    设计模式单例模式(singleton)
    Android允许其他应用程序启动你的Activity
  • 原文地址:https://www.cnblogs.com/interdrp/p/11695457.html
Copyright © 2011-2022 走看看