为什么我的应用程序在IntelliJ中比命令行运行得更快?

我们有一个应用程序通过拆分数据并对其进行排序来导入大量文件。 运行JUnit测试用例时,整个过程大约需要16分钟

同样的测试,用mvn clean test -Dtest=MyTest34分钟内完成

我们正在调用/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命令是

 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分钟。

谢谢大家的帮助。 事实certificate,IntelliJ以LANG=C开始排序。 Mac OS X终端默认以UTF8排序,这解释了性能损失。 希望这个答案会对某人有所帮助。

mvn clean是否正在重建项目? 在IDEA下运行不是这样吗? 使用Maven构建项目需要18分钟(如果确实如此,我会不会感到惊讶,因为Maven是绝对的坑)?

如果所有这些问题的答案都是“是”,那么我认为你得出结论。

解决方案是将Maven带到树林里,拍摄它,然后把它埋在一个没有标记的坟墓里。

一个猜测超过证实的答案:

很多可能取决于I / O缓冲。 排序超过500K的记录将输出大量数据,因此正确的缓冲区大小可能很重要。 我认为tty通常是行缓冲的,因此它将执行500K读写操作,IDE可能只是读取更大的缓冲区。

此外,OSX可能有进程或I / O调度,它比控制台应用程序更有利于GUI应用程序(可以通过绑定到tty来检测),因此可能需要等待和闲置更多时间从控制台而不是在IDE中。

这个问题没有完全正确定义,而且还不清楚。 您是说您使用Java IO读出文件夹中的文件列表,然后将其传递给外部进程进行排序? 对我来说听起来有点奇怪的解决方案,但无论如何,这必须与内存有关。 使用JConsole连接到这两个应用程序,并在图表中查找线索。

mvn可能正在推出一个具有与IDE不同的选项的JVM。

“java -server”和“java -client”之间的真正区别? 对于长时间运行的应用程序,可能会导致性能的显着差异,但是当您的应用程序以不同方式使用内存时,gc标志的差异有时会导致性能差异

如果您的进程受内存限制并因此在某些内存级别发生崩溃,则像-Xmx这样的堆标志也会极大地影响性能。 内存分析可以轻松地对此进行排除。

要诊断这些差异,请查看您的mvn配置文件以了解它是如何启动JVM的,并查看您的IDE Java应用程序启动器配置。

您是否尝试过使用VisualVM等分析器来查看瓶颈是什么? 还要比较计算机的CPU使用率图表(Mac应该有一些系统监视器)。 也许这个过程在某些时候是阻塞而不能有效地工作,这可以看作是不同形状的CPU使用率图。