2011-08-18 8 views
11

Abbiamo un'applicazione che importa una grande quantità di file suddividendo i dati e ordinandoli. Quando si esegue il test case JUnit, l'intero processo impiega circa 16 minuti.Perché la mia applicazione è più veloce in IntelliJ rispetto alla riga di comando?

Stesso test, eseguito con mvn clean test -Dtest=MyTest eseguito in 34 minuti.

Stiamo chiamando a /bin/sort per ordinare i file. Il tipo sembra richiedere più tempo. Non capisco cosa è diverso.

Guardando IntelliJ Corre con

/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 

Sono su OS X. Tutte le classi vengono iniettati con Primavera. Quali sono alcuni possibili suggerimenti sono le teorie su cosa c'è dietro questo guadagno di prestazioni in IntelliJ? I test sono identici. Non posso condividere tutto il codice perché c'è così tanto. Ma posso aggiungere qualsiasi dettaglio se richiesto.

Ecco la mia classe principale e come sto eseguendo entrambi.

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())); 
    } 

Ho deciso di rimuovere JUnit e di utilizzare solo un metodo main(). Il risultato è esattamente lo stesso. IntelliJ è di nuovo. Ecco il registro pazzo.

Con 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] 

Con 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] 

Il comando sort è

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

Come potete vedere sopra, l'ordinamento in Intellij prendere 1 minuto ma in java -jar richiede 5 minuti!

Aggiornamento

ho corse tutto utilizzando /Library/Java/JavaVirtualMachines/1.6.0_26-b03-383.jdk/Contents/Home/bin/java e la selezione prende ancora ben più di 5+ minuti.

+0

a quale installazione di Java puntano il comando '' java'' e '' javac''? –

+0

In IntelliJ non funziona più veloce, sta rallentando con Maven! Puoi provare a eseguirlo come una invocazione raw 'java'? –

+0

@hircus/usr/bin/java -> /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java e current è un link simbolico a A. Non ho idea di cosa A sia –

risposta

7

Grazie a tutti per l'aiuto. Si scopre che IntelliJ inizia a ordinare con LANG=C. Il terminale Mac OS X ordina per impostazione predefinita in UTF8 che spiega la perdita di prestazioni. Spero che questa risposta aiuti qualcuno.

1

È mvn clean eseguire una ricostruzione del progetto? La corsa sotto IDEA non lo sta facendo? La realizzazione del progetto con Maven dura 18 minuti (non sarei sorpreso se lo facesse, visto che Maven è l'assoluto)?

Se le risposte a tutte queste domande sono "sì", allora penso che tu abbia una conclusione.

La soluzione è portare Maven nel bosco, fucilarlo e poi seppellirlo in una tomba anonima.

+0

Sto avvolgendo il timer per l'importazione effettiva e non per quanto tempo il processo richiede. Aggiornerò il mio codice. –

+0

Sembra probabile. Prova '' mvn clean compile'' e poi cronometrate una serie di '' mvn test'' dopo –

+0

Ho incollato il mio codice.Non sto compilando nulla.Tutti i file sono stati precompilati in un file jar. l'importazione e non intorno all'inizio di java –

0

Questa domanda non è propriamente definita e non è chiara. Stai dicendo che hai letto un elenco di file in una cartella usando Java IO e poi lo passi a un processo esterno per ordinarli? Mi sembra una soluzione un po 'strana, ma comunque, questo deve essere legato alla memoria. Collegati ad entrambe le app usando JConsole e cerca gli indizi nei grafici.

+0

Sono già connessi a Jconsole e sono entrambi Questo non è un problema con java ma piuttosto con 'bin/sort' chiamato da java. –

+0

Da quello che capisco del tuo problema, sono sicuro al 99% che il problema sia un problema di memoria sta leggendo la lista dei file (non sono sicuro se la tua ipotesi sia stata ancora respinta) o, più probabilmente, un problema di memoria quando si passa l'elenco dei file al processo esterno. – MarianP

0

mvn sta probabilmente lanciando una JVM con diverse opzioni rispetto all'IDE.

Real differences between "java -server" and "java -client"? può causare differenze sostanziali nelle prestazioni per le applicazioni di lunga durata, ma a volte le differenze nei flag gc possono causare differenze di prestazioni quando l'app utilizza la memoria in modi diversi.

Se il tuo processo è legato alla memoria e quindi si blocca a un livello di memoria, i flag di heap come -Xmx possono influenzare drasticamente anche le prestazioni. Il profiling della memoria può facilmente escluderlo.

Per diagnosticare queste differenze, guarda i tuoi file di configurazione mvn per capire come sta lanciando una JVM e guarda la configurazione dell'utilità di avvio delle app java IDE.

+0

Se guardi la mia modifica, ho smesso di usare mvn e ho iniziato a usare solo un semplice file jar compilato con una classe principale. Ancora lo stesso effetto. –

0

Hai provato a utilizzare un profiler come VisualVM per vedere quale è il collo di bottiglia? Confronta anche i grafici di utilizzo della CPU del tuo computer (Mac dovrebbe avere un monitor di sistema). Forse il processo sta bloccando a un certo punto e non funziona in modo efficace, il che potrebbe essere visto come un grafico di utilizzo della CPU di forma diversa.

1

una supposizione più di risposta circostanziata:

Un sacco può dipendere/O buffer di I. Ordinare oltre i record di 500K produrrà un sacco di dati, quindi la giusta dimensione del buffer può essere molto importante. Penso che il tty sia tipicamente bufferizzato in linea, quindi farà 500K di lettura delle operazioni di scrittura & e l'IDE potrebbe semplicemente leggere buffer molto più grandi.

Inoltre, è possibile che OSX abbia una pianificazione di processo o I/O che favorisce pesantemente le app della GUI rispetto a quelle della console (che potrebbero essere rilevate essendo legate a una tty), quindi potrebbe essere necessario attendere & inattivo molto più tempo dalla console che dall'interno dell'IDE.

+0

Sto iniziando a pensare che questo potrebbe essere un problema. Quindi, come lo aggiusto :) –

Problemi correlati