Lettura dell'input tutti insieme o nei passaggi?

0

Per molti quiz di programmazione ci viene data una serie di linee di input e dobbiamo elaborare ogni input, fare alcuni calcoli e produrre il risultato.

La mia domanda è qual è il modo migliore per ottimizzare il runtime della soluzione?

  1. Leggi tutto l'input, memorizzalo (in array o qualcosa del genere), calcola il risultato per tutti, infine genera tutto insieme.

o  2. Leggere un input, calcolare il risultato, emettere il risultato e così via per ogni input dato.

UPDATE

Poiché nessuna risposta era specifica, chiederei quale sia l'approccio migliore per problemi come questo :

Quadrant Queries (30 points)

There are N points in the plane. The ith point has coordinates (xi, yi). Perform the following queries:

1) Reflect all points between point i and j both including along the X axis. This query is represented as "X i j"
2) Reflect all points between point i and j both including along the Y axis. This query is represented as "Y i j"
3) Count how many points between point i and j both including lie in each of the 4 quadrants. This query is represented as "C i j"

Input:

The first line contains N, the number of points. N lines follow.
The ith line contains xi and yi separated by a space.
The next line contains Q the number of queries. The next Q lines contain one query each, of one of the above forms.
All indices are 1 indexed.

Output:

Output one line for each query of the type "C i j". The corresponding line contains 4 integers; the number of points having indices in the range [i..j] in the 1st,2nd,3rd and 4th quadrants respectively.

Constraints:

1 <= N <= 100000
1 <= Q <= 1000000

You may assume that no point lies on the X or the Y axis.
All (xi,yi) will fit in a 32-bit signed integer
...

    
posta nischayn22 03.06.2012 - 10:30
fonte

3 risposte

4

Dipende dal problema.

Fintanto che tutti i dati si inseriscono nella RAM fisica disponibile, non vi è alcun motivo per scegliere entrambe le possibilità a fini di prestazioni. Leggere tutto in una volta ha il vantaggio di poter saltare avanti e indietro nei dati senza perdere le prestazioni in I / O e puoi convalidare tutti i tuoi dati prima di iniziare l'elaborazione. Soprattutto con strutture dati complesse (ad es. XML), questo approccio è molto più semplice dell'alternativa.

OTOH, l'elaborazione come si fa ('streaming') renderà l'applicazione più "pipe-friendly", cioè, se la si concatena insieme ad altri comandi tramite pipe UNIX (ad esempio, piping l'output di ls nel programma e da lì fino a grep ), trascorreranno meno tempo ad attendere l'un l'altro e l'utente vedrà subito l'output.

Se il tuo set di dati di input è troppo grande per essere contenuto nella memoria in una volta, non hai molta scelta - se provi a leggerlo tutto in una volta, esaurirai la memoria. Nella migliore delle ipotesi, il sistema inizierà lo scambio, il che significa che è lento; nel peggiore dei casi, il sistema operativo semplicemente rifiuterà di dare alla tua applicazione più memoria, o addirittura di ucciderla per comportamenti anomali.

    
risposta data 03.06.2012 - 14:06
fonte
1

Questa domanda non è realmente risolvibile - o meglio, la risposta è: dipende.

Per un'attività di breve durata , non ha molta importanza. Se l'intera operazione viene eseguita dopo 1 secondo, si potrebbe anche andare con qualcosa che si adatta bene al problema. Se le attività sono ortogonali, cioè non dipendono l'una dall'altra in alcun modo, potrebbe solo leggere input e calcolare direttamente l'output. Tuttavia, è spesso architettonicamente corretto farlo come descritto più avanti in questa risposta.

Per un'attività più lunga , in genere 10+ secondi, è molto importante l'usabilità per mostrare il feedback e anche convalidare l'input tutti prima dell'avvio del calcolo. Nota che l'importanza cresce esponenzialmente con il tempo di esecuzione.

Ho usato alcuni strumenti con due o più fasi. Invece di convalidare anche la sintassi per il secondo stadio, usciva dopo 10 minuti con il messaggio "sintassi della riga di comando non valida" o qualcosa del genere. Cose incredibili.

Leggere le opzioni e inserirle in una corretta struttura dati, convalidarle e quindi lavorare su quei dati ti dà molto gratuitamente. Ti darà un punto di partenza per iniziare a pensare al problema. Ti permetterà di lavorare sui dati senza preoccuparti del parsing e così via. Sarà facile generare messaggi di errore tempestivi (dato che analizzi e convalidi tutto all'inizio).

Anche se si tratta di una cosa one-shot, a mio parere è sicuramente sempre la pena di strutturare il programma in modo corretto.

    
risposta data 03.06.2012 - 11:19
fonte
1

L'elaborazione dei dati frammentari sarà un capello più veloce, ma per un quiz di programmazione in un ambiente accademico, l'ottimizzazione non dovrebbe nemmeno essere sul radar. La maggior parte dei motivi per cui dovresti farlo in questo modo non hanno nulla a che fare con il tempo di esecuzione e tutto ciò che riguarda le buone pratiche:

  • Non è necessario reinventare la ruota di buffering e splitting di input. La maggior parte delle lingue include funzionalità per leggere input alla volta che sono stati debellati e resi ragionevolmente efficienti.
  • Non devi scrivere codice per capire quanto input c'è e gestirlo per salvarlo prima dell'uso.
  • La quantità di input non è limitata dalla memoria disponibile.
  • Ripeti i primi tre elementi per l'output.
  • Il tuo programma diventa più semplice da scrivere e più facile da capire: leggi, elabora, scrivi invece di leggere e salva ripetutamente, elaborare e memorizzare ripetutamente, scrivere più volte.
  • Il tuo programma andrà meglio insieme ad altri programmi quando fa parte di una pipeline (ad esempio generate-input | your-program | process-output ). Se conservi tutto il tuo output fino a quando tutto l'input è stato elaborato, tutto il downstream deve rimanere inattivo fino a quando non inizi a produrre output, e hai effettivamente serializzato il processo (cioè sei diventato un collo di bottiglia).

Non fare nulla di evidentemente dispendioso, ma non lasciare che sia l'ottimizzazione a dettare il tuo design. C'è un posto per questo, ma farlo funzionare velocemente non arriva fino a dopo averlo fatto girare e farlo funzionare correttamente.

    
risposta data 03.06.2012 - 14:05
fonte

Leggi altre domande sui tag