2009-06-26 8 views
15

Sto iniziando a migrare un meccanismo di serializzazione personalizzato su Protocol Buffers. Un tipo di dati che verrà utilizzato in modo particolarmente regolare è BigDecimal.Qual è l'approccio migliore per serializzare BigDecimal/BigInteger su ProtocolBuffers

Qualcuno sa di un buon modo di serializzare questo all'interno dei buffer di protocollo? La nostra routine di serializzazione corrente utilizza BigDecimal.toPlainString() per la serializzazione e il nuovo BigDecimal (String) per la deserializzazione. Presumo che esista un modo migliore.

La mia ipotesi è quello di definire un BigDecimal come:

message BDecimal { 
    required int32 scale = 1; 
    required BInteger int_val = 2; 
} 

Ma io non sono troppo sicuro di come definire BigInteger - magari utilizzando il suo metodo toByteArray()?

risposta

10

Sì. È necessario definire BigInteger come BigInteger.toByteArray().

mia ipotesi è che BigDecimal sarebbe:


message BDecimal { 
    required int32 scale = 1; 
    required BInteger int_val = 2; 
} 

mentre BigInteger può essere definita come


message BInteger { 
    required bytes value = 1; 
} 

Il codice per gestire BigInteger sarebbe:


    BInteger write(BigInteger val) { 
    BInteger.Builder builder = BInteger.newBuilder(); 
    ByteString bytes = ByteString.copyFrom(val.toByteArray()); 
    builder.setValue(bytes); 
    return builder.build(); 
    } 

    BigInteger read(BInteger message) { 
    ByteString bytes = message.getValue(); 
    return new BigInteger(bytes.toByteArray()); 
    } 
+2

Come convertire un BigDecimal in un BigInteger e ridimensionarlo? E ritorno ? – stikkos

+1

Inizialmente ero preoccupato che questo approccio all'uso di 'toByteArray' non potesse essere portabile (non può essere deserializzato in modo significativo da lingue diverse da Java - spesso uno dei motivi principali per usare protobuf in primo luogo). Tuttavia, la specifica per ['BigInteger.toByteArray'] (http://docs.oracle.com/javase/6/docs/api/java/math/BigInteger.html#toByteArray()) è abbastanza specifica e facilmente utilizzabile da altri linguaggi (ad esempio [.net BigInteger] (http://msdn.microsoft.com/en-us/library/dd268207 (v = vs.110) .aspx), anche se devi stare attento dato che l'endianità sembra essere diverso). – bacar

1

Perché voi vuoi cambiarlo? Solo perché è possibile o c'è un reale bisogno (come una sessione di profilazione che conferma, che la serializzazione/deserializzazione richiede la maggior parte del tempo).

vorrei usare una stringa, proprio perché è costruito in :)

La proposta di approccio array di byte (What is the best approach for serializing BigDecimal/BigInteger to ProtocolBuffers) sembra che vada bene a me, se rappresentazione di stringa sembra essere un problema.

+2

Suppongo che si tratti di un problema di ottimizzazione della rete piuttosto che di ottimizzazione delle prestazioni. La stringa richiede molta memoria. Integer.MAX_VALUE (2147483647) richiede ad esempio nell'ordine di 24 byte come stringa ma solo 8 byte come array di byte. – notnoop

Problemi correlati