20180925-3 效能分析
此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2145
Git地址为:https://git.coding.net/Ljr6899/Wf.git
要求0 以 战争与和平 作为输入文件,重读向由文件系统读入。连续三次运行,给出每次消耗时间、CPU参数。
测试用例:《战争与和平》,以https://coding.net/u/younggift/p/word_count_demo/git/blob/master/war_and_peace.txt为数据输入。
CPU参数:Intel(R) Core(TM) i74500U CPU @ 1.80GHz 1.80GHz
要求1 猜测存在的瓶颈
判断参数是否是文件目录或是否是文件,次I/O操作会比较耗时。file.getPath()和Print()也都可能是方法中耗时的I/O操作。因为I/O操作和打印操作以及遍历都是比较耗时的操作。可能只会提升零点几秒。
1 File f = new File(args[0]); 2 if (f.isDirectory()) { 3 File[] filelist = f.listFiles(); 4 for (File file : filelist) { 5 try { 6 String s = file.getPath();//地址回溯 7 System.out.println(s); 8 FileCode(s); 9 } catch (Exception ex) { 10 } 11 } 12 } else if (f.isFile()) { 13 String s = f.getPath();//地址回溯 14 System.out.println(s); 15 FileCode(s); 16 }9
要求2 Profile分析
为了方便效能测试,main方法中添加了Thread.sleep(1000),所以main方法有过长耗时。
以下三个代码片段最为耗时
1 public static void main(String[] args) throws InterruptedException { 2 Thread.sleep(10000); //用来测试效能分析 3 int argNum; 4 argNum = args.length; //0单行输入,1,重定向或者单个文件或者一系列文件 5 switch (argNum) { 6 case 1: 7 ContributetTask(args); 8 break; 9 case 0: 10 System.out.println("进入命令行输入模式"); 11 LineCode(); 12 break; 13 default: 14 System.out.println("输入参数无效"); 15 break; 16 } 17 }
1 public static void FileCode(String args) { 2 try { 3 BufferedReader bf = null; 4 //程序中调用,内层参数认为是安全的 5 if (args == "") { 6 bf = new BufferedReader(new InputStreamReader(System.in)); 7 } else { 8 bf = new BufferedReader(new FileReader(args)); 9 } 10 List<String> lists = new ArrayList<String>(); //存储过滤后单词的列表 11 String s; 12 while ((s = bf.readLine()) != null) { 13 String[] wordsArr1 = s.toLowerCase().split("[^a-zA-Z]"); 14 for (String word : wordsArr1) { 15 if (word.length() != 0) { //去除长度为0的行 16 lists.add(word); 17 } 18 } 19 } 20 System.out.println("total:" + lists.size()); 21 StatisticalCode(lists); 22 } catch (IOException ex) { 23 System.out.println(ex.getMessage()); 24 } 25 }
1 public static void StatisticalCode(List<String> lists) { 2 //统计排序 3 Map<String, Integer> wordsCount = new TreeMap<String, Integer>(); //存储单词计数信息,key值为单词,value为单词数 4 //单词的词频统计 5 for (String li : lists) { 6 if (wordsCount.get(li) != null) { 7 wordsCount.put(li, wordsCount.get(li) + 1); 8 } else { 9 wordsCount.put(li, 1); 10 } 11 } 12 // System.out.println("wordcount.Wordcount.main()"); 13 SortMap(wordsCount); //按值进行排序 14 }
要求3 根据瓶颈,"尽力而为"地优化程序性能。
去掉没必要的print 和 在本次作业中 认为安全的逻辑判断引发的IO耗时操作。
要求4 再次Profile
要求1 中的最花费时间的3个函数此时的花费如下图:
要求5 老师测评