20190919-3 效能分析
作业要求详见:[https://edu.cnblogs.com/campus/nenu/2019fall/homework/7628]
代码地址:https://e.coding.net/SpringSun/wf.git
要求0 以 战争与和平 作为输入文件,重读向由文件系统读入。连续三次运行,给出每次消耗时间、CPU参数。 (2分)
| 次数 | 耗时(s) |
| 1 | 1.193 |
| 2 | 1.180 |
| 3 | 1.168 |
| 平均 | 1.180 |



CPU参数:Intel(R)Core(TM) i5-5200U CPU @2.20 GHz

要求1 给出你猜测程序的瓶颈。你认为优化会有最佳效果,或者在上周在此处做过优化 (或考虑到优化,因此更差的代码没有写出) 。
从字符输入流中读取文本并缓冲字符,由于文本里有大量单词,还需要过滤掉除字母以外的字符,我认为这个会非常耗时。
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));// 从字符输入流中读取文本并缓冲字符
List<String> list = new ArrayList<String>(); // 存储过滤后单词的列表
String readLine = null;
while ((readLine = br.readLine()) != null) {
String[] wordsArr = readLine.split("[^a-zA-Z]"); // 过滤掉除字母以外的字符
for (String word : wordsArr) {
if (word.length() != 0) { // 去除长度为0的行
list.add(word);
}
}
}
要求2 通过 profile 找出程序的瓶颈。给出程序运行中最花费时间的3个函数(或代码片断)。要求包括截图。 (5分)
对于笨笨的都不知道啥是profile,更不知道怎么对自己的程序profile。先是问了已经发布博客的同学是怎样做的,然后查询了往届学长学姐的实例,然后下载了一个verysleepys,又在网上找了大量相关资料,感觉不错的推荐看:https://www.cnblogs.com/duanxz/p/3492890.html
本次用的是JDK1.8自带的jvisualvm.exe来进行profile分析,由于程序功能单一,运行比较快,在main函数中加入以下代码,延长程序执行时间,便于及时查看profile分析结果。
Thread.sleep(10000); //测试效能分析
下面分别是main()、TexCount()、WordCount()等函数的CPU、内存占用时间和分布情况。

统过上面两张图即可看出,该功能耗时比较长的是分别是split.()、BufferedReader.readLine()等函数。
//split.()函数比较耗时
String[] wordsArr = readLine.split("[^a-zA-Z]"); // 过滤掉除字母以外的字符
要求3 根据瓶颈,"尽力而为"地优化程序性能。
由于该功能比较单一,所用到的函数不多,不会有太大的性能提升。可做的优化有,去掉没有必要的print,优化了函数调用逻辑,精简了代码量,使得代码可复用等。以下便是优化后的代码片段、耗时表和截图。
public static void main(String args[]) throws InterruptedException {
Thread.sleep(10000); //测试效能分析
if ("-d".equals(args[0])){//功能1、2实现:
String path = "D:/Project/JAVA/text/" + args[1] + ".txt";
try {
textCount(path);// 单个文件过滤单词
} catch (Exception ex) {
System.out.println("请输入正确的文件名称,确认文件存在以及文件是否放在D:/Project/JAVA/text/");
}
}else if ("-f".equals(args[0])){
//功能3实现:
String path1 = args[1];
File file = new File(path1);
if (file.isDirectory()) {
File[] filelist = file.listFiles();
for (File filePath : filelist) {
try {
String s = filePath.getPath();// 获取完整路径
System.out.println(filePath.getName());//输出文件名
textCount(s);
} catch (Exception ex) {
System.out.println("请输入正确的路径,格式:D:/Project/JAVA/text/");
}
}
}
}else if("-s".equals(args[0])){
//功能4实现:
try {
TxtCount();
} catch (Exception ex) {
System.out
.println("请输入正确的命令,eg:java WF.WF < a1.txt,确定后文件存在以及文件是否放在*.java文件目录");
}
}
}
| 次数 | 耗时(s) |
| 1 | 1.134 |
| 2 | 1.126 |
| 3 | 1.131 |
| 平均 | 1.130 |



要求4 再次Profile
经过精细化调优代码后,从下面的Profile可以看出CPU和内存耗时有明显的缩短。


要求5 程序运行时间。
期待老师的检验和指导。

浙公网安备 33010602011771号