一、程序分析
1.读文件到缓冲区
1 def process_file(dst): # 读文件到缓冲区 2 try: # 打开文件 3 file1 = open(dst, "r") 4 except IOError as s: 5 print(s) 6 return None 7 try: # 读文件到缓冲区 8 bvffer = file1.read() 9 except: 10 print("Read File Error!") 11 return None 12 file1.close() 13 return bvffer
2.处理缓冲区 bvffer的文件,统计每个单词的频率,存放在字典word_freq
1 def process_buffer(bvffer): 2 if bvffer: 3 word_freq = {} 4 # 下面添加处理缓冲区 bvffer代码,统计每个单词的频率,存放在字典word_freq 5 for i in '!"#$%&()*+-,-./:;<=>?@“”[\\]^_{|}~': 6 bvffer = bvffer.replace(i, " ") # 替换特殊字符 7 bvffer = bvffer.lower() # 把大写字母转换为小写 8 words = bvffer.split() # 分割字符串 9 for word in words: 10 word_freq[word] = word_freq.get(word, 0)+1 11 return word_freq
3.用输出函数将处理好的单词按词频排序,输出词频Top10 的单词
1 def output_result(word_freq): 2 if word_freq: 3 sorted_word_freq = sorted(word_freq.items(), key=lambda v: v[1], reverse=True) 4 for item in sorted_word_freq[:10]: # 输出 Top 10 的单词 5 print("%-5s %d " % (item[0], item[1]))
4.设立主函数,用于测试
1 def main(): 2 parser = argparse.ArgumentParser() 3 parser.add_argument('dst') 4 args = parser.parse_args() 5 dst = args.dst 6 bvffer = process_file(dst) 7 word_freq = process_buffer(bvffer) 8 output_result(word_freq)
5.用cProfile对代码性能进行测试
1 if __name__ == "__main__": 2 import cProfile 3 import pstats 4 import argparse 5 cProfile.run("main()", "result") 6 # 直接把分析结果打印到控制台 7 p = pstats.Stats("result") # 创建Stats对象 8 p.sort_stats('calls').print_stats(10) 9 # 按照调用次数排序,打印前10函数的信息 10 p.strip_dirs().sort_stats("cumulative", "name").print_stats(10) 11 p.strip_dirs().sort_stats("cumulative").print_stats() # 按执行时间次数排序 12 p.print_callers(0.5, "process_file") # 得知哪些函数调用了process_file 13 p.print_callers(0.5, "process_buffer") 14 p.print_callers(0.5, "output_result")
二、代码风格
缩进
使用 4 个空格进行缩进
1 def process_buffer(bvffer): 2 if bvffer: 3 word_freq = {}
空格
在二元运算符两边各空一格[=,-,+=,==,>,in,is not, and]
1 bvffer = file1.read()
三、程序运行命令、运行结果截图
1.对Gone_with_the_wind.txt进行词频统计
2.对A_Tale_of_Two_Cities.txt进行词频统计
四、性能分析结果及改进
为了更明显的看出差异,选择对Gone_with_the_wind.txt进行分析和改进
1.性能分析
(1)总运行时间
(2)执行时间、次数最多的部分代码
根据数据可以看出,如果除去函数中调用子函数的运行时间,执行次数最多且执行时间最多的代码是
for word in words: word_freq[word] = word_freq.get(word, 0)+1
2.代码改进
根据测试结果,最耗时间和次数最多的代码并不方便修改,我就从耗费时间第二多的replace 以及 split代码入手,
将原来的代码:
1 for i in '!"#$%&()*+-,-./:;<=>?@“”[\\]^_{|}~': 2 bvffer = bvffer.replace(i, " ") # 替换特殊字符 3 bvffer = bvffer.lower() # 把大写字母转换为小写 4 words = bvffer.strip().split() # 分割字符串
变为:
words = bvffer.lower().strip().split()
结果如下:
运行时间:
结果:比之前的0.669快了0.09秒,对于计算计而言已经算是非常漫长的时间了,在实验过程中我发现当我的电脑处于“繁忙”状态时,运行的总时间是0.97左右,有时候甚至高于1秒,当我把不用的软件关掉时,时间就会缩短,可见电脑性能也会影响实验结果。
四、性能分析结果及改进