PDA

View Full Version : [c#] consiglio di progettazione


file001
23-11-2018, 11:09
Ciao a tutti,

nel tempo libero mi metto a scrivere un pò di codice solo che mi è venuto un gran dubbio.

ho un file testo in cui ci sono circa 10mila righe. Il mio obiettivo è quello di leggere questo file testo e di metterlo in una listbox.

Come metodo risolutivo avevo pensato di leggere il file, creare l'oggetto per ogni riga e infine inserire tutti questi oggetti in una listbox.
Però, all'università mi stanno facendo una testa così grande per quanto riguarda l'ottimizzazione delle risorse che ho messo in dubbio questa soluzione.

prima di scrivere l'altro modo vi spiego semplicemente come è fatto la riga di questo file testo:
STRINGA, e interi (20 circa)
le righe sono di lunghezza fissa

Come seconda soluzione, avrei pensato di leggere solo le stringhe e di metterle nella listbox, poi quando clicco su quel determinato elemento della listbox, leggo la riga corrispondente nel file e mi creo l'oggetto solo per quella riga (dato che le righe sono di lunghezza fissa è un gioco da ragazzi)
E' meglio il primo o il secondo metodo? Perché allocare 10mila oggetti in memoria mi sembra eccessivo. Invece, nella seconda soluzione ci sono molte operazioni idi I/O.

pabloski
23-11-2018, 11:48
Perché allocare 10mila oggetti in memoria mi sembra eccessivo. Invece, nella seconda soluzione ci sono molte operazioni idi I/O.

Bingo. Hai centrato una questioni centrali dell'informatica, ovvero quella dei trade-off. Cioe' non c'e' trippa gratis per i gatti.

Se guadagni da un lato, lo paghi dall'altro. Il compromesso giusto e' quello migliore per la tua applicazione.

In pratica ti dico di leggere tutto. 10.000 righe fatte in quel modo sono una bazzecola anche per uno smartphone.

Ma volendo ottimizzare il tutto, la tua soluzione e' ovviamente possibile e in molti casi molto adatta.

Qualche anno fa mi sono ritrovato a scrivere un'applicazione che deve visualizzare vari dati relativi a persone, contratti, ecc... Le listbox erano popolate esclusivamente dei dati necessari ad identificare in maniera univoca i vari elementi. Cliccandoci sopra venivano visualizzati a lato tutti gli altri dati relativi.

Pero', perche' c'e' un pero', se WPF non avesse una grossa lacuna sarebbe meglio. Parlo della data virtualization. Cioe' tu hai una lista con 1 milione ( numero a caso ) di righe virtuali. In realta', man mano che l'utente scorre la lista, le righe necessarie vengono lette e messe in una cache. In questo modo non devi caricare tutte le righe fin dall'inizio e non le devi nemmeno mantenere tutte in memoria costantemente.

Purtroppo WPF non ha implementa un meccanismo del genere. Ci sono componenti di terze parti che lo fanno. Una grossa mancanza vista l'utilita' e il fatto che i concorrenti ( Java ma anche i vari web framework come Angular ) la implementano.

DoctorT
23-11-2018, 12:56
Ciao a tutti,

nel tempo libero mi metto a scrivere un pò di codice solo che mi è venuto un gran dubbio.

ho un file testo in cui ci sono circa 10mila righe. Il mio obiettivo è quello di leggere questo file testo e di metterlo in una listbox.

Come metodo risolutivo avevo pensato di leggere il file, creare l'oggetto per ogni riga e infine inserire tutti questi oggetti in una listbox.
Però, all'università mi stanno facendo una testa così grande per quanto riguarda l'ottimizzazione delle risorse che ho messo in dubbio questa soluzione.

prima di scrivere l'altro modo vi spiego semplicemente come è fatto la riga di questo file testo:
STRINGA, e interi (20 circa)
le righe sono di lunghezza fissa

Come seconda soluzione, avrei pensato di leggere solo le stringhe e di metterle nella listbox, poi quando clicco su quel determinato elemento della listbox, leggo la riga corrispondente nel file e mi creo l'oggetto solo per quella riga (dato che le righe sono di lunghezza fissa è un gioco da ragazzi)
E' meglio il primo o il secondo metodo? Perché allocare 10mila oggetti in memoria mi sembra eccessivo. Invece, nella seconda soluzione ci sono molte operazioni idi I/O.

Leggere la riga corrispondente in file di testo a lettura sequenziale non è possibile, dovresti aprirlo come un file di record a lunghezza fissa, anche se non conosco gli oggetti disponibili in c# per fare questa operazione, ma potrebbe essere una complicazione non necessaria.

Dal punto di vista pratico puoi ovviamente caricare tutto in memoria, (tra l'altro quando leggi le stringhe carichi già l'intero file in memoria per cui non ti servono altre operazioni di I/O) ma visto che si tratta di un esercitazione a scopo di studio credo che ti debba sforzare di trovare una soluzione che funzioni indipendentemente dalla dimensione dei dati da gestire.

_angelo_
22-12-2018, 13:46
Non sono esperto su c#, anche perche lavoro in ambito linux/opensource, ma nei vari linguaggi interpretati tipo anche lua e python etc e' pieno di funzioni "readline" che leggono l'intera riga, linux shell bash inclusa.
Alla fine devi leggere da file riga per riga e popolare una lista, non servono specializzazioni accademiche, ci sono oggetti lista molto performanti, a me piace anche tcl/tk. Se no vai su programmazione vera e propria compilata e usi librerie grafiche di ogni genere, dalle windows api, a gtk, wxwidgets, e molte altre.
Nel caso, per file molto grandi (ma 10000 righe non e' molto grande), vedi anche "memory mapped file" che ti dovrebbero dare una performance migliore.

pseudo code
for (i = 0; i < 10000; ++i) {
read_line(buff);
list->add_item(buff);
}
list->refresh()