|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#21 |
|
Senior Member
Iscritto dal: Sep 2001
Città: de_legato
Messaggi: 792
|
premetto, penso sia un'opzione particolarmente utile ...avere la possibilità di creare un contenitore di oggetti "limitato" nell'utilizzo della memoria permette al programmatore di capire quanti oggetti di un certo tipo può istanziare prima che il sistema vada in crisi di memoria centrale
__________________
---------------------------------------------- File reality.sys corrupted, Reboot Universe? Y/N ---------------------------------------------- |
|
|
|
|
|
#22 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Potresti usare un anello. Una cosa tipo:
Codice:
public class Ring<T extends Serializable> {
public T push(T value)...
public T extract()..
}
Se l'anello è pieno, push restituisce il record rimosso per far posto a value. Se intendi scartare le richieste più vecchie crei un anello LIFO. Altrimenti un FIFO. A naso, non dovrebbe essere complicato.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
|
|
|
|
|
#23 |
|
Senior Member
Iscritto dal: Sep 2001
Città: de_legato
Messaggi: 792
|
si maaaahhh ....un momento!! ...mi stai consigliando di serializzare/deserializzare per l'implementazione?
Questo che voglio fare è rivolto sopratutto al lato prestazione, cioè il non dover scrivere ogni volta sul db la request del client: se mi consigli di serializzare/deserializzare su buffer mi sa che allora mi conviene direttamente scrivere sul db.... poi non so, magari dalla java 6 la serializzazione è diventata iperveloce....
__________________
---------------------------------------------- File reality.sys corrupted, Reboot Universe? Y/N ---------------------------------------------- |
|
|
|
|
|
#24 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Devi fare un test per verificare se una soluzione è compatibile con gli obiettivi di performance dell'applicazione che stai sviluppando.
Io ho fatto una prova con questa classe: Codice:
package serialtest;
import java.io.*;
public class Query implements Serializable {
private static final long serialVersionUID = 0;
private String path;
private long timestamp;
public Query(String path, long timestamp) {
this.path = path;
this.timestamp = timestamp;
}
public String getPath() {
return path;
}
public long getTimestamp() {
return timestamp;
}
private void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
}
private void readObject(ObjectInputStream in) throws IOException {
try {
in.defaultReadObject();
} catch(ClassNotFoundException ex) {
throw new IOException("Class not found...");
}
}
}
A questo punto uno deve valutare se 0.013 millisecondi per scrivere e leggere una query con il meccanismo della serializzazione standard siano eccessivi rispetto ad un'altra opzione. Nota che qui la questione non è se la serializzazione sia o non sia rapida. Anche se impiegasse l'ora e un quarto a cui generalmente si pensa, quest'ora e un quarto andrebbe valutata nel contesto dei requisiti del programma.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
|
|
|
|
|
#25 |
|
Senior Member
Iscritto dal: Sep 2001
Città: de_legato
Messaggi: 792
|
i requisti del programma, di solito, sono la massima velocità di esecuzione della query ...nel mio caso essendo il webserver volto a soddisfare le richieste dei client non vorrei, essendoci in mezzo questo salvataggio della richiesta, un eccessivo overhead prima che si passi alla fase di risposta alla GET/POST ....considerando che siamo in un contesto di un webserver che deve gestire parecchi client contemporanemente potrei vedermi crollare le prestazioni proprio per questo eccessivo (forse quasi oserei dire, pedante) salvataggio di tutte le richieste perventure al server.....
Dal tuo codice però non capisco una cosa, la defaultReadObject() legge l'oggetto dallo stream passato come argomento, ma perchè il metodo non ritorna l'oggetto appena deserializzato? ps: ma i 0.013s li hai messi a caso? ...perchè considerando le 77000 istanze al secondo e ponendo il tempo di deserializzazione equivalente a quello di serializzazione abbiamo 1s/(77000/2) che è mooolto più basso di 13ms....
__________________
---------------------------------------------- File reality.sys corrupted, Reboot Universe? Y/N ---------------------------------------------- Ultima modifica di Frank1962 : 12-05-2007 alle 10:07. |
|
|
|
|
|
#26 | ||
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Quote:
Invece è ambiguo quando scrivo Quote:
Per questo ho detto 0.013 e non 0.026. Il meccanismo tramite cui è realizzata la (de)serializzazione standard non restituisce l'oggetto deserializzato ma, in un certo senso, "riempie un'istanza vuota". Tale istanza è poi usata come valore restituito dal metodo readObject() di ObjectInput.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
||
|
|
|
|
|
#27 |
|
Senior Member
Iscritto dal: Sep 2001
Città: de_legato
Messaggi: 792
|
opss ...una piccola svista
in effetti, però, non sapevo che un elaboratore avesse una precisione dell'ordine del milionesimo di secondo! Interessante la possibilità di serializzare/deserializzare un oggetto in quel modo ...ma l'ObjectInputStream e l'ObjectOutputStream fanno le veci del "database" in memoria? ..cioè se vado a serializzare più oggetti dello stesso tipo in quegli stream il distinguo nell'andarli a deserializzare viene eseguito automaticamente? a prima vista da come hai scritto il codice sembrerebbe proprio di si
__________________
---------------------------------------------- File reality.sys corrupted, Reboot Universe? Y/N ---------------------------------------------- Ultima modifica di Frank1962 : 12-05-2007 alle 12:57. |
|
|
|
|
|
#28 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Non so se il comune hardware offra una precisione al milionesimo di secondo. So che il timer che Java usa per nanoTime() ha una granularità massima di 1 millisecondo. Io ho fatto un test su 50000 serializzazioni e ho diviso il tempo totale per il numero di istanza serializzate, ottenendo il valore medio che ho indicato.
Quanto alla distinzione automatica se intendo correttamente il dubbio la risposta è sì. Cioè se scrivo 3 oggetti distinti posso poi leggere distintamente questi stessi 3 oggetti.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
|
|
|
|
|
#29 | |
|
Senior Member
Iscritto dal: Sep 2001
Città: de_legato
Messaggi: 792
|
Quote:
oltretutto, come mai i metodi write/readObject della classe Query sono private?
__________________
---------------------------------------------- File reality.sys corrupted, Reboot Universe? Y/N ---------------------------------------------- |
|
|
|
|
|
|
#30 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Mhhh...
Hai presente quando scrivi un testo su un file? Ecco, se vuoi avere indietro quel testo devi leggere lo stesso file. Se il testo è "pippo" e sul file scrivo prima la p, poi la i, poi la p eccetera, per leggerlo io devo leggere prima la p, poi la i, poi la p eccetera. Questo è il collegamento che deve sussistere anche tra ObjectOutput e ObjectInput. Quanto all'output-input che si collega al byte array... la metti giù un po' troppo complicata. Tu serializzi l'oggetto in memoria e lo deserializzi leggendo dei byte dalla regione di memoria in cui li hai scritti. I metodi readObject e writeObject sono private perchè chi ha progettato il meccanismo della serializzazione standard ha voluto esprimere il vincolo "non invocate direttamente questi metodi, grazie".
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
|
|
|
|
|
#31 | |
|
Senior Member
Iscritto dal: Sep 2001
Città: de_legato
Messaggi: 792
|
Quote:
Con la modalità fifo sono invece obbligato a leggermi tutti gli oggetti serializzati prima di ottenere quello voluto! Codice:
Query q1 = new Query("ciao",1234567890);
Query q2 = new Query("hello",1234567890);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(q1);
oos.writeObject(q2);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
q1 = (Query)ois.readObject();
q2 = (Query)ois.readObject();
System.out.println(q2.getPath());
} catch (Exception e) {
e.printStackTrace();
}
a me piacerebbe invece fare un'utopia simile ( Codice:
Query q1 = new Query("ciao",1234567890);
Query q2 = new Query("hello",1234567890);
DatabaseInMemoriaCentraleConUnNomeTroppoLungo dbmem = new DatabaseInMemoriaCentraleConUnNomeTroppoLungo(10YottaByte);
q1.miserializzo(dbmem);
q2.miserializzo(dbmem);
Query q1= q1.mideserializzo(dbmem);
System.out.println(q1.stampalostampabile());
__________________
---------------------------------------------- File reality.sys corrupted, Reboot Universe? Y/N ---------------------------------------------- Ultima modifica di Frank1962 : 12-05-2007 alle 14:28. |
|
|
|
|
|
|
#32 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Se devi creare un buffer per un servizio che evade delle richieste avrai una politica di ordinamento delle evasioni che si riflette nell'accodamento delle richieste. Se la politica di evasione richiede un accesso casuale, tu crei un buffer ad accesso casuale. Se è richiesto un accesso lifo, crei un buffer lifo. Se è richiesto un accesso fifo, crei un buffer fifo.
Se il server evade le richieste un po' come gli gira e un po' come tira il vento allora non è più un problema di programmazione. Può essere poesia o pittura o una qualsiasi altra nobilissima e affascinante attività creativa dell'uomo. Ma non è programmazione. La serializzazione si occupa di trasformare un oggetto in un pacchetto di byte e la deserializzazione di trasformare un pacchetto di byte in un oggetto. Le specifiche del programma che devi creare le conosci tu e tu devi decidere se la serializzazione sia o non sia idonea a rappresentare la soluzione ad uno dei problemi che hai già risolto. E' possibile che io mi sbagli, perchè si tratta pur sempre di una conversazione astratta su questioni delineate a botta e risposta su un forum, ma ho l'impressione che tu abbia il problema ma non la sua soluzione. La programmazione è l'attività di rappresentazione della soluzione ad un problema. Non è un tecnica di soluzione di problemi. Devi già sapere quello che devi fare. Poi prendi gli strumenti offerti dalla piattaforma di programmazione che hai scelto e li usi per rappresentare, per tradurre quello che già sai di dover fare. Io ti parlo di serializzazione perchè la soluzione che ho trovato al problema che hai proposto è rappresentabile con questo strumento. Pensavo che la mia soluzione coincidesse con la tua ma ora mi viene il dubbio che, nel nostro dialogo, la mia soluzione sia anche l'unica in ballo
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
|
|
|
|
|
#33 |
|
Senior Member
Iscritto dal: Sep 2001
Città: de_legato
Messaggi: 792
|
ammetto che forse la strada al "contratto" che la discussione originariamente voleva condurci si è andata un pò a perdere
Se la serializzazione in un bytearrayoutputstream mi permette di far ciò: ben venga! Il problema è che non vorrei che questa soluzione mi portasse fuoristrada sotto due aspetti: lato prestazione e lato "usabilità" di quello che voglio creare. Se dal lato prestazioni abbiamo visto che ciò conviene dal lato usabilità rimango con qualche perplessità; ovvero: se voglio recupare l'oggetto di indice i dalla sfilza di oggetti che inserisco nel mio dbase come cavolaccio faccio se non applico qualche paradigma in chiave poetica/pittorica di influenza ermetista ....o per meglio intenderci ( Il dubbio/perplessità/confusione veniva dal fatto che pensavo la serializzazione avese bultin la possibilità di fare il distinguo (tramite un suo protocollo) degli oggetti serializzati all'interno di un'area di memoria (in questo caso il nostro bytearrayoutputstream).
__________________
---------------------------------------------- File reality.sys corrupted, Reboot Universe? Y/N ---------------------------------------------- |
|
|
|
|
|
#34 |
|
Senior Member
Iscritto dal: Sep 2001
Città: de_legato
Messaggi: 792
|
ecco una prima implementazione ....a voi il giudizio!! (sopratutto per pgi, essendo ormai nato un "contenzioso" tra un nobilissimo programmatore java (pgi) e un lurker con un attacco mistico di posting (frank)
Codice:
import java.io.*;
import java.util.HashMap;
public class ObjectDBase {
private int mode = 0;
private int total = 0;
private int maxsize = 0;
private Queue q = new Queue();
private HashMap<Integer,Object> hm = null;
private ByteArrayOutputStream baos = null;
private ObjectOutputStream oos = null;
ObjectDBase(int maxsize, int mode) {
this.mode = mode;
this.maxsize = maxsize;
hm = new HashMap<Integer,Object>();
try {
baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(baos);
} catch (IOException e) {
e.printStackTrace();
}
}
public void addObject(int key, Object o) throws Exception {
baos.reset();
oos.reset();
oos.writeObject(o);
byte[] aux = baos.toByteArray();
if(!(total+aux.length>maxsize)) {
insertObject(key, aux);
} else {
if(mode==0 || aux.length>maxsize) {
throw new Exception("spazio insufficente");
} else {
while(total+aux.length>maxsize) {
Integer inx = (Integer)q.deQueue();
byte[] a = (byte[])hm.get(inx.intValue());
total -= a.length;
hm.remove(inx);
}
insertObject(key, aux);
}
}
}
private void insertObject(int key, byte[] array) {
hm.put(key, array);
q.enQueue(key);
total += array.length;
System.out.println(total);
}
public Object getObject(int key) {
byte[] aux = (byte[])hm.get(key);
ByteArrayInputStream bais = new ByteArrayInputStream(aux);
try {
ObjectInputStream ois = new ObjectInputStream(bais);
return ois.readObject();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
Codice:
public static void main(String... args) {
try {
int i = 0;
while(true) {
i++;
odb.addObject(i, buildmap());
}
} catch (Exception e1) {
e1.printStackTrace();
}
public Map buildmap() {
HashMap map = new HashMap();
int i = 0;
while(i<(int)100.0*Math.random()) {
map.put(i, Math.random());
i++;
}
return map;
}
}
Mi sorge un problema sul fatto della compressione dei dati ...ho provato a utilizzare il normale deflater fornito dalle librerie java ma ho notato che la dimensione dei dati compressi molte volte tende a superare la dimensione dei dati originali (per piccole quantità di dati, dell'ordine di una stringa di 200/300 caratteri) quindi mi chiedo se ci può essere qualche alternativa che non vadi a salvare ogni volta il dizionario nei dati di compressione.
__________________
---------------------------------------------- File reality.sys corrupted, Reboot Universe? Y/N ---------------------------------------------- Ultima modifica di Frank1962 : 13-05-2007 alle 10:45. |
|
|
|
|
|
#35 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Ma che nobiltà, eleganza e via sproloquiando. I fatti, contano i fatti! Carta canta!
A vederlo direi che funzioni. La mappa puoi dichiararla come <Integer, byte[]>, a meno che i valori non debbano effettivamente essere Object o figli. Mi sfugge la ragione per cui devi avere una mappa ma tra noi due sei senz'altro tu a sapere come dev'essere fatto 'sto programma.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
|
|
|
|
|
#36 | |
|
Senior Member
Iscritto dal: Sep 2001
Città: de_legato
Messaggi: 792
|
Quote:
Sul discorso "compressione" non mi dici nulla?
__________________
---------------------------------------------- File reality.sys corrupted, Reboot Universe? Y/N ---------------------------------------------- |
|
|
|
|
|
|
#37 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Mi intendo di compressione come di scissione dell'atomo. So che le librerie standard fornisco compressori/decompressori zlib, zip o gzip e qui mi fermo.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
|
|
|
|
|
#38 | ||
|
Senior Member
Iscritto dal: Sep 2001
Città: de_legato
Messaggi: 792
|
Quote:
cmq come da documentazione java della classe deflater: Quote:
__________________
---------------------------------------------- File reality.sys corrupted, Reboot Universe? Y/N ---------------------------------------------- Ultima modifica di Frank1962 : 13-05-2007 alle 14:39. |
||
|
|
|
|
|
#39 | |
|
Senior Member
Iscritto dal: Sep 2001
Città: de_legato
Messaggi: 792
|
cmq togliendo il problema della compressione che, da post su forum.java.sun.com (trovato dopo un casino di tempo, dato che google sembri disprezzare tale forum) il problema sembra di rapida soluzione, volevo domandarti che cosa non ti è chiaro della mia classe dopo che ho postato il codice, dalle tue parole infatti:
Quote:
Cioè, la necessità di avere un "contenitore" di oggetti limitato superiormente penso non sia cosa di poco conto come soluzione di parecchie problematiche tra i programmatori java...... o sbaglio?
__________________
---------------------------------------------- File reality.sys corrupted, Reboot Universe? Y/N ---------------------------------------------- |
|
|
|
|
|
|
#40 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Come no. Figurati che se non devo fare un contenitore di oggetti limitato superiormente io la mattina neanche mi alzo.
Tu devi fare quello che pensia sia corretto per il tuo programma. A me sembra strano che ti serva una mappa perchè, probabilmente, mi sono fatto un'idea del programma che è diversa da quello reale. Il programma che mi sono immaginato è questo. C'è un server che mastica richieste. Le richieste provengono da un numero non determinato di client. Il server ha una limitata capacità di evasione delle richieste. Tra il server e i client infili un buffer tampone. Il buffer accumula le richieste provenienti dai client e il server le consuma in ordine di arrivo. Il buffer ha una dimensione prefissata. Quando il buffer si riempie, possono succedere tre cose (sempre nella mia idea del programma) 1. il buffer rifiuta le nuove richieste 2. il buffer rimpiazza la richiesta più vecchia con la richiesta più recente 3. il buffer mette i client in attesa E qui la mappa non ci sta. La mappa permette di prelevare una richiesta in particolare. Non serve per prelevare la richiesta più vecchia o la più recente, perchè questo compito lo assolve già la coda del buffer. La mappa offre un criterio di "scelta" diverso. Qual'è questo criterio? Perchè il server dovrebbe prelevare (presumo per evadere) una richiesta senza rispettare l'ordine di arrivo? Forse alcune richieste sono prioritarie? Ma in questo caso la priorità dovrebbe essere gestita nell'accodamento delle richieste. Ecco, sono perplessità di questo tipo che mi fanno apparire strana quella mappa. Ma questo non vuol dire che sia stramba. Insomma, se l'hai messa una ragione ci sarà. Io mi fido.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 10:18.




















