Подтвердить что ты не робот

Почему мое приложение работает быстрее в IntelliJ по сравнению с командной строкой?

У нас есть приложение, которое импортирует большое количество файлов, разбивая данные и сортируя их. При запуске тестового примера JUnit весь процесс занимает около 16 минут.

Те же тесты, выполненные с mvn clean test -Dtest=MyTest, выполняются 34 минуты.

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

Глядя на IntelliJ, он работает с

/Library/Java/JavaVirtualMachines/1.6.0_26-b03-383.jdk/Contents/Home/bin/java -Didea.launcher.port=7532 -Didea.launcher.bin.path=/Applications/IntelliJ IDEA 10.app/bin -Dfile.encoding=UTF-8 -classpath %classhpath% com.intellij.rt.execution.application.AppMain com.intellij.rt.execution.junit.JUnitStarter -ideVersion5 -junit4 xxx.IntTestImportProcess,testImportProcess

Я на OS X. Все классы вводятся с помощью Spring. Каковы некоторые возможные предложения - теории, стоящие за этим ростом производительности в IntelliJ? Тесты идентичны. Я не могу разделить весь код, потому что есть так много. Но я могу добавить любую деталь, если потребуется.

Вот мой основной класс и как я запускаю оба.

public static void main(String... args) throws IOException {
        if(args.length != 2) {
            System.out.println("Usage: \n  java -jar client.jar spring.xml data_file");
            System.exit(1);
        }
        ApplicationContext applicationContext = new FileSystemXmlApplicationContext(args[0]);
        PeriodFormatter formatter = new PeriodFormatterBuilder()
                .appendMinutes()
                .appendSuffix("minute", "minutes")
                .appendSeparator(" and ")
                .appendSeconds()
                .appendSuffix("second", "seconds")
                .toFormatter();
        URI output = (URI) applicationContext.getBean("workingDirectory");
        File dir = new File(output);
        if(dir.exists()) {
            Files.deleteDirectoryContents(dir.getCanonicalFile());
        }
        else {
            dir.mkdirs();
        }
        ImportProcess importProcess = applicationContext.getBean(ImportProcess.class);
        long start = System.currentTimeMillis();
        File file = new File(args[1]);
        importProcess.beginImport(file);
        Period period = new Period(System.currentTimeMillis() - start); // in milliseconds
        System.out.println(formatter.print(period.toPeriod()));
    }

Я решил удалить JUnit и просто использовать метод main(). Результат точно такой же. IntelliJ снова. Вот сумасшедший журнал.

С IntelliJ

DEBUG [ main] 2011-08-18 13:05:16,259 [er.DelimitedTextUnixDataSorter] Sorting file [/Users/amirraminfar/Desktop/import-process/usage]
DEBUG [ main] 2011-08-18 13:06:09,546 [er.DelimitedTextUnixDataSorter] Sorting file [/Users/amirraminfar/Desktop/import-process/customer]

С java -jar

DEBUG [ main] 2011-08-18 12:10:16,726 [er.DelimitedTextUnixDataSorter] Sorting file [/Users/amirraminfar/Desktop/import-process/usage]
DEBUG [ main] 2011-08-18 12:15:55,893 [er.DelimitedTextUnixDataSorter] Sorting file [/Users/amirraminfar/Desktop/import-process/customer]

Команда сортировки

sort -t'    ' -f -k32,32f -k18,18f -k1,1n

Как вы можете видеть выше, сортировка в Intellij занимает 1 минута, но в java -jar занимает 5 минут!

Обновление

Я запускал все, используя /Library/Java/JavaVirtualMachines/1.6.0_26-b03-383.jdk/Contents/Home/bin/java, и сортировка по-прежнему занимает более 5 минут.

4b9b3361

Ответ 1

Спасибо всем за помощь. Оказывается, IntelliJ начинает сортировку с LANG=C. Терминал Mac OS X сортируется по умолчанию в UTF8, что объясняет потерю производительности. Надеюсь, этот ответ поможет кому-то.

Ответ 2

Является ли mvn clean выполнение перестройки проекта? Пробег под IDEA не делает этого? Совершает ли проект проект с Maven 18 минут (я бы не удивился, если бы это произошло, учитывая, что Maven - это абсолютные ямы)?

Если ответы на все эти вопросы "да", то я думаю, что у вас есть вывод.

Решение состоит в том, чтобы взять Мейвена в лес, застрелить его, а затем похоронить его в немаркированной могиле.

Ответ 3

Угадайте более чем обоснованный ответ:

Многое может зависеть от буферизации ввода-вывода. Сортировка более 500 тыс. Записей будет выводить много данных, поэтому правильный размер буфера может иметь большое значение. Я думаю, что tty, как правило, буферизируется в строке, поэтому он будет делать операции чтения и записи 500K, а среда IDE может просто читать в гораздо более крупных буферах.

Кроме того, возможно, что OSX имеет планирование процессов или ввода-вывода, которое в значительной степени благоприятствует приложениям графического интерфейса пользователя над консольными (что может быть обнаружено посредством привязки к tty), поэтому может потребоваться, чтобы вам пришлось ждать и простаивать больше времени с консоли, чем из среды IDE.

Ответ 4

Этот вопрос не совсем правильно определен и далек от ясности. Вы считаете, что вы читаете список файлов в папке с использованием Java IO, а затем передаете ее внешнему процессу для их сортировки? Звучит как немного странное решение для меня, но в любом случае это должно быть связано с памятью. Подключайтесь к обоим приложениям с помощью JConsole и ищите подсказки в диаграммах.

Ответ 5

mvn, вероятно, запускает JVM с различными параметрами, чем ваша среда IDE.

Реальные различия между "java -сервером" и "java -client" ? могут привести к существенным различиям в производительности для приложений с длительным сроком выполнения, но иногда различия в gc-флагах могут вызывать разницу в производительности, когда ваше приложение использует память по-разному.

Если ваш процесс связан с памятью, и, таким образом, на каком-то уровне памяти, кучи флагов, таких как -Xmx, могут также сильно повлиять на производительность. Профилирование данных может легко управлять этим в или из.

Чтобы диагностировать эти различия, просмотрите конфигурационные файлы mvn, чтобы выяснить, как он запускает JVM, и посмотрите на конфигурацию запуска Java-приложения IDE.

Ответ 6

Вы пытались использовать профилировщик, например VisualVM, чтобы узнать, что является узким местом? Также сравните графики использования процессора вашего компьютера (у Mac должен быть некоторый системный монитор). Возможно, процесс блокируется в какой-то момент и не работает эффективно, что можно рассматривать как график использования процессора различной формы.