Java 如何加快以下代码段的执行速度
我的目标是:我想读取一个文件中的特定文本,并在包含所有文件的其他目录/子目录中找到该文本。但目前程序执行速度非常慢。我多次运行该程序以检查性能。我目前在我的系统中使用jdk1.6。有谁能改进执行时间或指导如何获得更好的性能Java 如何加快以下代码段的执行速度,java,multithreading,performance,file,Java,Multithreading,Performance,File,我的目标是:我想读取一个文件中的特定文本,并在包含所有文件的其他目录/子目录中找到该文本。但目前程序执行速度非常慢。我多次运行该程序以检查性能。我目前在我的系统中使用jdk1.6。有谁能改进执行时间或指导如何获得更好的性能 import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.u
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;
}
}
导入java.io.BufferedReader;
导入java.io.File;
导入java.io.FileReader;
导入java.io.IOException;
导入java.util.ArrayList;
导入java.util.array;
导入java.util.List;
导入java.util.Scanner;
公共类ActionFinder{
私有静态最终字符串FILENAME=“D:\\WorkSpace\\data\\Navigation.properties”;
私有静态ArrayList AllabSolutionFilePath列表=新ArrayList();
公共静态void main(字符串[]args){
BufferedReader br=null;
FileReader fr=null;
试一试{
fr=新文件读取器(文件名);
br=新的缓冲读取器(fr);
弦电流线;
ArrayList actionList=新建ArrayList();
而((sCurrentLine=br.readLine())!=null){
字符串cmdString=sCurrentLine;
if(cmdString.contains(“.Commands”)){
字符串[]输出=cmdString.split(\\.Commands”);
actionList.add(“Action.”+输出[0]);
}
}
列出所有文件(“D:\\dev\\vob002\\IB\\war\\src\\main\\webapp\\web\\L001\\corporate”);
//在这里,我们从文件列表中逐个查找所有操作
对于(int i=0;i
它看起来像你:
这里的主要好处是,您只需搜索此文件列表一次。如评论中所述,请尝试使用配置文件找出性能损失的地方。独立于此,这里有一些可以改进的地方(不一定与性能相关,但仍然…;-): 不要使用
FileReader
,而是像这样打开一个文件:
fr = new InputStreamReader(new FileInputStream(FILENAME), "8859_1");
br = new BufferedReader(fr);
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);
}
}
}
}
FileReader
使用系统的字符集将内容转换为可能不是文件编码字符集的文本
if (cmdString.contains(".Commands")){
String[] output = cmdString.split("\\.Commands");
actionList.add("Action."+output[0]);
}
您正在调用contains
,并创建一个正则表达式,执行基本相同的操作。每次执行拆分时,“拆分”都会创建并编译模式。所有这些都可以通过直接使用正则表达式来处理。如果在循环外部编译模式
,这将有助于提高性能,因为它只执行一次而不是n次
} catch (Exception e) {
System.out.println("Error1: " + e.toString());
}
如果引发异常,这将没有帮助,通常您需要完整的stacktrace,因此如果您确实必须输出错误,则首选
e.printStackTrace()
。尝试以下方法:
fr = new InputStreamReader(new FileInputStream(FILENAME), "8859_1");
br = new BufferedReader(fr);
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);
}
}
}
}
公共类ActionFinder
{
私有静态最终字符串FILENAME=“D:/WorkSpace/data/Navigation.properties”;
私有静态列表allAbsoluteFilePathList=新ArrayList();
公共静态void main(字符串[]args)
{
try(final BufferedReader br=new BufferedReader(new InputStreamReader(
新文件输入流(文件名,“UTF-8”))
{
List actionList=新建ArrayList();
while(true)//infinte循环
{
最终字符串sCurrentLine=br.readLine()
if(null==sCurrentLine)
{
break;//离开t