晚饭后的food coma,不能高效地做其他事情,利用这个时间总结一下上一周编代码的收获。
上上周周末以及上周一、二,都在调试POS-tagger的程序,这是一个老师布置的project。代码量不大,思路也不复杂。做Natural Language Processing的肯定都熟悉Part-Of-Speech是什么。
POS简单说来,对于给定的一些句子/文章进行处理,给每个单词添加标签。比如简单的: I want to race. 程序经过处理后,就会识别出I是代词,want是动词,to是介词,race是动词。不同的标签库对单词的词性细分程度不同。比如粗粒度下,race和want都识别成动词,而细粒度下race识别出动词原形,want识别出非第三人称单数的动词。POS同样适用于中文,但预处理更加复杂,至少分词就很麻烦。
POS基于隐马尔科夫链模型(HMM),使用Viterbi算法实现,语言模型使用bigram。我使用java语言编写的代码,收获主要在java编程上:
1)HashTable与HashMap的效率
如果不要求同步,一定要使用HashMap。程序的数据量较大,通过实例测试,发现HashMap可以在3s中完成的事,HashTable可能需要几分钟。
2)HashMap与数组
和数组相比, HashMap非常占用时间和空间。当数据量大时,要尽量减少HashMap的数量。比如可以使用一个HashMap<String,Integer>做数组索引查询,使用int[][]来真正存储数据。效率和时间的提高都会很明显。
3)ArrayList的contains
数据量大时,要谨慎使用。contains的实现方法应该是一个一个item的比对,要遍历所有的数据。如果程序确实需要这个功能,可以使用HashSet。
4)StringBuilder和StringBuffer
在不需要同步的时,优先使用StringBuilder。如果能够大概估计最终的容量,不要使用默认的capacity(16个字符),预先分配内存。
5)for循环
for(int i=0;i<hashMap.size();i++) 这是我们程序一般情况的写法。但每次循环,都会调用一次hashMap.size,增加不必要的时间开销,最好将循环写出 int size = hashMap.size(); for(int i=0;i<size;i++)。实践后发现确实能够减少一点点时间。
暂且写到这里,未来的一个月会很忙碌,要加油奋斗了!
借用高中物理老师的一句话:闲情闲语闲思,都要杜绝!