如何利用多核提升分词速度

2015-05-12  来源:本站原创  分类:word  人气:2178 

在进行中文分词的时候,我们如何利用多核提升分词速度呢?

计算机很早就进入多核心时代了,不充分利用多核CPU是对计算资源的一种极大的浪费。

在对一段文本进行分词的时候,word分词器的处理步骤如下:

1、把要分词的文本根据标点符号分割成句子;

2、以分割后的句子为基本单位进行分词;

3、把各个句子的分词结果按原来的句子顺序组合起来;

word分词器充分考虑到了利用多核提升分词速度这个问题,在第1步完成后,如果分割出了多个句子,那么这多个句子就可以同时(并行)进行分词,这样就能充分利用多核CPU来提升分词速度。

word分词器提出了两种解决方案,我们分别来介绍:

1、多线程

在Java中,多线程可以帮助我们充分利用CPU,我们可以根据自己的机器情况及其应用特点在配置文件word.conf中指定合适的线程池大小:

#配置分词使用的固定线程池大小,根据机器的情况设置合适的值
thread.pool.size=4

代码实现核心片段如下:

private static final ExecutorService EXECUTOR_SERVICE = Executors.newFixedThreadPool(WordConfTools.getInt("thread.pool.size", 4));
@Override
public List<Word> seg(String text) {
    List<String> sentences = Punctuation.seg(text, KEEP_PUNCTUATION);
    if(sentences.size() == 1){
        return segSentence(sentences.get(0));
    }
    //如果是多个句子,可以利用多线程提升分词速度
    List<Future<List<Word>>> futures = new ArrayList<>(sentences.size());
    for(String sentence : sentences){
        futures.add(submit(sentence));
    }
    sentences.clear();
    List<Word> result = new ArrayList<>();
    for(Future<List<Word>> future : futures){
        List<Word> words;
        try {
            words = future.get();
            if(words != null){
                result.addAll(words);
            }
        } catch (InterruptedException | ExecutionException ex) {
            LOGGER.error("获取分词结果失败", ex);
        }
    }
    futures.clear();
    return result;
}
/**
 * 将切分句子的任务提交给线程池来运行
 * @param sentence 句子
 * @return 切分结果
 */
private Future<List<Word>> submit(final String sentence){
    return EXECUTOR_SERVICE.submit(new Callable<List<Word>>(){
        @Override
        public List<Word> call() {
            return segSentence(sentence);
        }
    });
}

2、Parallel Stream

Java8 support functional-style operations on streams of elements,if we use "parallelStream()" instead of "stream()" , the serial process can automatic change to parallel process.

Java8的内置的并行处理功能,通过上面的简短的介绍我们应该有所了解,使用这种方案的好处是,随着JDK的改进,程序的性能会间接受益,而且我们的代码可以更简单,虽然我们不再能够控制并行度,比如上面我们能指定线程数,但是我们可以放心JRE会做出合理的调度与优化,而且人为指定线程数很多时候都不是最合理的。

我们可以在配置文件word.conf中指定是否启用并行分词:

#是否利用多核提升分词速度
parallel.seg=true

上面多线程的代码可以简化为:

private static final boolean PARALLEL_SEG = WordConfTools.getBoolean("parallel.seg", true);
@Override
public List<Word> seg(String text) {
    List<String> sentences = Punctuation.seg(text, KEEP_PUNCTUATION);
    if(sentences.size() == 1){
        return segSentence(sentences.get(0));
    }
    if(!PARALLEL_SEG){
        //串行顺序处理,不能利用多核优势
        return sentences.stream().flatMap(sentence->segSentence(sentence).stream()).collect(Collectors.toList());
    }
    //如果是多个句子,可以利用多核提升分词速度
    Map<Integer, String> sentenceMap = new HashMap<>();
    int len = sentences.size();
    for(int i=0; i<len; i++){
        //记住句子的先后顺序,因为后面的parallelStream方法不保证顺序
        sentenceMap.put(i, sentences.get(i));
    }
    //用数组收集句子分词结果
    List<Word>[] results = new List[sentences.size()];
    //使用Java8中内置的并行处理机制
    sentenceMap.entrySet().parallelStream().forEach(entry -> {
        int index = entry.getKey();
        String sentence = entry.getValue();
        results[index] = segSentence(sentence);
    });
    sentences.clear();
    sentences = null;
    sentenceMap.clear();
    sentenceMap = null;
    List<Word> resultList = new ArrayList<>();
    for(List<Word> result : results){
        resultList.addAll(result);
    }
    return resultList;
}

