Domanda

E 'la mia prima volta per creare un programma con file di lettura e scrittura coinvolto. A dire il vero mi chiedo qual è la migliore tecnica a fare questo. Perché quando ho confrontato il mio lavoro con il mio compagno di classe, la nostra logica sono molto diversi gli uni dagli altri.

Si vede, la nostra insegnante ci ha chiesto di fare un semplice sistema di lista degli studenti dove gli utenti possono aggiungere, modificare ed Elimina i record. E ci ha tenuto a fare un file per salvare tutti i record in modo da poter accedere la prossima volta che si usa il programma.

La mia soluzione a questo problema è prima che il programma si apre il suo menu, ho letto tutti i record all'interno e salvarlo in una matrice []. In tal modo, ho potuto manipolare tutti i record. Quindi prima che l'utente esce dal programma, ho salvarlo sullo stesso file e sovrascrivere tutti i record su di esso.

La soluzione di mio compagno di classe è come questo. Quando si aggiunge un record, ha accedere al file e aggiungere i dati, quando si modifica un record, ha accedere al file e modificare il record particolare e quando si elimina un record che accedere al file e cancella il record. Quindi, quello che ha fatto è per ogni funzione ha fatto, sta accedendo al file.

Sia del nostro lavoro è, naturalmente, possibile codice. Ma mi chiedo, che è più efficiente ed efficace per l'uso, se abbiamo a che fare con migliaia o milioni di record. O ci sono altre soluzioni migliori di quello che abbiamo fatto. Forse si potrebbe condividere il tuo movimentazione esperienze con noi di file ... Grazie.

È stato utile?

Soluzione

Questo è un classico caso che si incontrano di volta in volta in programmazione:? Faccio a ottimizzare per la velocità o l'utilizzo della memoria

E, come tutte le enigmi, non c'è una risposta "corretta" o la soluzione perfetta. In altre parole, tu e il tuo compagno di classe sono entrambi direttamente nei soluzioni al problema.

Con la soluzione di caricare tutti i record in memoria, è "spendere" la memoria al fine di rendere l'accesso e la modifica di ciascuno di quei dischi più veloci in fase di esecuzione. Memorizzazione tutti i record in un array in memoria occupa spazio, ma perché l'accesso alla memoria è quasi infinitamente più veloce di accesso al disco, il tuo approccio è andare a correre molto più veloce di quanto il tuo compagno di classe di.

Per contro, il tuo compagno di classe conserve RAM in attesa di caricare i dati su richiesta dal disco rigido. Ma che sta andando a costare lei: colpire il disco rigido è un processo terribilmente costoso rispetto al recupero dei dati che è già in memoria, e lei sta per essere bloccato fare questo ogni volta che l'utente apporta una modifica . Pensate a quanto tempo ci vuole per avviare un programma contro il passaggio a uno che è già aperto.

