Почему запуск .jar занимает в 2-3 раза больше времени, чем запуск тех же файлов .java в ide?

За Пасху я сделал программу, которая берет большой файл журнала, читает его, анализирует и выводит в табличное представление с помощью javafx. Программа работает и поэтому превратилась в .jar с помощью Intellij, чтобы ее можно было легко использовать без IDE.

Однако при запуске программы требуется примерно в 2-3 раза больше времени при запуске методов ввода-вывода в форме JAR программы.

(файл .java) 3,5 секунды чтение -> (файл .jar) 11,3 секунды

(файл .java) 0,014 секунды на запись -> (файл .jar) 0,034 секунды

Я прочитал более старые вопросы об этом. Попробовали синхронизировать методы, убедившись, что используется последняя версия JDK / JRE.

Методы, которые, как я уверен, замедляются при запуске как jar:

/**
 * 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;
}

Редактировать добавил к обоим методам предложение finally, не изменив производительность, хотя

Этот код берет большой файл журнала, ищет в каждой строке искомую строку и добавляет ее в список массивов, а затем создает новый файл. Этот файл значительно меньше, поэтому его легко открыть.

Любая помощь в улучшении производительности jar будет принята с благодарностью, поскольку у меня нет большого опыта работы с файлами .jar!

Обновлено: переход от сканера к буферизированному считывателю радикально улучшил производительность

(файл .java) 1,39 секунды чтение -> (файл .jar) 1,82 секунды

(файл .java) 0,014 секунды на запись -> (файл .jar) 0,034 секунды

/**
 * 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);
}

Конечно, есть еще около полсекунды, но это не так заметно, если кто-нибудь может объяснить, почему существует такая резкая разница между сканером и буферизованным считывателем, я был бы признателен.

Должен ли я всегда использовать буферизованный ридер? Даст ли буферизованный писатель аналогичный прирост производительности? Почему все еще есть разница в производительности?

Спасибо всем :)

Звучит странно. Это может быть кеширование в вашей среде IDE. Возможно, сделайте недействительными какие-либо кеши и перезапустите IDE. Значит, он все еще работает так же быстро? В качестве альтернативы ваша IDE может быть настроена для запуска JVM с большим объемом памяти, чем ваша система при запуске jar. И между прочим: то, как вы пишете файл, не очень «лучшая практика». Вы должны поместить вызов close() в finally. а еще лучше использовать try-with-resources.

user3237736 15.04.2018 14:28

@ user3237736 Я не думаю, что это связано с моей IDE, я впервые заметил разницу между производительностью, когда я запускал этот код на своем ноутбуке, используя netbeans, когда код был немного более беспорядочным, если вы не имеете в виду что-то еще? и спасибо да добавлю блок finally :)

Joe Kerr 15.04.2018 14:42

Хм, может быть, попробуйте использовать BufferedReader вместо Scanner для чтения файла. Я понятия не имею, почему это решит проблему, но черт возьми, почему бы не попробовать

user3237736 15.04.2018 14:46

Записан ли файл в текущий каталог? Когда вы создаете банку, этот файл находится внутри нее?

OneCricketeer 15.04.2018 14:52

@ user3237736 Ну, это имело огромное значение, я заменил сканер на буферизованный ридер, и он занял 1,39 секунды в файле java и 1,82 секунды в файле jar (я обновлю свой вопрос в ближайшее время) есть ли для этого какие-либо причины вы можете думать о. Я не использовал буферизованный ридер, поэтому мало о нем знаю?

Joe Kerr 15.04.2018 15:07

@ cricket_007 файлы, записанные программой, записываются в текущий каталог

Joe Kerr 15.04.2018 15:08

@JoeKerr BufferedReaders может быть быстрее, чем сканеры, особенно для больших файлов. Для объяснения, пожалуйста, Google. Однако я понятия не имею, почему сканер работает намного медленнее в JAR по сравнению с IDE, извините

user3237736 15.04.2018 15:10

BufferedReader - это практически документированный способ чтения файла. stackoverflow.com/a/5868528/2308683. Также ответьте на мой второй вопрос выше? Можете ли вы перечислить его содержимое в файле JAR?

OneCricketeer 15.04.2018 15:14

@ cricket_007 нет, файл отдельный, jar содержит только файлы классов java, которые запускают методы / gui. Затем будет найден путь к этому файлу журнала. Если я понимаю ваш вопрос. И я полагаю, что мне никогда не приходилось использовать ничего, кроме сканеров, чему нас учили.

Joe Kerr 15.04.2018 15:21
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
9
90
0

Другие вопросы по теме