如果对更多的细节感兴趣,请点击这里查看代码的源文件

相关文章
  • 如何利用多核提升分词速度 2015-05-12

    在进行中文分词的时候,我们如何利用多核提升分词速度呢? 计算机很早就进入多核心时代了,不充分利用多核CPU是对计算资源的一种极大的浪费. 在对一段文本进行分词的时候,word分词器的处理步骤如下: 1.把要分词的文本根据标点符号分割成句子: 2.以分割后的句子为基本单位进行分词: 3.把各个句子的分词结果按原来的句子顺序组合起来: word分词器充分考虑到了利用多核提升分词速度这个问题,在第1步完成后,如果分割出了多个句子,那么这多个句子就可以同时(并行)进行分词,这样就能充分利用多核CPU来提

  • 利用Psyco提升Python运行速度 2014-11-25

    这篇文章主要介绍了利用Psyco提升Python运行速度,需要的朋友可以参考下 Psyco 是严格地在 Python 运行时进行操作的.也就是说,Python 源代码是通过 python 命令编译成字节码的,所用的方式和以前完全相同(除了为调用 Psyco 而添加的几个 import 语句和函数调用).但是当 Python 解释器运行应用程序时,Psyco 会不时地检查,看是否能用一些专门的机器代码去替换常规的 Python 字节码操作.这种专门的编译和 Java 即时编译器所进行的操作非常类似

  • 实用!这8个CSS工具可以提升编程速度 2014-06-12

    概述:下面为大家推荐的这8个CSS工具,有提供函数的,有提供类的,有提取代码的,还有收集CSS的统计数据的--请花费两分钟的时间看完这篇文章,或许你会找到意外的惊喜,并且为你的编程之路打开了一扇新的大门. 作为网页设计师,为了在预期的时间内能完成项目,前期肯定是要进行大量练习的.但是如果你花了大量的时间在编写CSS代码上,那无疑是浪费时间.工欲善其事必先利其器,聪明的设计师善于利用工具提升他们的编码效率,从而将更多的心思放在设计上. 下面为大家推荐的这8个CSS工具,有提供函数的,有提供类的,有

  • 如何利用多核CPU来加速你的Linux命令 - awk, sed, bzip2, grep, wc等 2014-04-21

    你是否曾经有过要计算一个非常大的数据(几百GB)的需求?或在里面搜索,或其它操作--一些无法并行的操作.数据专家们,我是在对你们说.你可能有一个4核或更多核的CPU,但我们合适的工具,例如grep,bzip2,wc,awk,sed等等,都是单线程的,只能使用一个CPU内核. 借用卡通人物Cartman的话,"如何我能使用这些内核"? 要想让Linux命令使用所有的CPU内核,我们需要用到GNU Parallel命令,它让我们所有的CPU内核在单机内做神奇的map-reduce操作,当然

  • 8个简单方法提升WordPress速度 2015-03-11

    WordPress是一个很棒的开源程序,几乎我认识的站长朋友当中,粗略估算有80%使用Wordpress.但很棒不等于完美,就在我所认识的这些朋友中,几乎所有人都会抱怨Wordpress太臃肿,运行效率太低了,大家有无同感? 所以,今天这篇博文和大家分享8个小贴士来提升WP的运行效率,如果您运用了这些方法后发现确实有帮助,请把这篇博文分享给更多的人好吧?当然为了尊重劳动成果,也烦请指明出处. 1.使用高效的缓存插件 WordPress的插件们是非常有用的, 我推荐一款缓存插件可以改善页面载入时间

  • 利用多核CPU来加速你的Linux命令 - awk, sed, bzip2, grep, wc等 2014-10-07

    你是否曾经有过要计算一个非常大的数据(几百GB)的需求?或在里面搜索,或其它操作--一些无法并行的操作.数据专家们,我是在对你们说.你可能有一个4核或更多核的CPU,但我们合适的工具,例如 grep, bzip2, wc, awk, sed等等,都是单线程的,只能使用一个CPU内核. 借用卡通人物Cartman的话,"如何我能使用这些内核"? 要想让Linux命令使用所有的CPU内核,我们需要用到GNU Parallel命令,它让我们所有的CPU内核在单机内做神奇的map-reduce

  • mysql千万级数据入库,提升插入速度 2015-02-28

    需求:将文本文件中包含的一千万int型id数据插入mysql中,并求得出现频率最高的前10条. 文本文件:http://pan.baidu.com/s/1gd08g3D.内容是一行一个int型id. 本文只探讨mysql插入速度.‍‍分别从‍‍数据库‍‍和‍‍代码‍‍两方面进行总结.‍‍ 首先有表test: CREATE TABLE `test` ( `id` INT NOT NULL AUTO_INCREMENT, `testId` INT NULL, PRIMARY KEY (`id`),

  • 利用SEO提升百度有啊销售的小发现 2013-11-10

    今天我在百度有啊申请的帐号已经通过了实名认证,本来准备开个小店玩玩,不过在设置店名的过程中我被雷到了,百度有啊规定只有到了1钻以上才能更改一次店名,在之前只能使用默认的店名(帐号ID+的小店),这个设置有点太苛刻,毕竟达到1钻不是很简单的事情,而且很多人习惯用英文ID,这样就会出现很多"sunyunkun的小店"这种店名,这样的店名既不会引起客户的特别注意,也很难在搜索引擎排名中获得好位置.看起来感觉相当的糟糕,但是如果反过来利用他这这个规则,只要初期设置得当,也可以让你的小店获得和一

  • 提升PHP速度全攻略 2014-02-21

    PHP的优点之一是速度很快,对于一般的网站应用,可以说是已经足够了.不过如果站点的访问量很高.带宽窄或者其它的因素令服务器产生性能瓶颈的时候,你可能得想想其它的办法来进一步提高PHP的速度了.这篇文章将从几个方面介绍如何做到这一点,从而令用户浏览的时候更加"爽". 代码优化 在这里并不想再次告诉你如何写更干净的代码,这一点我想每个人都清楚,在需要速度的时候,你可能已经在PHP源代码的优化上面做了不少的工作,这里所提出的是,这个烦琐的工作可以交由其它工具来完成.这就是Zend Optim

  • C# 利用StringBuilder提升字符串拼接性能的小例子 2014-08-02

    一个项目中有数据图表呈现,数据量稍大时显得很慢,在使用了StringBuilder后效果提升很明显,下面有例子 用Stopwatch分段监控了一下,发现耗时最多的函数是SaveToExcel 此函数中遍列所有数据行,通过Replace替换标签生成Excel行,然后将行数据累加赋值到一个字符串 string excelString = ""; foreach(var item in list){ excelString += string.Format("<row>

  • asp中利用CSW中文分词组件来实现自己网站的内容关键词自动提取 2015-01-11

    比如标题是:腾讯QQ 2006 珊瑚虫集成版 v4.5b 分词后:[此资源关键词:腾讯 QQ 珊瑚虫 集成 ] 并且把关键词做成专题,可以为每个内容页面生成相关连接了 用CSW中文分词组件 下载:http://www.vgoogle.net/Product_CSW.asp 下面是我的ASP代码,比较粗浅,但实用 codecsw 得到输出的所有分词结果,用它的组建里面有个ASP文件,你一看就知道怎么得到分词结果了,这个不详细说了. fcon=split(htm," ") fcs=ubou

  • 如何合理利用辅导班提升考研数学 2014-11-27

    虽然说辅导书和辅导班对考研来说都是一个辅助,但是没有也是不行的,如果能够选择一个非常好的辅导班,对那些考研数学本来就不是很好的同学来说就是很有必要的了.总的来说,考研辅导班有以下的几个优点,第一,考研辅导班的老师一般都是经验丰富的,他们有自己专业的优势和多年的辅导经验,对于帮助考生把握考研重点和难点是很有帮助的:第二是可以督促学生反复性的复习,帮助考生克服懒惰的习惯,达到高效复习的效果:第三,考研辅导班都是有自己的信息源和资料库的,这些都是对考生很重要的信息,可以帮助考生制定正确的复习计划. 在

  • Java中文分词组件 - word分词 2014-04-29

    Java分布式中文分词组件 - word分词 word分词是一个Java实现的分布式的中文分词组件,提供了多种基于词典的分词算法,并利用ngram模型来消除歧义.能准确识别英文.数字,以及日期.时间等数量词,能识别人名.地名.组织机构名等未登录词.能通过自定义配置文件来改变组件行为,能自定义用户词库.自动检测词库变化.支持大规模分布式环境,能灵活指定多种分词算法,能使用refine功能灵活控制分词结果,还能使用词性标注.同义标注.反义标注.拼音标注等功能.同时还无缝和Lucene.Solr.El

  • Java分布式中文分词组件word分词v1.2发布 2015-04-15

    word分词是一个Java实现的分布式的中文分词组件,提供了多种基于词典的分词算法,并利用ngram模型来消除歧义.能准确识别英文.数字,以及日期.时间等数量词,能识别人名.地名.组织机构名等未登录词.同时提供了Lucene.Solr.ElasticSearch.Luke插件. 自1.0之后,在1.1和1.2中,word分词有了重大改进,优化了分词算法.利用多线程提升分词速度.支持分布式.支持资源变化自动检测.新增了全切分算法.支持三元模型.支持Luke插件.增加gradle支持等等,同时,wo

  • [阅读笔记] 基于P2P的CDN,Go/Erlang并发比较 2013-03-28

    PeerCDN 利用P2P进行文件分发不是什么新鲜事,但是在Web环境引入P2P仍然有很多挑战.PeerCDN团队正在进行相关技术的研发.该项目期望通过P2P技术为网站提供稳定.便捷.低成本的内容分发方案. 任何支持WebRTC的浏览器可以支持这种技术,这比之前需要安装额外软件的技术是一个显著的进步.网站页面中只需要加入一行javascript代码. PeerCDN的专注点应该是大文件(视频,音频,图片),而对于海量小文件则可能会力不从心. PeerCDN Solving the wrong p

  • 利用Windows 7新功能提升工作效率 2014-12-24

    几经变迁,随着Windows 7正式版的发布,其功能.组件总算尘埃落定.其实,大多数用户是实用主义者,对一个新系统他们更关心使用该系统能否提升自己的工作效率.Windows 7新增的功能不少,哪些对于提升工作效率有帮助呢?本文将和大家谈谈几个Windows 7新功能,以及如何使用它们提升我们的工作效率. 1.凭据管理器--提升访问速度及快速迁移 在登录远程计算机或者访问站点时,我们通常要输入用户名和密码信息.这些重复性的操作会影响我们的工作效率和使用体验,其实对于本地用户来说我们完全可以将这些访

  • 修改.htaccess,提升你的网站加载速度 2013-11-15

    有时候遇到一个比较复杂的问题,我会选择暂时放一放. YSlow的检测结果,当时优化掉几个问题后,就暂时放手了. 最近在网站优化上有了新的认识,应用一下: Add an Expires or a Cache-Control Header 简单点说:就是缓存一下不常修改的文件,提升访问速度. 再简单点说:就是在.htaccess文件中写入以下内容: <IfModule mod_expires.c> ExpiresActive On ExpiresDefault A600 ExpiresByType

  • java利用FutureTask.ExecutorService 在多核时代充分利用CPU运算 2012-12-07

    java利用FutureTask.ExecutorService 在多核时代充分利用CPU运算 FutureTask.ExecutorService 相关知识,请看java,API 一个使用FutureTask简单的例子: package com.spell.threads; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurre

  • Solr的中英文分词实现 2013-11-14

    对于Solr应该不需要过多介绍了,强大的功能也是都体验过了,但是solr一个较大的问题就是分词问题,特别是中英文的混合分词,处理起来非常棘手. 虽然solr自带了支持中文分词的cjk,但是其效果实在不好,所以solr要解决的一个问题就是中文分词问题,这里推荐的方案是利用ik进行分词. ik是较早作中文分词的工具,其效果也是得到多数用户认同.但是现在作者似乎更新缓慢,对于最新的solr4.4支持不好,最新的更新也停留在2012年. 虽然不支持4.4版本(这也不是作者的错,solr的lucene的新

  • 中文分词算法 之 基于词典的正向最大匹配算法 2014-03-18

    基于词典的正向最大匹配算法(最长词优先匹配),算法会根据词典文件自动调整最大长度,分词的好坏完全取决于词典. 算法流程图如下: Java实现代码如下: /** * 基于词典的正向最大匹配算法 * @author 杨尚川 */ public class WordSeg { private static final List<String> DIC = new ArrayList<>(); private static final int MAX_LENGTH; static{ try