在进行中文分词的时候,我们如何利用多核提升分词速度呢?
计算机很早就进入多核心时代了,不充分利用多核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; }
如果对更多的细节感兴趣,请点击这里查看代码的源文件。
相关推荐
Linux利用多核多线程进行程序优化.docx
利用OpenMP线程绑定技术提升多核平台应用性能.pdf
程绑定在固定的核上运行,使其不再迁移,这种方法将有可能提升应用程序性能,更充分的利 用多核平台的计算能力。本文将介绍如何使用主流的编译器绑定接口以及Linux内核API的方式 实现OpenMP线程与核之间的绑定,使用...
修改opencv traincascade 代码,利用多核并行计算大幅提升查找负样本的速度
利用多核编译基于VC编译器的Makefile,提升编译效率。
iOS 的多核编程和内存管理相当之经典 大师出品
3G与超3G:利用多核处理器优势实现卓越3G、WiMAX及LTE性能.pdf
多核程序设计技术 通过软件多线程提升性能 电子书 PDF格式 带书签 高清 作者都是长期供职于Intel公司的资深软件工程师和结构师,书中融入了他们自己丰富的软硬件开发经验,可以为面向多核体系结构进行并行程序设计...
AMD多核补丁AMD多核补丁AMD多核补丁AMD多核补丁
不论对从未接触过并行程序设计的开发人员,还是转型面向多核体系结构进行并行程序设计的开发人员来讲,《多核程序设计技术:通过软件多线程提升性能》都是一本难得的参考书。个人觉得此书比较易懂,适合刚入门的程序...
1.iOS多核任务,比NSThead更易用的异步方法 2.展示了如何停止一个GCD方法
利用多cpu或多核cpu求解deform3d案例的方法
主要介绍了Nginx服务器进程数设置和利用多核CPU的方法,这样便可以更大限度地提高Nginx运行效率,需要的朋友可以参考下
Intel多核培训Intel多核培训Intel多核培训Intel多核培训
多核编程模型多核编程模型清华大学计算机科学与技术
近年来,多核平台越来越普及,充分利用多核硬件可以有效提高系统应用程序的性能。而现有大部分图形系统或其他类型的应用程序仍然使用单线程或者固定的线程数量,这就使得多核系统平台的性能并不能得到完全的利用。使用...
处理器从多核到众核的详细叙述文章 其实“多核”这个词已经流行很多年了,世界上第一款商用的非嵌入式多 核处理器是2002年IBM推出的POWER4。当然,多核这个词汇的流行主 要归功与AMD和Intel的广告,Intel与AMD的...
并行计算是当今热门的一个技术,本文档简单介绍了多核多线程的入门知识,可以作为初学者入门的好材料。
为了在多核处理器上充分利用多核资源以提升挖掘性能,提出了一种动态与静态任务分配机制相结合的基于多核的并行序列模式挖掘算法。该算法采用数据并行与任务并行相结合的策略,在各处理器核生成局部序列模式后,再与...