Domanda

Come ho ciclo attraverso le linee in file A, sto l'analisi della riga e mettendo ogni stringa (char*) in un char**.

Alla fine di una riga, ho quindi eseguire una procedura che consiste di apertura del file B, utilizzando fgets, fseek e fgetc per afferrare personaggi di quel file. Ho quindi chiudere il file B.

Lo ripeto riapertura e richiusura del file B per ogni linea.

Quello che vorrei sapere è:

  1. C'è un significativo calo di prestazioni di utilizzare malloc e free, in modo tale che dovrei usare qualcosa di statico come myArray[NUM_STRINGS][MAX_STRING_WIDTH] invece di un char** myArray dinamica?

  2. C'è un overhead significativo delle prestazioni da apertura e chiusura di file B (concettualmente, molte migliaia di volte)? Se il mio file A è ordinato, c'è un modo per me di utilizzare fseek a muoversi "a ritroso" nel file B, per ripristinare in cui ero in precedenza trova nel file di B?

modifica Risulta che un approccio duplice notevolmente ridotto il tempo di esecuzione:

  1. Il mio file B è in realtà uno dei ventiquattro file. Invece di aprire lo stesso file B1 mille volte, e poi B2 mille volte, ecc apro file di B1 volta, chiuderlo, B2 una volta, chiuderlo, ecc Questo riduce molte migliaia di operazioni fopen e fclose a circa 24.

  2. Ho usato rewind() per ripristinare il puntatore del file.

Questo ha prodotto un miglioramento della velocità circa 60 volte, che è più che sufficiente. Grazie per avermi a rewind().

È stato utile?

Soluzione

Se la matrice dinamica si sviluppa nel tempo, c'è un costo copia su alcuni reallocs. Se si utilizza l'euristica "sempre doppio", questo viene ammortizzato a O (n), quindi non è orribile. Se si conosce l'anticipo dimensione del tempo, una pila di allineamenti allocato sarà ancora più veloce.

Per la seconda domanda leggere su rewind. Essa ha avuto modo di essere più veloce di apertura e chiusura per tutto il tempo, e permette di fare a meno della gestione delle risorse.

Altri suggerimenti

Quello che vorrei sapere è:

  • fa il tuo lavoro codice correttamente?
  • è in esecuzione abbastanza veloce per il vostro scopo?

Se la risposta sia di questi è "sì", non cambia nulla.

Apertura e chiusura ha un overhead variabile a seconda se altri programmi sono competitng per quella risorsa.

misurare la dimensione del file prima e quindi utilizzare tale per calcolare la dimensione della matrice in anticipo per fare una grande allocazione heap.

Non sarà possibile ottenere un array multi-dimensionale destra fuori, ma un po 'di aritmetica dei puntatori e siete arrivati.

Si può non memorizzare nella cache le informazioni di posizione in un altro file e quindi, invece di apertura e chiusura, utilizzare precedente cercare gli indici come un offset? Dipende dalla logica precisa davvero.

  1. Se i file sono di grandi dimensioni, disco I / O sarà molto più costoso di gestione della memoria. Preoccuparsi malloc / prestazioni senza prima profiling indica che si tratta di un collo di bottiglia è l'ottimizzazione prematura.

  2. E 'possibile che il sovraccarico di frequente apertura / chiusura è significativo nel vostro programma, ma ancora una volta l'attuale I / O è probabile che sia più costoso, a meno che i file sono di piccole dimensioni, nel qual caso la perdita di buffer tra il chiudere e aprire potenzialmente può causare ulteriore disco I / O. E sì, è possibile utilizzare ftell () per ottenere la posizione corrente in un file poi fseek con SEEK_SET per arrivare a questo.

C'è sempre un calo di prestazioni con l'utilizzo di memoria dinamica. Utilizzando un buffer statico fornirà un aumento di velocità.

C'è anche sarà un calo di prestazioni con la riapertura di un file. È possibile utilizzare fseek (pos, SEEK_SET) per impostare il puntatore del file in qualsiasi posizione nel file o fseek (offset, SEEK_CUR) per fare una mossa relativa.

calo di prestazioni significativo è relativo, e si dovrà determinare che cosa significa per te stesso.

  1. Credo che sia meglio allocare il spazio reale si ha bisogno, e la spese generali non sarà probabilmente significativo. Questo consente di evitare sia sprecare spazio e di stack overflow

  2. Sì. Anche se il IO viene memorizzato nella cache, si sta facendo chiamate di sistema non necessari (Apertura e chiusura). Utilizzare fseek con probabilmente SEEK_CUR o SEEK_SET.

In entrambi i casi, non v'è alcuni calo di prestazioni, ma il significato dipenderà dalla dimensione dei file e del contesto del programma viene eseguito in.

  1. Se realmente conosce il numero massimo di stringhe e larghezza massima, questo sarà molto più veloce (ma si può sprecare un sacco di memoria, se si utilizza meno della "max"). La via di mezzo è quello di fare ciò che molte implementazioni di array dinamici in C ++ fare: ogni volta che avete a realloc myArray, alloc il doppio dello spazio di cui hai bisogno, e solo realloc ancora una volta che hai esaurito lo spazio. Questo ha O (log n) Costo prestazioni.

  2. Questo può essere un grande calo di prestazioni. Vi consiglio vivamente di utilizzare fseek, anche se i dettagli dipenderanno vostro algoritmo.

Spesso trovo il sovraccarico di prestazioni per essere compensato dalla gestione della memoria diretta che viene fornito con malloc e quelli di basso livello gestori C sulla memoria. A meno che queste aree di memoria stanno per rimanere statica e intatto per una quantità di tempo che è in tempo ammortizzato superiore toccando questa memoria, può essere più vantaggioso per attaccare con la matrice statica. Alla fine, tocca a voi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top