2015-08-10 19 views
5

Se qualcuno mi può aiutare, sono completamente fuori dalle idee.Problema di prestazioni della mappa

così ho questo codice (si tratta di una versione molto semplificata del mio codice):

while(readNewFile()) 
{ 
    while(getNewStructFromFile()) 
    { 
     unsigned long starttime = GetTickCount(); 
     customerData.fillFromBinaryData(structPointer); 
     cout<< GetTickCount() - starttime; 

     aMap.insert(pair<int,string>(customerData.phoneNumber,"")); 
    } 

    // Ouptut all data 

    aMap.clear(); 
} 

In sostanza, si legge solo i record da un file binario. customerData ottiene i dati e riempie le sue variabili con i dati da esso. Quindi, inserisce il numero di telefono in una mappa (per il debug sto solo inserendo una stringa int e una stringa vuota).

Il problema è che dopo un po 'questo programma diventa molto lento; se commento la mappa, il programma viene eseguito correttamente senza problemi con un tempo di esecuzione costante per file. Se utilizzo l'inserimento della mappa, dopo alcuni file, il programma torna molto lentamente (da 8 a 10 secondi a 1 minuto o più). Ma eseguendo il debug con GetTickCount(), mi viene mostrato che il ritardo si verifica in customerData.fillFromBinaryData (al primo 0 ms, quindi salta a 30-40 ms (per compilare le variabili di classe)). Ma se commento questa semplice inserzione della mappa, non c'è alcun ritardo nel riempire l'oggetto con i dati! Dov'è la logica in questo? Qualcuno potrebbe darmi un suggerimento, sono fuori di idee. Scusa se questa domanda non è veramente buona.

Ho provato diversi tipi di mappe, ma ancora una volta, mi mostra che il ritardo non è nell'inserimento della mappa.

Modifica/Possibile soluzione:

Nel caso in cui qualcuno ha problemi simili, ho installato VS2015, e il ritardo utilizzando le mappe è andato! Non sono sicuro di come sia correlato, ma Hurra!

+2

Si stanno stampando tutti i dati in ogni ciclo? I dati aumentano di volta in volta .... – Aleksandar

+1

Semplicemente non posso essere l'unica persona stranamente curiosa del fatto che questa domanda sia contrassegnata come 'asn.1', considerando che non vi è assolutamente alcuna menzione di ciò nel corpo della domanda. – WhozCraig

+0

I output una volta per file, e ho cancellato la mappa dopo questo, perché dovrebbe farlo diventare più grande? customerData è solo un record del cliente, ogni volta che ottiene un nuovo valore. In realtà sto leggendo da un file ASN :) Non sono sicuro del motivo per cui ho aggiunto il tag ... – Silencer

risposta

1

Potrebbe succedere che se una mappa diventa molto grande, si ha un problema con la gestione della memoria e fillFromBinaryData richiede un po 'di allocazione di memoria che ora è più lenta. A causa di una frammentazione della memoria, forse?

Vorrei suggerire di provare alcune librerie per questo scopo specifico. Tuttavia, ho dimenticato come vengono chiamati. So solo che ce n'è uno disponibile da Google, "jemalloc" o qualcosa di simile.

Il punto principale di un pool di memoria personalizzato è che è possibile allocare la memoria una volta come un grande gruppo e utilizzarla solo in un ambito della propria app con allocatori personalizzati.

Un'altra cosa è forse quella di smettere di usare una mappa e usare invece la mappa non ordinata. Modifica la complessità temporale per l'inserimento da O (logn) a O (1) con una funzione di hash perfetta, poiché per te è un numero di telefono.

  • Si chiama jemalloc e non è di Google. :)
+0

Bene il i primi file la mappa va bene, come può essere spiegato? Chiamo clear() dopo ogni file, quindi la mappa dovrebbe ricominciare da 0, non è come sta ancora crescendo? E uso la mappa non ordinata e riserva 4000 elementi, un il file ha circa 3500 record. – Silencer

+2

Quindi potrebbe essere un problema di frammentazione. Controlla cosa fa jemalloc. Altrimenti non so quale potrebbe essere. Suggerirei quindi di eseguire la tua app con valgrind --tool = callgrind o qualcosa di simile. – AlexTheo

Problemi correlati