Ответ 1
Спасибо всем за помощь. Оказывается, IntelliJ начинает сортировку с LANG=C
. Терминал Mac OS X сортируется по умолчанию в UTF8
, что объясняет потерю производительности. Надеюсь, этот ответ поможет кому-то.
У нас есть приложение, которое импортирует большое количество файлов, разбивая данные и сортируя их. При запуске тестового примера 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 минут.
Спасибо всем за помощь. Оказывается, IntelliJ начинает сортировку с LANG=C
. Терминал Mac OS X сортируется по умолчанию в UTF8
, что объясняет потерю производительности. Надеюсь, этот ответ поможет кому-то.
Является ли mvn clean
выполнение перестройки проекта? Пробег под IDEA не делает этого? Совершает ли проект проект с Maven 18 минут (я бы не удивился, если бы это произошло, учитывая, что Maven - это абсолютные ямы)?
Если ответы на все эти вопросы "да", то я думаю, что у вас есть вывод.
Решение состоит в том, чтобы взять Мейвена в лес, застрелить его, а затем похоронить его в немаркированной могиле.
Угадайте более чем обоснованный ответ:
Многое может зависеть от буферизации ввода-вывода. Сортировка более 500 тыс. Записей будет выводить много данных, поэтому правильный размер буфера может иметь большое значение. Я думаю, что tty, как правило, буферизируется в строке, поэтому он будет делать операции чтения и записи 500K, а среда IDE может просто читать в гораздо более крупных буферах.
Кроме того, возможно, что OSX имеет планирование процессов или ввода-вывода, которое в значительной степени благоприятствует приложениям графического интерфейса пользователя над консольными (что может быть обнаружено посредством привязки к tty), поэтому может потребоваться, чтобы вам пришлось ждать и простаивать больше времени с консоли, чем из среды IDE.
Этот вопрос не совсем правильно определен и далек от ясности. Вы считаете, что вы читаете список файлов в папке с использованием Java IO, а затем передаете ее внешнему процессу для их сортировки? Звучит как немного странное решение для меня, но в любом случае это должно быть связано с памятью. Подключайтесь к обоим приложениям с помощью JConsole и ищите подсказки в диаграммах.
mvn
, вероятно, запускает JVM с различными параметрами, чем ваша среда IDE.
Реальные различия между "java -сервером" и "java -client" ? могут привести к существенным различиям в производительности для приложений с длительным сроком выполнения, но иногда различия в gc-флагах могут вызывать разницу в производительности, когда ваше приложение использует память по-разному.
Если ваш процесс связан с памятью, и, таким образом, на каком-то уровне памяти, кучи флагов, таких как -Xmx
, могут также сильно повлиять на производительность. Профилирование данных может легко управлять этим в или из.
Чтобы диагностировать эти различия, просмотрите конфигурационные файлы mvn
, чтобы выяснить, как он запускает JVM, и посмотрите на конфигурацию запуска Java-приложения IDE.
Вы пытались использовать профилировщик, например VisualVM, чтобы узнать, что является узким местом? Также сравните графики использования процессора вашего компьютера (у Mac должен быть некоторый системный монитор). Возможно, процесс блокируется в какой-то момент и не работает эффективно, что можно рассматривать как график использования процессора различной формы.