Newsgroup: it.comp.java
Titolo: Hashmap & dintorni

Ciao, chiedo un consiglio sulla struttura dati più veloce da
utilizzare.
eseguo un ciclo sul resultset ed ho due campi concatenati che
costituiscono la mia chiave, tale  chiave può esser presente n volte
nel resulset, ma io devo scriverla una volta sola nel mio file txt; ho
utilizzato un'hashmap per verificare se ho già scritto la mia chiave:
while(rs.next()) {
    word =rs.getString(1)+rs.getString(2);
    if (! Hashmap.containsKey(word)) {
	 Hashmap.put(word,Mioprogressivo);
   }
   else{
	System.out.println("riga già scritta");
  }
}
il resulset può avere 1000000 di record....
c'è una soluzione più veloce?
grazie

 utilizzato un'hashmap per verificare se ho già scritto la mia chiave:
Non so per la velocità, ma hai pensato se sia valido usare un Set
(HashSet,o altro) per memorizzare le chiavi (mi pare dal codice che ti
servano solo quelle, mentre il 'valore' è un semplice contatore). Il Set
per sua struttura memorizza una volta sola ogni chiave, quindi se fai
due put della stessa il contenuto del Set è un solo elemento e se usi un
TreeSet le ottieni anche ordinate.
bye
DKano

Ho utlizzato l'hashset ed i tempi di esecuzione sono identici
ciaooo

 c'è una soluzione più veloce?
Sì, secondo me sbagli approccio:
- considera che una HashMap è di vari ordini di grandezza (dipende dalle 
dimensioni ma puoi verificarlo con un semplice for) più lenta in 
scrittura di un array "semplice";
- i database sono ottimizzati per restituire rapidamente grosse moli di 
dati.
Metti insieme le due cose e vedi che non usi il database (veloce) per 
delegare tutto alla Hash (lenta).
Hai due opzioni:
- gestire il tutto lato database ad es. con delle (join tra) select 
distinct (ipotizzo perché non conosco il tuo db);
- utilizzare lato applicativo una struttura dati più ottimizzata.
Ti sconsiglio fortemente questa seconda opzione in quanto gli algoritmi 
delle collections sono già discretamente ottimizzati e per fare di 
meglio dovresti battere vari record ;)
Per ottenere ciò che ora hai nella variabile "word" dovresti fare una 
query del tipo:
SELECT DISTINCT (string1 + string2) AS word FROM ... ORDER BY
Ovviamente la sintassi varia a seconda del db engine che stai usando, ad 
esempio in MySql diventa:
SELECT DISTINCT CONCAT(string1, string2) AS word FROM ... ORDER BY word
A questo punto scorri il resultset e non fai altro che leggere tutte le 
stringhe "word" memorizzandole in un oggetto adeguato.
Personalmente userei un normale array (decisamente più veloce), visto 
che ne conosci a priori sia la dimensione (dal resultset) che il tipo di 
dato (String).
Spero di esserti stato d'aiuto.

Purtroppo il database Oracle non ha indicizzati i campi che ho nella
where della query, semplice recupero da un unica tabella, e l'order by
su 4.000.000 di record mi sembra lento....
Per queesto delego alla mia classe nel ciclo del resulset
l'elaborazione di quali record scrivere nel file txt

Beppe wrote:

Trovo più produttivo cercare di ottimizzare la query lato oracle,
eventualmente creando un indice se questo risulta essere necessario.
Il lavoro del DB deve essere fatto dal DB, non dal codice applicativo.
Y.

non ho questo potere... ho solo privilegi applicativi, il db non si
tocca, le tabelle non si possono modificare....
sorry

 tocca, le tabelle non si possono modificare....
In ogni caso ti consiglio di fare qualche prova: probabile che anche non 
ottimizzato il db sia comunque più veloce di una hash gestita come nel 
tuo primo esempio.
Anche perché una select distinct ti restituisce un sottoinsieme (di che 
entità percentuale puoi saperlo solo tu) di tutti i record.
Molto dipende da come deve essere utilizzato questo programma: se 
lanciato una tantum (es. il file va creato ogni ora) o se usato 
contemporaneamente da n utenti.
Nel secondo caso devi prepararti un algoritmo ad hoc.

 tocca, le tabelle non si possono modificare....
Chiedi al DBA, eventualmente motivando la tua richiesta con benchmark
fatti su un'istanza Oracle di test.
Mi sembra sacrosanto che i programmatori non possano modificare le
tabelle, gli indici invece si devono creare in base alle esigenze
applicative.
Y.

Ho già testato la query che mi eviterebbe l'hashmap, usando la group
by, ho già tutti i record da poter discriminare ,quelli distinti per
coppia di campi da scrivere nel file txt:
select campo1, campo2
from...
where....
group by campo1, campo2
order by campo1, campo2
però ci mette 4 minuti ad eseguire la query in  Produzione , la
tabella ha 27.000.000 di record ,mentre sul database di sviluppo che
ha solo 4.000.000 record ci mette 32 secondi
cmq il programma sarà un batch notturno che gira ad un orario
schedulato...ed ora va bene così mi hanno detto eh eh
vi ringrazio per le risposte datemi :-D

 ha solo 4.000.000 record ci mette 32 secondi
Tu fai fare la query al db
Poi quando ti diranno "ma è lento, consuma risorse, bla  bla real time
solcaz bidu"
Tu farai presente che forse un indiciuzzo sul db...
bye
DKano