文档章节

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

杨尚川
 杨尚川
发布于 2015/05/12 23:38
字数 922
阅读 1237
收藏 13

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

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


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






© 著作权归作者所有

杨尚川

杨尚川

粉丝 1100
博文 220
码字总数 1624053
作品 12
东城
架构师
私信 提问
Java中文分词组件 - word分词

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

杨尚川
2014/04/29
0
47
结巴分词 0.27 发布,Python 中文分词组件

本次release的主要更新: 1) 新增并行分词功能,可以在多核计算机上显著提高分词速度 2) 修正了“的”字频过高引起的bug;修正了对小数点和下划线的处理 3) 修正了python2.6存在的兼容性问题...

fxsjy
2013/04/22
3.3K
8
CPU密集型任务并发与资源控制

人生苦短,我用Python! 情景描述: 当我们在处理数据的时候,尤其对大量的文本数据或是大量的独立的数据处理的时候,如果是用单线程的方式处理的话可能会耗费大量的时间,大量到你会哭的那种...

北静王
04/16
0
0
Java分布式中文分词组件word分词v1.2发布

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

杨尚川
2015/04/11
5.7K
5
中文分词算法 之 基于词典的正向最大匹配算法

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

杨尚川
2014/03/18
0
20

没有更多内容

加载失败,请刷新页面

加载更多

揭秘阿里云背后神秘而富有能量的一群人

作为某创业公司CTO兼CTO兼CFO,带领众子弟行走于云端计算,累计犒赏已达757157.09银两,江湖人称紫龙,就是众多阿里云大使中低调内敛的一位。其话不多,一个典型的技术男,但又热心钻研传播推...

阿里云云栖社区
31分钟前
1
0
深入浅出Mybatis系列(一)---Mybatis源码分析环境准备

Mybatis源码分析环境准备 源码下载地址: https://blog.mybatis.org/p/products.html 把下载好多源码导入idea 之后可以在Test包下进行源码分析 这里我们就把源码分析的环境准备好了,下一篇文...

须臾之余
47分钟前
0
0
使用JDK的观察者接口进行消息推送

观察者模式就是对对象内部的变化进行观察,当发生改变时做出相应的响应。代码样例见 设计模式整理 ! 因为观察者模式较为重要,使用频率较高,JDK早已经提供了内置的观察者接口以及被观察者父...

算法之名
55分钟前
16
0
supervisor的配置与laravel php artisan queue:work的配置

安装环境 centos 7.2 安装supervisor easy_install supervisor echo_supervisord_conf > /etc/supervisord.conf 配置supervisor 如下 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20......

bengozhong
今天
2
0
DevExpress Winforms Controls:安装使用系统要求文档

【DevExpress WinForms v19.1下载】 本文档包含了有关安装和使用DevExpress WinForms控件的系统要求信息。 .NET Framework 下图展示了支持的.NET Framework版本。 Microsoft已发布.NET Fram...

FILA6666
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部