开端与场景
接着上一篇文章的地区分词匹配,最近发现有一些内容中全部为英文或者直接就是一些连接URL,理论上根本不可能产生地区特征的关键字,之前的做法却把这些也进行了分词和匹配了。所以一个比较高效的方式就是把文章内容中非中文的字符过滤掉。
集群的数据存储了约8亿的文章,现在进行一次索引的 rebuild .
这涉及了一个对中文字符的判断及过滤了,想必大家对此也很多想法。网上也介绍了几种方式。这里不讨论是否能实现的问题,是讨论实现速度最快的的问题。
方法一:
也是网上最多人使用的方式通过正则表达式,方便又快捷
string.matches( "[\u4e00-\u9fa5]" );
方法二:
也有部分人使用
具体,通过JDK内置的 uncode 变量去判断
private static final boolean isChinese(char c) { Character.UnicodeBlock ub = Character.UnicodeBlock.of(c); if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) { return true; } return false; }
方法三:
通过找到中文 unicode 的范围,把中文的判断变成简单的 int 判断从而达到最高的性能与效率
// 中文的 char 范围 // by kernaling.wong private static int cn_min = (int)"一".charAt(0); //\u4e00 private static int cn_max = (int)"龥".charAt(0); //\u9fa5 // 方法 3 // 通过最原始的 unicode 范围判断 // 把中文变成 int 的判断 private static final boolean isChinese3(char c) { int char_int = (int)c; if( char_int < cn_min || char_int > cn_max ){ return false; }else{ return true; } }
对比的测试效果
我做了一个三种方式性能对比,在判断 100W 个字符的时间,如下图所示
以下是测试的类文件,复制后,直接可以执行
package com.test.logs; /** * * @author kernaling.wong * * 测试中文判断方式的效率与性能 * */ public class Test { // 中文的 char 范围 // by kernaling.wong private static int cn_min = (int)"一".charAt(0); //\u4e00 private static int cn_max = (int)"龥".charAt(0); //\u9fa5 public static void main(String[] args) { try{ String s = "你"; long start = System.currentTimeMillis(); for(int i=0;i<100*10000;i++){ isChinese(s); } start = System.currentTimeMillis() - start; System.out.println("function 1 : " + start); start = System.currentTimeMillis(); for(int i=0;i<100*10000;i++){ isChinese2(s.charAt(0)); } start = System.currentTimeMillis() - start; System.out.println("function 2 : " + start); start = System.currentTimeMillis(); for(int i=0;i<100*10000;i++){ isChinese3(s.charAt(0)); } start = System.currentTimeMillis() - start; System.out.println("function 3 : " + start); }catch(Exception ex){ ex.printStackTrace(); } } // 方法 1 // 通过正则表达式 private static final boolean isChinese(String c) { return c.matches("[\u4e00-\u9fa5]"); } // 方法 2 // 通过JDK内置的 unicode 变量判断 private static final boolean isChinese2(char c) { Character.UnicodeBlock ub = Character.UnicodeBlock.of(c); if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) { return true; } return false; } // 方法 3 // 通过最原始的 unicode 范围判断 // 把中文变成 int 的判断 private static final boolean isChinese3(char c) { int char_int = (int)c; if( char_int < cn_min || char_int > cn_max ){ return false; }else{ return true; } } }
总结
本来对于 这一个中文的判断方式,其实只是在原来的基础上添加一个方法而已,但也正因为这样子导致了性能上有所偏差,在未实现之前,跑 1W 的数据到 solr 用了 19秒,但实现后,同样数据到 solr 用了 9 秒。节省了足足10秒的时间。可能很多人不理解这样子一个简单实现的功能为何劳师动众,在普通的注重功能上实现来说,其实用方法一,方法二,方法三都看不出差别,但对于大数据的集群来说,丝毫的性能差别经过累积却放大很多倍。所以才需要对性能和效率的执着追求。
欢迎连载,请注明来源及作者
http://kernaling-wong.iteye.com/blog/2079091
by kernaling.wong @ 2014.06.13
相关推荐
java判断字符串是否是json或json数组; 简单小方法,很实用;简单实用的方法;亲测可用;嗯嗯嗯呃呃呃呃呃呃呃
Java 正则表达式判断字符串是否包含中文
java判断字符串是否存在递增或递减 java判断字符串是否重复
java 判断字符串是否是中文 共总结了6种方法。。。。
利用字符间的转化把汉字转化为英文字符主要应用于提取汉字的首字母等要求
对网上问的一些问题的总结,封装成了一个工具类。完成的功能有: 1、判断字符串中是否有中文; 2、得到字符串中有几个中文; 3、判断字符串中有没有连续的几个中文;
在JAVA里面实现判断字符串长度,和截取字符串
通用的文件字符编码集判断需要借助第三方包cpdetector.jar 使用Cpdetector jar包检测文件编码需要依赖antlr-2.7.7.jar、chardet-1.0.jar、jargs-1.0.jar三个jar包 本下载资源一站式全包含,并附带亲测有效的片段...
判断字符串是否为空判断字符串是否为空判断字符串是否为空
判断字符串是否包含emoji表情
JAVA的字符串拼接与性能 概述:本文主要研究的是JAVA的字符串拼接的性能,原文中的测试代码在功能上并不等价,导致concat的测试意义不大。不过原作者在评论栏给了新的concat结果,如果有兴趣的同学建议自己修改代码...
自己编的java判断一个字符串是否对称的,忘指导。判断一个字符串是否是对称字符串(方法改进) (一个一个比较) 例如"abc"不是对称字符串,"aba"、"abba"、"aaa"、"mnanm"是对称字符串
下面小编就为大家带来一篇java判断中文字符串长度的简单实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
java判断一段话中是否有电话号码,并将其进行隐藏
Java中文问题及最优解决方法
Java获取随机字符串Java获取随机字符串Java获取随机字符串
java中根据汉字字符串获取拼音首字母工具类
java解析xml字符串,添加属性,更新属性等
这个是我自己写的一个JAVA的小方法,用正则表达式写的一个判断字符串是否为数字的一个方法,拿过来就能用,很方便,比如说:手机号等
主要介绍了Java中判断字符串是中文或者英文的工具类分享,本文直接给出代码,相关说明请看代码的注释,需要的朋友可以参考下