如何加快下面代码片段的执行速度

时间:2017-09-06 08:36:03

标签: java multithreading performance file

我的目标是:我想读取特定文本的文件,我想在其他目录/子目录中找到包含所有文件的文本。但是目前程序执行速度很慢。我多次运行该程序来检查性能。我目前在我的系统中使用jdk1.6。任何人都可以改善执行时间或指导如何获得更好的表现吗?

  import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileReader;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    import java.util.Scanner;


    public class ActionFinder {
        private static final String FILENAME = "D:\\WorkSpace\\data\\Navigation.properties";
        private static ArrayList<String> allAbsoluteFilePathList = new ArrayList<String>();
    public static void main(String[] args) {
        BufferedReader br = null;
        FileReader fr = null;
        try {
            fr = new FileReader(FILENAME);
            br = new BufferedReader(fr);
            String sCurrentLine;
            ArrayList<String> actionList = new ArrayList<String>(); 


            while ((sCurrentLine = br.readLine()) != null) {

                String cmdString = sCurrentLine;

                  if(cmdString.contains(".Commands")){
                      String[] output = cmdString.split("\\.Commands");
                      actionList.add("Action."+output[0]); 

                  }

            }

              listAllTheFile("D:\\dev\\vob002\\IB\\war\\src\\main\\webapp\\web\\L001\\corporate");

            //here we are finding all the actions one by one from the file list
            for(int i=0; i < actionList.size(); i++){
                String actionName= actionList.get(i);
                searchAction(allAbsoluteFilePathList, actionName);
            }



        } catch (Exception e) {
            System.out.println("Error2: " + e.toString());

        } finally {
            try {
                if (br != null)
                    br.close();

                if (fr != null)
                    fr.close();

            } catch (Exception ex) {
                System.out.println("Error3: " + ex.toString());

            }

        }
    }


    private static void searchAction(ArrayList<String> allAbsoluteFilePathList, String actionName) {
        try {

          if(null !=allAbsoluteFilePathList){
              for(int i=0; i < allAbsoluteFilePathList.size(); i++){

                  final Scanner scanner = new Scanner(new File(allAbsoluteFilePathList.get(i)));
                  while (scanner.hasNextLine()) {
                     final String lineFromFile = scanner.nextLine();
                     if(lineFromFile.contains(actionName)) { 
                         // a match!
                         System.out.println("I found " +actionName+ " in file " + allAbsoluteFilePathList.get(i));
                         break;
                     }
                  }
              } 

          }




          }catch (Exception e) {
             System.out.println("Error1: " + e.toString());

        }

    }


    private static List<File> listAllTheFile(String directoryName) {
        File directory = new File(directoryName);
        List<File> resultList = new ArrayList<File>();

        File[] fList = directory.listFiles();
        resultList.addAll(Arrays.asList(fList));

        for (File file : fList) {

            if (file.isFile()) {
                allAbsoluteFilePathList.add(file.getAbsolutePath());
            } else if (file.isDirectory()) {
                resultList.addAll(listAllTheFile(file.getAbsolutePath()));
            }
        }

        return resultList;
    }

    }

3 个答案:

答案 0 :(得分:1)

正如评论中已经说过的那样,尝试通过使用个人资料找出您的表现丢失的位置。独立于此,有些点可以改进(不一定与性能相关,但仍然......; - ):

fr = new FileReader(FILENAME);
br = new BufferedReader(fr);

请勿使用FileReader,但请打开如下文件:

fr = new InputStreamReader(new FileInputStream(FILENAME), "8859_1");
br = new BufferedReader(fr);

FileReader使用系统的字符集将内容转换为可能不是您的文件编码字符集的文本。

if (cmdString.contains(".Commands")){
    String[] output = cmdString.split("\\.Commands");
    actionList.add("Action."+output[0]); 
}

您正在调用contains并创建一个基本相同的正则表达式。 split每次进行拆分时都会创建并编译Pattern。所有这些都可以通过直接使用正则表达式来处理。如果您在循环外编译Pattern,这应该有助于提高性能,因为它只执行一次而不是n次。

} catch (Exception e) {
    System.out.println("Error1: " + e.toString());
}

如果抛出异常,这没有用,通常你需要完整的堆栈跟踪,所以如果你真的必须输出错误,那么e.printStackTrace()是首选。

答案 1 :(得分:1)

尝试这样的事情:

public class ActionFinder
{
   private static final String FILENAME = "D:/WorkSpace/data/Navigation.properties";
   private static List<String> allAbsoluteFilePathList = new ArrayList<>();
   public static void main(String[] args)
   {
      try (final BufferedReader br = new BufferedReader(new InputStreamReader(
                                     new FileInputStream(FILENAME), "UTF-8")))
      {
          List<String> actionList = new ArrayList<>(); 
          while (true) // infinte loop
          {
             final String sCurrentLine = br.readLine()
             if (null == sCurrentLine)
             {
                break; // leave the loop at the end of file
             }
             else
             {
                // indexOf and substring is faster than parsing a RegEx and then
                // instantiating an array of String objects...
                final int pos = sCurrentLine.indexOf(".Commands");
                if (pos >= 0)
                {
                   actionList.add("Action." + sCurrentLine.substring(0, pos)); 
                }
             }
          }
          listAllTheFile(new File("D:/dev/vob002/IB/war/src/main/webapp/web/L001/corporate")
                             .getAbsoulteFile());
          // here we are finding all the actions one by one from the file list
          for(final String actionName : actionList)
          {
             searchAction(allAbsoluteFilePathList, actionName);
          }
      }
      catch (Exception e)
      {
         e.printStackTrace();
      }
   }

   private static void searchAction(List<String> allAbsoluteFilePathList, String actionName)
   {
      if (null != allAbsoluteFilePathList)
      {
         // Entering/leaving a TRY block uses resources, so placing it inside the if
        // statement seems logical...
         try
         {
            for(final String absFilePath : allAbsoluteFilePathList)
            {
               final Scanner scanner = new Scanner(new File(absFilePath));
               while (scanner.hasNextLine())
               {
                  final String lineFromFile = scanner.nextLine();
                  if(lineFromFile.contains(actionName))
                  { 
                     // a match!
                     // printf is faster than String + String...
                     // Also, allAbsoluteFilePathList.get() is only called once...
                     System.out.printf("I found %s in file %s%n", actionName, absFilePath);
                     break;
                  }
               }
            }
         }
         catch (Exception e)
         {
            e.printStackTrace();
         }
      }
   }

   // The return value of this result, a collection was never used...
   // Changed it to not return anything.
   private static void listAllTheFile(File directory)
   {
      final File[] fList = directory.listFiles();
      for (final File file : fList)
      {
         if (file.isFile())
         {
            // As the root call is made with an absolute path, it is not necessary to call
            // getAbsolutePath every time...
            allAbsoluteFilePathList.add(file.getPath());
         }
         else if (file.isDirectory())
         {
            // As the argument is changed to File, do not need to call getAbsolutePath
            // method on the recursion...
            listAllTheFile(file);
         }
      }
   }
}

答案 2 :(得分:0)

看起来像你:

  1. 查找文件中的所有操作。
  2. 对于您找到的每个操作:
    1. 搜索文件列表。
    2. 对于每个文件中的每一行:
      1. 如果该行动出现在该行中,请执行某些操作。
  3. 你会做得更好,比如:

    1. 查找文件中的所有操作。
    2. 搜索文件列表。
      1. 对于每个文件中的每一行:
        1. 对于您找到的每个操作:
          1. 如果您的某个操作出现在该行中,请执行某些操作。
    3. 这里的主要好处是您只搜索此文件列表一次。