Over Easter I made a program that would take a large log file, read it in and parse it and output this to a table view with javafx. The program works and so made it into a .jar using Intellij so it could easily be used without an IDE.
However when running the program takes about 2-3 times longer when running the I/O methods in the JAR form of the program.
(.java file)3.5 seconds reading in -> (.jar file) 11.3 seconds
(.java file)0.014 seconds writing out -> (.jar file) 0.034 seconds
I have gone through reading the over older questions about this. Have tried timing the methods, making sure the latest JDK/JRE are being used.
The methods I am pretty sure are slowing down when run as a jar are:
/**
* Method that filters a file based on a search string and a selected radio button
*
* @param num index of a selected radio button
* @param filterSearch String that is being searched for
* @param path Of the log file that is being filtered through
* @return The new file that contains only the desired lines
*/
public static String filterFile(int num, String filterSearch, String path) {
long startTime = System.currentTimeMillis();
ArrayList<String> toOutput = new ArrayList<>();
Scanner in = null;
File inputFile = new File(path);
try {
in = new Scanner(inputFile);
String searchString = null;
//While the log file has a line
while (in.hasNext()) {
//the next line to be searched is stored in searchString
searchString = in.nextLine();
switch (num) {
//if the user radio button is selected
case 1:
//if the searchString contains the filter search
//print the whole line to the new file
if (searchString.contains("user=\"" + filterSearch)) {
//System.out.println(searchString);
toOutput.add(searchString);
}
break;
case 2:
//if the searchString contains the filter search
//print the whole line to the new file
if (searchString.contains("srcip=\"" + filterSearch)) {
toOutput.add(searchString);
}
break;
}
}
} catch (Exception e) {
System.out.println("Cannot open file: ");
System.exit(0);
}finally {
in.close();
}
long endTime = System.currentTimeMillis();
double duration = (endTime - startTime)/1000.0;
System.out.println("first formatedSeconds = "+ duration);
return createFilterFile(toOutput);
}
/**
* Create a new file with the filtered results inside
* @param toPrint lines from the log file that have been filtered out
* @return Path to this new file
*/
private static String createFilterFile(ArrayList<String> toPrint){
long startTime = System.currentTimeMillis();
Date date = new Date();
String fileName = "New filtered search file " + sdf.format(date) + ".log";
PrintWriter out = null;
try{
FileWriter outputFile = new FileWriter(fileName, true);
out = new PrintWriter(outputFile);
for(String item: toPrint){
out.println(item);
}
}catch(Exception e){
e.printStackTrace();
}finally {
out.close();
}
long endTime = System.currentTimeMillis();
double duration = (endTime - startTime)/1000.0;
// formatedSeconds = (0.xy seconds)
System.out.println("second formatedSeconds = "+ duration);
return fileName;
}
Edit added finally clause to both methods, didnt change any performance tho
This code takes the large log file, searches for each line for a searched string and adds it to an array list, then create a new file. This file is significantly smaller so can be easily opened.
Any help towards improving the performance of the jar would be appreciated and as I don't have much experience with .jar files!
EDIT: Changing From a scanner to a buffered reader drastically improved performance
(.java file)1.39 seconds reading in -> (.jar file) 1.82 seconds
(.java file)0.014 seconds writing out -> (.jar file) 0.034 seconds
/**
* Method that filters a file based on a search string and a selected radio button
*
* @param num index of a selected radio button
* @param filterSearch String that is being searched for
* @param path Of the log file that is being filtered through
* @return The new file that contains only the desired lines
*/
public static String filterFile(int num, String filterSearch, String path) {
long startTime = System.currentTimeMillis();
ArrayList<String> toOutput = new ArrayList<>();
BufferedReader reader = null;
File inputFile = new File(path);
try {
reader = new BufferedReader(new FileReader(inputFile));
String searchString = null;
//While the log file has a line
//the next line to be searched is stored in searchString
while ((searchString = reader.readLine())!=null) {
switch (num) {
//if the user radio button is selected
case 1:
//if the searchString contains the filter search
//print the whole line to the new file
if (searchString.contains("user=\"" + filterSearch)) {
toOutput.add(searchString);
}
break;
case 2:
//if the searchString contains the filter search
//print the whole line to the new file
if (searchString.contains("srcip=\"" + filterSearch)) {
toOutput.add(searchString);
}
break;
}
}
} catch (IOException e) {
System.out.println("Cannot open file: ");
System.exit(0);
}finally {
try{
reader.close();
}catch (IOException ef){
}
}
long endTime = System.currentTimeMillis();
double duration = (endTime - startTime)/1000.0;
System.out.println("first formatedSeconds = "+ duration);
return createFilterFile(toOutput);
}
Ofcourse there is still about half a second but this is not so noticeable if anyone can explain why there is such a drastic difference between scanner and buffered reader I would be appreciative.
Should I always use buffered reader? Is buffered writer going to give a similar performance increase? Why is there still a performance difference ?
Thanks everyone :)