博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
中文分词算法 之 词典机制性能优化与测试
阅读量:6764 次
发布时间:2019-06-26

本文共 2647 字,大约阅读时间需要 8 分钟。

hot3.png

在之前的两篇博文和中,我们对分词实现词典实现都做了优化,本文对词典实现做进一步优化,并和之前的多个实现做一个对比,使用的词典,使用的测试文本。

 

优化TrieV3的关键在于把虚拟根节点(/)的子节点(词表首字母)提升为多个相互独立的根节点,并对这些根节点建立索引。优化的依据是根节点(词表首字母)的数量庞大,索引查找的速度远远超过二分查找

 

下面看看进一步优化后的TrieV4和之前的TrieV3的对比:

    /**     * 获取字符对应的根节点     * 如果节点不存在     * 则增加根节点后返回新增的节点     * @param character 字符     * @return 字符对应的根节点     */    private TrieNode getRootNodeIfNotExistThenCreate(char character){        TrieNode trieNode = getRootNode(character);        if(trieNode == null){            trieNode = new TrieNode(character);            addRootNode(trieNode);        }        return trieNode;    }    /**     * 新增一个根节点     * @param rootNode 根节点     */    private void addRootNode(TrieNode rootNode){        //计算节点的存储索引        int index = rootNode.getCharacter()%INDEX_LENGTH;        //检查索引是否和其他节点冲突        TrieNode existTrieNode = ROOT_NODES_INDEX[index];        if(existTrieNode != null){            //有冲突,将冲突节点附加到当前节点之后            rootNode.setSibling(existTrieNode);        }        //新增的节点总是在最前        ROOT_NODES_INDEX[index] = rootNode;    }    /**     * 获取字符对应的根节点     * 如果不存在,则返回NULL     * @param character 字符     * @return 字符对应的根节点     */    private TrieNode getRootNode(char character){        //计算节点的存储索引        int index = character%INDEX_LENGTH;        TrieNode trieNode = ROOT_NODES_INDEX[index];        while(trieNode != null && character != trieNode.getCharacter()){            //如果节点和其他节点冲突,则需要链式查找            trieNode = trieNode.getSibling();        }        return trieNode;    }

 

 不同的字符可能会映射到同一个数组索引(映射冲突),所以需要给TrieNode增加一个引用sibling,当冲突发生的时候,可利用该引用将多个冲突元素链接起来,这样,在一个数组索引中就能存储多个TrieNode。如果冲突大量发生,不但会浪费已经分配的数组空间,而且会引起查找性能的下降,好在这里根节点的每个字符都不一样,冲突发生的情况非常少。我们看看词数目为427451的的冲突情况:

 

冲突次数为:1 的元素个数:2746冲突次数为:2 的元素个数:1冲突次数:2748总槽数:12000用槽数:9024使用率:75.2%剩槽数:2976

 

 

 

 

 

将词典文件和测试文本解压到当前目录下,使用下面的命令进行测试需要注意的是,这里的-Xmx参数指定的值是相应的词典实现所需要的最小的堆空间,如果再小就无法完成分词

 

nohup java -Ddic.class=org.apdplat.word.dictionary.impl.TrieV4 -Xmx40m  -cp target/word-1.0.jar org.apdplat.word.SegFile &nohup java -Ddic.class=org.apdplat.word.dictionary.impl.TrieV3 -Xmx40m  -cp target/word-1.0.jar org.apdplat.word.SegFile &nohup java -Ddic.class=org.apdplat.word.dictionary.impl.TrieV2 -Xmx40m  -cp target/word-1.0.jar org.apdplat.word.SegFile &nohup java -Ddic.class=org.apdplat.word.dictionary.impl.TrieV1 -Xmx120m  -cp target/word-1.0.jar org.apdplat.word.SegFile &nohup java -Ddic.class=org.apdplat.word.dictionary.impl.Trie -Xmx200m  -cp target/word-1.0.jar org.apdplat.word.SegFile &nohup java -Ddic.class=org.apdplat.word.dictionary.impl.HashSet -Xmx50m  -cp target/word-1.0.jar org.apdplat.word.SegFile &

 

测试结果如下:

 

 

 

 

 

 

参考资料:

1、

2、

3、

4、

5、

 

转载于:https://my.oschina.net/apdplat/blog/213968

你可能感兴趣的文章
不是人家炫耀,而是我们太挫,你为什么不努力
查看>>
线性代数--矩阵乘法
查看>>
【学习】一本概率论经典书籍《Introduction to Probability》(pdf和LaTeX源代码下载)...
查看>>
redis学习篇(七)-----高级特性之安全篇
查看>>
轻松搞定面试中的二叉树题目
查看>>
用MySQL Slow Log解决MySQL CPU占用高的问题
查看>>
php+smarty分页类
查看>>
oracle 用户密码过期-ORA-28001: 口令已经失效
查看>>
Java 实现 Hook 对鼠标键盘监听
查看>>
非常实用的Chrome插件之总结
查看>>
你应该知道的7种回归方法
查看>>
grunt简单的入门
查看>>
关于css浮动
查看>>
C Primer Plus 第2章 C语言概述
查看>>
Sticky Notes
查看>>
SHELL利器:比较常用的SHELL命令(持续更新)
查看>>
Ubuntu 默认启动到命令行 12.04 .
查看>>
Vue调试神器vue-devtools安装
查看>>
Android Dialog几种对话框
查看>>
Python+Flask.0009.FLASK静态资源之默认及自定义资源目录
查看>>