AD

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

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

计算机很早就进入多核心时代了,不充分利用多核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;
}

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

标签: word, 多线程, 多核, word分词器, 并行分词, ParallelStream
分类: word
时间: 2015-05-12

相关文章

  1. 利用Psyco提升Python运行速度

    这篇文章主要介绍了利用Psyco提升Python运行速度,需要的朋友可以参考下 Psyco 是严格地在 Python 运行时进行操作的.也就是说,Python 源代码是通过 python 命令编译成字节码的,所用的方式和 ...
  2. 实用!这8个CSS工具可以提升编程速度

    概述:下面为大家推荐的这8个CSS工具,有提供函数的,有提供类的,有提取代码的,还有收集CSS的统计数据的--请花费两分钟的时间看完这篇文章,或许你会找到意外的惊喜,并且为你的编程之路打开了一扇新的大门. 作为网页设计师 ...
  3. 如何利用多核CPU来加速你的Linux命令 - awk, sed, bzip2, grep, wc等

    你是否曾经有过要计算一个非常大的数据(几百GB)的需求?或在里面搜索,或其它操作--一些无法并行的操作.数据专家们,我是在对你们说.你可能有一个4核或更多核的CPU,但我们合适的工具,例如grep,bzip2,wc,aw ...
  4. 8个简单方法提升WordPress速度

    WordPress是一个很棒的开源程序,几乎我认识的站长朋友当中,粗略估算有80%使用Wordpress.但很棒不等于完美,就在我所认识的这些朋友中,几乎所有人都会抱怨Wordpress太臃肿,运行效率太低了,大家有无同 ...
  5. 利用多核CPU来加速你的Linux命令 - awk, sed, bzip2, grep, wc等

    你是否曾经有过要计算一个非常大的数据(几百GB)的需求?或在里面搜索,或其它操作--一些无法并行的操作.数据专家们,我是在对你们说.你可能有一个4核或更多核的CPU,但我们合适的工具,例如 grep, bzip2, wc ...
  6. mysql千万级数据入库,提升插入速度

    需求:将文本文件中包含的一千万int型id数据插入mysql中,并求得出现频率最高的前10条. 文本文件:http://pan.baidu.com/s/1gd08g3D.内容是一行一个int型id. 本文只探讨mysql ...
  7. 利用SEO提升百度有啊销售的小发现

    今天我在百度有啊申请的帐号已经通过了实名认证,本来准备开个小店玩玩,不过在设置店名的过程中我被雷到了,百度有啊规定只有到了1钻以上才能更改一次店名,在之前只能使用默认的店名(帐号ID+的小店),这个设置有点太苛刻,毕竟达 ...
  8. 提升PHP速度全攻略

    PHP的优点之一是速度很快,对于一般的网站应用,可以说是已经足够了.不过如果站点的访问量很高.带宽窄或者其它的因素令服务器产生性能瓶颈的时候,你可能得想想其它的办法来进一步提高PHP的速度了.这篇文章将从几个方面介绍如何 ...
  9. C# 利用StringBuilder提升字符串拼接性能的小例子

    一个项目中有数据图表呈现,数据量稍大时显得很慢,在使用了StringBuilder后效果提升很明显,下面有例子 用Stopwatch分段监控了一下,发现耗时最多的函数是SaveToExcel 此函数中遍列所有数据行,通过 ...
  10. asp中利用CSW中文分词组件来实现自己网站的内容关键词自动提取

    比如标题是:腾讯QQ 2006 珊瑚虫集成版 v4.5b 分词后:[此资源关键词:腾讯 QQ 珊瑚虫 集成 ] 并且把关键词做成专题,可以为每个内容页面生成相关连接了 用CSW中文分词组件 下载:http://www.v ...
  11. 如何合理利用辅导班提升考研数学

    虽然说辅导书和辅导班对考研来说都是一个辅助,但是没有也是不行的,如果能够选择一个非常好的辅导班,对那些考研数学本来就不是很好的同学来说就是很有必要的了.总的来说,考研辅导班有以下的几个优点,第一,考研辅导班的老师一般都是 ...
  12. Java中文分词组件 - word分词

    Java分布式中文分词组件 - word分词 word分词是一个Java实现的分布式的中文分词组件,提供了多种基于词典的分词算法,并利用ngram模型来消除歧义.能准确识别英文.数字,以及日期.时间等数量词,能识别人名. ...
  13. Java分布式中文分词组件word分词v1.2发布

    word分词是一个Java实现的分布式的中文分词组件,提供了多种基于词典的分词算法,并利用ngram模型来消除歧义.能准确识别英文.数字,以及日期.时间等数量词,能识别人名.地名.组织机构名等未登录词.同时提供了Luce ...
  14. [阅读笔记] 基于P2P的CDN,Go/Erlang并发比较

    PeerCDN 利用P2P进行文件分发不是什么新鲜事,但是在Web环境引入P2P仍然有很多挑战.PeerCDN团队正在进行相关技术的研发.该项目期望通过P2P技术为网站提供稳定.便捷.低成本的内容分发方案. 任何支持We ...
  15. 利用Windows 7新功能提升工作效率

    几经变迁,随着Windows 7正式版的发布,其功能.组件总算尘埃落定.其实,大多数用户是实用主义者,对一个新系统他们更关心使用该系统能否提升自己的工作效率.Windows 7新增的功能不少,哪些对于提升工作效率有帮助呢 ...
  16. 修改.htaccess,提升你的网站加载速度

    有时候遇到一个比较复杂的问题,我会选择暂时放一放. YSlow的检测结果,当时优化掉几个问题后,就暂时放手了. 最近在网站优化上有了新的认识,应用一下: Add an Expires or a Cache-Control ...
  17. java利用FutureTask.ExecutorService 在多核时代充分利用CPU运算

    java利用FutureTask.ExecutorService 在多核时代充分利用CPU运算 FutureTask.ExecutorService 相关知识,请看java,API 一个使用FutureTask简单的例子 ...
  18. Solr的中英文分词实现

    对于Solr应该不需要过多介绍了,强大的功能也是都体验过了,但是solr一个较大的问题就是分词问题,特别是中英文的混合分词,处理起来非常棘手. 虽然solr自带了支持中文分词的cjk,但是其效果实在不好,所以solr要解 ...
  19. 中文分词算法 之 基于词典的正向最大匹配算法

    基于词典的正向最大匹配算法(最长词优先匹配),算法会根据词典文件自动调整最大长度,分词的好坏完全取决于词典. 算法流程图如下: Java实现代码如下: /** * 基于词典的正向最大匹配算法 * @author 杨尚川 ...