E qui sta il compromesso. Alcune delle cose importanti da porsi qui sono:

  1. È l'insieme di dati (nelle configurazioni comuni avrete a che fare con) troppo grande (o sta per diventare troppo grande) per rientrare completamente nella memoria? Se hai a che fare con il genere piccoli insiemi di dati, i computer oggi hanno abbastanza RAM che è probabilmente vale la pena.

  2. Come veloce hai bisogno per essere in grado di accedere ai dati? L'accesso in tempo reale importanti? Si tratta di un particolare di grandi dimensioni o complesso insieme di dati che avrebbe preso troppo tempo per caricare dal disco rigido su richiesta? Che tipo di prestazioni non tuoi utenti si aspettano?

  3. Che tipo di sistema è l'applicazione di mira? A volte i sistemi embedded e altri casi particolari necessitano il proprio design unico si avvicina. Si potrebbe avere una grande varietà di RAM e quantità molto limitate di stoccaggio fisso, o si potrebbe avere esattamente il contrario. Se stai usando standard moderni hardware del PC, che cosa gli utenti vogliono / necessità / già? Se la maggior parte dei tuoi utenti target utilizzano relativamente "robusto" hardware già, si potrebbe fare diverse scelte progettuali che se si sta puntando di indirizzare una più grande potenziale pubblico-youve sicuramente visto questi compromessi resi espliciti prima attraverso il sistema espresso di un programma requisiti.

  4. Avete bisogno di consentire situazioni particolari? Cose come l'accesso simultaneo da parte di più utenti fanno mantenere tutti i dati in memoria molto più difficile. Come vengono altri utenti saranno in grado di leggere nei dati che memorizzato solo nella memoria su un computer locale? Condividere un file comune (forse anche su un server condiviso) è destinata probabilmente ad essere necessaria qui.

  5. Ci sono alcune parti dei dati a cui si accede più frequentemente di altri? Considerare mantenendo quelle porzioni specifiche sempre nella memoria e pigro-caricamento del resto (che significa, solamente tenta di loro prendere in memoria quando / se sono accessibili all'utente).

E come che i suggerimenti ultimo punto, qualcosa di un approccio equilibrato o combinato è probabilmente quanto di più vicino si arriva ad una soluzione "ideale". È possibile memorizzare il maggior numero di dati in RAM possibile, mentre la scrittura periodicamente eventuali modifiche o modifiche al file sul disco durante lo stato di inattività dell'applicazione. C'è un sacco di tempo in cui il programma di media spende in attesa che l'utente a fare qualcosa, in contrapposizione al contrario. È possibile usufruire di questi cicli di CPU di inattività per scovare le cose in corso a tornare memoria al disco senza incorrere in alcuna penalità velocità notevole. Questo approccio viene utilizzato tutto il tempo nello sviluppo di software, e aiuta a evitare la trappola sottolineato dalla risposta di EClaesson. Se l'applicazione si blocca o in altro modo si chiude improvvisamente, solo una piccola porzione didati rischia di essere perso, perché più di esso è stato già impegnata a disco dietro le quinte.

Postscript: Naturalmente, la risposta di scuro Falcon è corretto che in un'applicazione di produzione, si sarebbe più che probabile che l'uso qualcosa di simile a un database per gestire i dati. Ma dal momento che questo sembra essere per scopi educativi, penso che la comprensione dei compromessi di base dietro ogni approccio è molto più importante.

Altri suggerimenti

In ogni applicazione seria, un programmatore buon sarebbe probabilmente utilizzare una libreria esistente per gestire i dati. La scelta di questo strumento dipende dai requisiti esatti:

  1. Ha bisogno di accedere contemporaneamente da più utenti?
  2. Ha bisogno di essere accessibile da più macchine?

La scelta più comune per l'archiviazione di una notevole quantità di informazioni sarebbe un database basato su SQL, come MySQL, Postgres, Microsoft SQL Server, SQLite, ecc Questi lo più assomigliare la soluzione del vostro compagno di classe più della tua.

La versione (mantenendo tutti i record in memoria) sarà molto probabilmente più veloce. E 'necessario disporre di memoria sufficiente se il conteggio dei record cresce però. La cosa brutta di questo è che un crash del programma o di uscita non corretta vi farà perdi tutti i dati, come non è mai stato salvato in un file.

La versione compagni di classe non sarà così veloce, in formato io non il più veloce si può fare è. Ma richiede meno memoria ed è più sicura in crash come la maggior parte dei dati saranno già nel file.

Questa è una domanda che non si può rispondere senza conoscere i dettagli del sistema sul quale è quello di eseguire, la dimensione del set di dati, e il relativo costo del tempo di sviluppo tempo vs cpu. Se il sistema ha una memoria sufficiente, lavorando su una copia in RAM è probabilmente preferibile. In un piccolo sistema con ram estremamente limitati (oggi trova soprattutto nelle applicazioni embedded) potrebbe essere necessario aggiornare il file su disco. Altre cose a cui pensare sono buffering che il sistema operativo può fare prima di scrittura vera e propria per il disco, cosa succede con coerenza nel file se il programma va in crash, e anche se la scrittura del disco è "costoso" sia perché è davvero lento o ha un numero limitato di cicli di scrittura (alcuni dischi flash).

Se questo fosse un piccolo problema pratico su computer desktop di oggi si potrebbe anche prendere in considerazione il tempo speso sviluppando diverse soluzioni contro il tempo relativamente insignificante che potrebbe prendere per l'esecuzione su piccoli insiemi di dati.

Inoltre, oggi potrebbe essere meglio per risolvere il problema utilizzando un database esistente di quel bravo a gestire le questioni rilevanti, piuttosto che fare il proprio database nel file system.

Modifica di record sul posto è sottile se non di dimensioni fisse sono. È realmente possibile solo con un formato binario e supporto per la marcatura fila come inutilizzato (per esempio, con un indice esterno o con whiteouts). I filesystem non sono atomiche, quindi non si può essere sicuri che quello che hai fatto finisce su disco nella sua interezza.

Questo rende il modo in cui problema più complesso rispetto al resto della vostra applicazione note degli studenti, e meglio delegata ad una banca dati (SQLite e tokyocabinet sono alcune delle più leggero). Se non è possibile utilizzare un database, andare con una semplice implementazione. Avrà meno bug, e non sarà possibile ottenere attaccato quando arriva il momento di sostituirlo con un database. Così, il vostro approccio di leggere l'intero file in suoni di memoria come la scelta migliore.

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