作业要求参见:https://edu.cnblogs.com/campus/nenu/2019fall/homework/7628。
优化后代码地址:https://e.coding.net/wangkefei/optimize_wf.git。
要求0:以 战争与和平 作为输入文件,重读向由文件系统读入。连续三次运行,给出每次消耗时间、CPU参数。
上周未完成功能四,这周继续努力实现功能四,但仍未实现。此次作业使用韩昊同学上周词频统计代码进行较能分析和优化。
韩昊同学代码地址:https://e.coding.net/hanhao/count_words.git。
第一次运行截图:
第二次运行截图:
第三次运行截图:
次数 | 时间(s) |
1 | 2.494 |
2 | 1.855 |
3 | 1.754 |
平均 | 2.034 |
CPU参数:Intel(R) Core(TM) i7-3770 CPU @ 3.40GHz 3.40GHz
要求1:给出你猜测程序的瓶颈。
猜测:代码中计算单词频数部分使用了for循环和判断语句,猜测此处花费时间较长。
代码片段:
dir_a = {} # 计算频数 for str1 in list1: if str1 != ' ': if str1 in dir_a.keys(): dir_a[str1] = dir_a[str1] + 1 else: dir_a[str1] = 1 dir_b = sorted((dir_a).items(), key=lambda x: x[1], reverse=True) # 按照频数排序
要求2:通过 profile 找出程序的瓶颈。给出程序运行中最花费时间的3个函数(或代码片断)。要求包括截图。
在命令行输入:
python -m cProfile -s cumulative wf.py war_and_peace.txt
该命令可以显示出程序中每个函数调用的次数以及运行时间,并按时间长短进行排序。
运行截图如下,红框中为耗时最长的三个函数:
要求3:根据瓶颈,"尽力而为"地优化程序性能。
重点:使用python的collection模块,及其提供的数据类型counter计数器用于计数,废除原有的for循环和判断语句。
修改代码部分:
def countNumber(text, flag): text = text.replace(' ', ' ').replace(' ', ' ').replace('.', ' ').replace(',', ' ').replace('"', ' ') text = deal_Redundantwords(text) list1 = text.replace(' ', ' ').lower().split() # 保存原始数据 list2 = list(set(list1)) # 去重之后的数据 if (flag == 0): print("total " + str(len(list2))) # 小文本统计词汇量(功能1不输出words) else: print("total " + str(len(list2)) + " words") # 统计词汇量 print(" ") text = collections.Counter(list2) dir_b = text.most_common(10)
要求4:再次 profile,给出在 要求1 中的最花费时间的3个函数此时的花费。要求包括截图。
优化后,三个函数缩进到一秒钟之内。
运行截图:
要求5:程序运行时间。