Fattori che influenzano le prestazioni di questa applicazione Java

2

Ho un'applicazione Java che effettua le seguenti operazioni:

  1. Lo strumento prende un documento che analizzerà.
  2. Strumento chiama servizio web esterno
  3. Lo strumento completa l'esecuzione

Tuttavia, quando ho provato a eseguire questa applicazione in due "ambienti" diversi, c'è un enorme divario tra le prestazioni dello strumento. Nel primo ambiente ci vogliono solo 30 secondi, mentre nel secondo strumento ci sono voluti 40 minuti.

Un ambiente è costituito da quanto segue:

  1. La macchina su cui viene eseguita l'app.
  2. La connessione al webservice.
  3. Il documento di input che verrà analizzato dallo strumento.

Sono stato in costante comunicazione tra le persone nel secondo ambiente (40 minuti di esecuzione), e sono abbastanza perplesso.

Sto cercando di isolare il problema. Per prima cosa, ho chiesto le specifiche della macchina che stanno usando e questo sembra andare bene. Ho quindi chiesto la loro connessione al webservice e va bene anche.

Il documento di input tra i due ambienti (in questo caso) è lo stesso; L'ho mantenuto una variabile costante in modo da avere meno problemi da controllare.

Stranamente, ho chiesto maggiori informazioni e ho scoperto che ci vuole molto tempo con l'analisi del documento di input. Nell'esecuzione di 40 minuti, lo strumento è stato "bloccato" durante l'analisi per 38 minuti. Stavo pensando se fosse il mio codice, ma sono abbastanza confuso dal fatto che il primo ambiente abbia impiegato solo pochi secondi per analizzare lo stesso documento.

La struttura generale del mio parsing è la seguente:

do{
   ... code here.
   do {
      ... code here.
      for{}
   }while
}while
for{}
do{
  ... code here.
}while

code here sono miscele di istruzioni if e chiamate di funzione (tuttavia viene utilizzata solo una funzione ed è generalmente ifs, no loop).

So che i cicli annidati richiedono un po 'di tempo e questo è peggio di O(n^2) e so che ho bisogno di lavorare sulla mia ottimizzazione, ma potrebbe davvero essere il codice che causa questo enorme divario tra le prestazioni o c'è un altro fattore questo potrebbe causare questo gap?

    
posta Kawamoto Takeshi 26.08.2016 - 05:48
fonte

2 risposte

2

Sebbene tu abbia fatto un buon lavoro nel determinare il problema determinando che proviene dall'analisi stessa (e non, ad esempio, dalle chiamate al servizio web), c'è ancora del lavoro da fare per trovare il collo di bottiglia effettivo.

Questo di solito è fatto con un profiler. Sfortunatamente, immagino che non sia possibile eseguire un profiler nel tuo caso per due possibili motivi: l'ambiente distante è probabilmente un ambiente di produzione, e potresti non essere in grado di installare quello che vuoi lì; alcuni profiler stanno prendendo di mira brevi pezzi di codice che eseguono in termini di secondi, piuttosto che decine di minuti.

Quello che puoi fare, d'altra parte, è:

  • Isolare completamente il codice parser in un'app Java autonoma. Ciò garantirebbe di non aver perso alcune chiamate di fantasia in un servizio Web nascosto in un loop.

  • Aggiungi istruzioni di debug / benchmarking che semplicemente scriveranno l'ora corrente in un file di registro. Quando in realtà profiling codice, questa non è una buona pratica, dal momento che non ti dà abbastanza precisione (nella profilazione effettiva, i microsecondi spesso contano). Tuttavia, quando stiamo parlando di 40 minuti di esecuzione, questo dovrebbe essere abbastanza preciso.

  • Trova la parte che richiede più tempo (fai attenzione, un metodo che impiega 50 secondi ed è eseguito una volta è molto meno importante di un metodo che impiega 5 secondi ed è eseguito 100 volte in un ciclo) . Da lì, potrebbe essere necessario, in modo iterativo, aggiungere altre istruzioni di debug / benchmarking nel blocco lento per ottenere la riga effettiva in cui il codice è bloccato per 38 minuti.

Un approccio leggermente diverso consiste nell'utilizzare la registrazione programmazione orientata all'aspetto (AOP) . Ecco un buon inizio . L'idea è che invece di mettere manualmente le istruzioni di debug / benchmarking che scriveranno l'ora corrente nel file di log, semplicemente decorerai i metodi che vuoi misurare e lascerai che la libreria AOP svolga il lavoro effettivo.

Un effetto collaterale positivo è che ti incoraggerebbe a rifattorizzare il tuo blocco di codice do/while . Guardando il tuo codice, non sono sicuro che il tuo metodo stia effettivamente facendo una e una sola cosa.

    
risposta data 26.08.2016 - 09:14
fonte
0

Il problema è probabilmente basato sulla memoria per l'analisi. Vorrei fare abbastanza domande su entrambi gli ambienti per replicarli con nuove VM e vedere se potrei trovare una differenza simile tra queste VM.

Una volta che hai VM simili, puoi ripetere i test con specifiche leggermente diverse per capire se il problema si aggrava di più per memoria, potenza di elaborazione o cosa. A quel punto avresti un'idea su dove focalizzare la tua energia durante l'ottimizzazione.

    
risposta data 26.08.2016 - 18:18
fonte

Leggi altre domande sui tag