我和队友在一周的时间内完成了“词频统计”程序的编写、调试与性能优化。
源码和应用程序地址:https://github.com/ycWang9725/word-count
词频统计的要求如下:
wf [-f|-c|-p
|-q ] [-n ] [-x ] [-v ] [-d [-s]]
Options:
-f: Count word occurrences.
-c: Count character occurrences.
-p: Count phrase occurrences, treating any contiguous words as a phrase.
-q: Count VERB-PREPOSITION pair occurrences. is the path to the list of prepositions. -v must be specified. THIS IS AN OPTIONAL FEATURE.
-v: Use as a verb dictionary that can be used with -p or -q.
-d: Treatas the path to a directory and operate on each file inside the directory.
-s: Recurse into sub-directories. Must be used with -d.
-n: Output only the top items.
-x: Use as a list of stop words, which are ignored in the counting. Effective only with -f or -p specified.
: The path to the input file if -d is not specified.
合作方式
和队友结对编程,这次主要使用队友更加擅长的C#写程序,我主要起到的是领航员的作用,考虑代码的架构以及优化方案等,另外还有就是辅助检查代码有无bug(在这一方面我还是因为粗心漏掉了不少问题)。这次跟着队友学到了C#编程,探索了在Visual Studio C#环境下效能分析与代码优化,收获不小。
代码规范
使用vs的C语言风格。
创建了总共五个类:CommandLineArgumentParser, modes, VocabTree(已弃用), Program, 和evaluate, 分别用于:接受命令行参数, 处理命令行参数, 建立字典树(后来因为搜索慢而舍弃), 词频统计的主要功能实现, 以及单元测试。
效能分析与代码优化
效能分析主要使用Visual Studio自带的效能分析工具,使用起来非常方便。
代码优化主要集中在对词表以及文本搜索的优化,以及对输入输出的优化上。
输入输出通过建立缓冲区实现优化。
- 词表搜索优化经历了以下几个过程:
- 使用
- 作为数据存储格式,虽然建立过程非常快,但是搜索占用了绝大多数时间。
- 使用自己写的字典树(VocabTree)进行优化,搜索时间降低了很多,但是建立时间较长。
- 最后使用哈希表以及字典,在建立以及搜索方面都有较好的性能。
三者的对比图如下:(由上到下依此为:列表、树、哈希映射。其中使用哈希映射甚至快到不会被命中)
其实还有很多可以优化的地方,比如多线程优化、IO优化(占用超过一半时间)等。只是截止日期到了,就没有继续优化下去。所以是时间限制了我们的优化,具体原因有两个,一个是自身原因:我和队友这周都比较忙,花在结对编程上的时间较零散。另外一个是外在的原因:这次代码的需求没有从最开始就明确,致使我们在最开始踩了很多坑,后来又修正明确了需求,拿到助教的样例程序,又把前面的一些实现推倒重来,重新测试又花了很多时间。感觉这次助教最终定稿的代码要求可以在这门课程中以后继续使用,写得很明确了,也能让同学少踩坑,多优化。
结对编程的感悟
上一次结对编程主要是我敲代码,队友做领航员。这次我当领航员感受到这个角色也不太容易:需要快速读懂队友的代码、及时和队友沟通、在更大的范围中思考解决办法以及帮助队友挑代码细节的问题等。我自认为我只是做到了在宏观上设计代码架构并及时与队友沟通这个方面,并没有在挑代码细节的问题方面做到位。这导致我们的代码在测试环节发现了多处细节问题,影响到了进度。看来我还是要提高读代码的速度和细致程度。
列举一下队友在这次结对编程中展现出的优点和暴露出的缺点:
优点:
- 对C# 比较熟悉,实现代码很快,遇到没用过的方法也能能够通过各种方式,如查看msdn、源码定义等方式找到需要的方法。
- 做的版本控制比较好,对代码比较负责,在组里给的任务比较多的情况下仍能和我熬夜坚持写程序。
- 对代码出现的问题有较快的判断,说明她有对代码整体的把握。
缺点:在结对编程后期存在两个工程,经常搞错待测试的工程,操作有些紊乱,导致测试进度有点被拖慢。