开端与场景
接着上一篇文章的地区分词匹配,最近发现有一些内容中全部为英文或者直接就是一些连接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
相关推荐
10. **性能优化**:为了实现高效的分词速度,开发者可能会使用缓存技术、字符串池以及Java的并发库进行性能优化。 " spliter "作为压缩包内的文件名,很可能是指分词器的主类或者核心模块,负责将输入的文本进行...
位运算在某些特定场景下可以提供高效的解决方案,如求最大公约数、判断奇偶性、快速幂运算等。 这个"java_algorithm_Daquann.rar"的源码包很可能会包含以上提到的各种算法的Java实现,通过阅读和理解这些代码,...
10. **字符串处理**:Java中的String类提供了丰富的操作方法,如模式匹配、替换、分割等,涉及到KMP算法、Boyer-Moore算法等字符串匹配策略。 在《各种算法java实现.docx》这个文档中,你可能会找到以上算法的详细...
- **解惑**:字符串拼接时需要注意内存效率和性能问题。使用`StringBuilder`或`StringBuffer`类进行拼接可以提高效率,特别是在处理大量字符串的情况下。 **谜题14:转义字符的溃败** - **描述**:涉及到转义字符的...
- 字符串:涉及到字符串处理,如回文判断、最长公共前后缀等。 - 树结构:二叉树的遍历、平衡二叉树、最近公共祖先等。 - 链表:链表操作,如两链表相交、删除中间节点等。 - 哈希表:用于快速查找和去重,如两...
3. **高性能:** Hibernate使用Java反射机制而非字节码增强技术实现了透明性,这有助于提高应用程序的性能。 4. **易于维护:** 当数据库结构发生变化时,通过调整Hibernate的映射配置文件即可,减少了对业务代码的...
- Java中的字符串是不可变的对象,使用`String`类来表示。字符串可以通过拼接、索引访问等方式进行操作。 - **数组** - 数组是一种基本的数据结构,用于存储固定大小的同类型元素。数组可以通过索引来访问或修改...
该题目要求通过栈操作对字符进行处理,并根据栈的长度来判断字符串中的特定模式。可能涉及到字符串解析、数据结构的操作和模式识别。 C题“斐波那契”可能要求解决和斐波那契数列相关的问题,这是一个典型的递归...
12. 代码可读性与健壮性:在编写代码时,应该注意代码的可读性,例如合理地使用变量名和注释来解释代码逻辑,以及在方案一中使用for循环的嵌套和条件判断来确保代码的正确执行。 13. 时间复杂度与空间复杂度:动态...
在LeetCode平台上,Java是一种广泛使用的编程语言来解决算法和数据结构的问题。这些问题涵盖了从基础到高级...在实践中,还需要注意代码的优化、错误处理和性能调优,这些都是成为一名优秀的Java程序员必不可少的部分。
- **Huffman树及Huffman编码**:通过构建Huffman树得到最优的二进制编码方案。 #### 七、图 - **图的定义** - **图及基本术语**:图是由顶点集和边集组成的集合,分为有向图和无向图。 - **抽象数据类型**:...
Java数据结构和算法是计算机科学...总之,Java数据结构和算法是开发高效程序的基础,深入学习和理解这些概念,能够帮助我们设计出更好的解决方案,提高代码质量。无论是面试还是实际项目开发,这都是不可或缺的知识点。
- **性能优化**:鼓励参赛者编写高效代码,关注算法的时间复杂度和空间复杂度,追求优雅的解决方案。 - **资源管理**:避免在函数内部定义大数组,以减少栈空间的消耗,提倡合理利用全局变量。 ### 2. 字符串处理与...
8. **编程语言基础**:如C/C++/Java/Python等,熟悉其语法特性和性能特性,了解如何写出高效且优雅的代码。 9. **逻辑思维**:解决复杂问题时,良好的逻辑思维能力能帮助分析问题,找到最优解决方案。 10. **调试...
《Algorithms-Exercises-master》这个压缩包很可能是包含上述知识点的Java代码实现,每个子文件对应一个具体的算法练习,学习者可以通过阅读和运行这些代码来加深对算法的理解,并且可以尝试自己编写解决方案,以...
在编程中,正确地组织和操作数据可以显著提升程序的性能。以下是一些主要的数据结构和算法的详细说明: 1. **一维数据结构**: - **数组**:是最基本的数据结构,它提供了直接访问元素的能力,通过索引进行操作。...
本资源包“Leetcode-February-master”包含了针对这些挑战的解决方案,以下是基于Java语言的解题知识点的详细分析: 1. **基础语法**:在解决LeetCode问题时,Java的基础语法是必不可少的,包括变量声明、条件语句...