Come creare una matrice grossa ma leggera ???

venerdì 03 aprile 2009 - 20.09

willy_80 Profilo | Senior Member

Ciao a tutti,
Sto facendo un programma in vb2008 e ho bisogno di creare una variabile molto molto grossa, tipo 30000x20000 e in ogni cella devo scriverci un valore di 4 cifre senza virgola, mi sapete consigliare come dichiararla per fare in modo che sia il più leggera possibile???
Grazie

R3GM4ST3R Profilo | Junior Member

Sinceramente non ne capisco l'utilità...
La matrice non si può sostituire con un paio di tabelle di un database con ID incrociati?


Tutti sanno che una cosa è impossibile da realizzare, finché arriva uno sprovveduto che non lo sa e la inventa. (Albert Einstein)

willy_80 Profilo | Senior Member

Ci ho già provato e facendo così quando devo leggere e analizzare i dati il sistema diventa molto lento

luigidibiasi Profilo | Guru

>Ciao a tutti,
Ciao
>Sto facendo un programma in vb2008 e ho bisogno di creare una
>variabile molto molto grossa, tipo 30000x20000 e in ogni cella
>devo scriverci un valore di 4 cifre senza virgola, mi sapete
>consigliare come dichiararla per fare in modo che sia il più
>leggera possibile???

L'idea che seguirei è la questa:

Informazioni ---] Caricamento in memoria ---] Operazioni in memoria

Per fare una cosa del genere la struttura che mi verrebbe da consigliarti è la Dictionary(Of string,integer) oppure una Hashtable (che dovrebbe essere la piu' performante).

Non so quanta memoria hai a disposizione ma una tabella del genere dovrebbe comunque occupare un pò di spazio (però win swappa in automatico e a te non ti tange)

Inoltre sia la dictionary che la hashtable ti permettono di consumare memoria solo per le celle che usi... se su 20000x20000 in realtà ne imposti solo 1500 x 1500 e le altre stanno a zero consumi solo per quelle 1500x1500

Un esempio banale da cui magari puoi scriverti una classe x implementarti la matrice tramite gli hashtable: ( invece di integer puoi usare un tipo di dato piu' piccolo visto che devi mantenere solo 4 cifre in modo da risparmiare memoria)
' La nostra matrice fittizia dim myMem as new Dictionary(of string,integer) // oppure dim myMem as new hashtable Dim x as integer // indice X dim y as integer // indice Y dim valoreCella as integer //valore da inserire in myMem(x,y) // Aggiungi il valore alla cella identificata dai due indici myMem.add(x & "*" & y, ValoreCella) // Accesso al valore dim myVal as integer if myMem.containsKey(x & "*" & y) then myVal = myMem(x & "*" & y) else myVal = -1 ' Oppure un flag che indica che la cella è vuota end if

>Grazie
Spero ti sia stato utile anche se non sò fino a quanta memoria riesci a gestire . Se provi a fare così fammi sapere come và.
Se funziona poi scriviamo pure la classe HashMatrix !

Luigi Di Biasi
http://blogs.dotnethell.it/luigidibiasi/

willy_80 Profilo | Senior Member

Ho fatto una prova col tuo sistema e mi sembra molto buono.
L'unico problema è che mentre tentavo di popolare una matrice per vedere la quantità di memoria disponibile il debugger mi ha dato l'errore "out of memory" alla cella x=1999 y=2950.

willy_80 Profilo | Senior Member

Pensandoci bene mi sa che mi conviene scrivere i dati in un file, così almeno non vado ad intasare la ram.
Per la gestione dei dati da file ho solo 2 piccoli problemini:
1. se ho una matrice unidimensionale es. ( dim Matrice(0 to 20000) as integer ), la popolo e poi la scrivo nel file, esiste un comando che mi consenta di scrivere tutta la matrice sul file con separatore di elenco ? , il contrario lo so gia fare leggendo la riga e buttandola nella matrice usando il comando split.
2.E' possibile leggere una precisa riga in un file es. Leggere la 35esima riga senza leggere tutte le 34 righe precedenti ?

R3GM4ST3R Profilo | Junior Member

Beh io non ho molto capito cosa stai facendo, ma che il database sia lento per fare cose di questo tipo mi sembra un tantino eccessivo...
Facendo query specifche su database di grandi dimensioni con tabelle contenenti anche diversi milioni di righe si ottengono risultati ottimi nell'ordine di 3/4 secondi per recuperare migliaia di righe...(certo che se come database mi usi l'access, ti do ragione, ma non esiste solo quello)
Poi dal tuo ultimo post, leggo che vuoi scrivere una matrice di 20mila righe in un file...mi sembra che non sia troppo efficente...

Solo una curiosità, che tipo di applicazione stai scrivendo?

Quello che voglio dirti, è che non ha senso usare 20mila righe se te ne servono 2mila o meno...
E soprattutto scrivere un file, e parsarlo in un successivo momento per recuperare i valori non è molto efficente, te lo dico per esperienza.
Per lavoro, infatti, devo leggere dei file di 86400 righe per poi mettere i valori letti in un grafico...per leggere e parsare il file ci metti tipo 20 secondi (su un thread separato, con priorità massima), per fare la stessa cosa su un database i tempi si riducono fino ad un terzo, per non dire meno!

Se mi fai capire cosa stai sviluppando, potrò aiutarti meglio, ma mi pare che la strada che stai scegliendo non sia la migliore

Ciao!
Tutti sanno che una cosa è impossibile da realizzare, finché arriva uno sprovveduto che non lo sa e la inventa. (Albert Einstein)

luigidibiasi Profilo | Guru

>Ho fatto una prova col tuo sistema e mi sembra molto buono.
>L'unico problema è che mentre tentavo di popolare una matrice
>per vedere la quantità di memoria disponibile il debugger mi
>ha dato l'errore "out of memory" alla cella x=1999 y=2950.

Bha.. ho dato un occhio all'allegato ... ogni N inserimenti nella hash viene richiamata una funzione che credo si occupi di ridimensionare la memoria (sarà una sorta di defrag?)
Step into: Stepping over non-user code 'System.Collections.Generic.Dictionary<string,int>.Resize'

Effettivamente mantenere in memoria così tanti dati non và.... ( 1999*2950*1024 = 6.000.000.000+ byte..) chissà ... magari indicizzando la matrice e caricando solo la parte che ti interessa invece di tutta in un colpo solo .... però a questo punto stai reimplementando un dbms e quindi ti conviene usarne uno già pronto :)

>Pensandoci bene mi sa che mi conviene scrivere i dati in un file,
>così almeno non vado ad intasare la ram.
>Per la gestione dei dati da file ho solo 2 piccoli problemini:
>1. se ho una matrice unidimensionale es. ( dim Matrice(0 to 20000)
>as integer ), la popolo e poi la scrivo nel file, esiste un comando
>che mi consenta di scrivere tutta la matrice sul file con separatore
>di elenco ? ,
Se cerchi su MSDN le funzioni di gestione dei file fileopen o open troverai da qualche parte come aprire i file in modalità scrittura record...


Luigi Di Biasi
http://blogs.dotnethell.it/luigidibiasi/
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5