pascaldekloe / colfer

binary serialization format
Creative Commons Zero v1.0 Universal
746 stars 53 forks source link

Big Decimal Support #73

Open danieagle opened 3 years ago

danieagle commented 3 years ago

Hi! Thanks for this excelent serializer!

Please add suport for big.Int and decimal.Big !

My main need is the following golang types (biginteger,native) math/big.Int and (bigdecimal) github.com/ericlagergren/decimal.Big

for others langs I don't care, but I would suggest: java => (biginteger, native) https://docs.oracle.com/javase/10/docs/api/java/math/BigInteger.html (bigdecimal, native) https://docs.oracle.com/javase/10/docs/api/java/math/BigDecimal.html JavaScrip => (biginteger, native) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt (or, biginteger) https://github.com/MikeMcl/decimal.js (bigdecimal) https://github.com/MikeMcl/decimal.js C => (biginteger) https://github.com/libtom/libtommath (bigdecimal) https://github.com/libtom/libtomfloat

Thanks Very Very Very Much!

Best Whishes, Dani.

pascaldekloe commented 3 years ago

Big decimals allocate memory on instantiation, which goes against the spirit of a fast serialization system. The worst part is that almost none of the implementations allow you to specify the backing array.

Big decimals have their use of course. I am simply not sure what to do here.

danieagle commented 3 years ago

Hi! and thanks!

Big decimals colfer encoding is just a length and a []byte in golang.

To get the binary from decimal.Big to []byte there is a high performance: Big.MarshalText and the reverse op []byte to decimal.Big there is a high performance: Big.UnmarshalText

I'll try mirror the code used in "colf_binary" type for bigdecimal.

in this time I'll create a branch 'bigdecimal" in the my forks area.

ps.1: I Liked very very very much the code you made, it is a pleasant surprise to see a practical use of go / {ast, parser, etc.} ps.2: what types of bigdecimal do you prefer for C, Java, Javascript?

[]'s Gratitude, Dani.

pascaldekloe commented 3 years ago

Thanks Dany. It is nice to hear you like you like the code. 😊

MarshalText allocates a new byte array. That's a big no-go in terms of performance.

The generated code does not have any dependencies as a rule. That means we must either use whatever is in the core library, or expose the value in some sort of raw format.

danieagle commented 3 years ago

Hi! Thanks! I completed the go lang support. https://github.com/danieagle/colfer bigdecimal branch :-)

Mostly arbitrary precision libs already use a text or a array of bytes as mantissa, because this, mostly change or conversion (type to []byte and []byte to type) is high performance.

i finished golang, so what next language do you want? Thanks, Dani.

pascaldekloe commented 3 years ago

A good start would be to add a big decimal entry in ./testdata/test.colf O and run the unit tests to see if your code compiles. Next we need a unit test (in ./go/gen_test.go).

pascaldekloe commented 3 years ago

You are still allocating a new buffer with MarshalText. At least use Append with hex then for somewhat reasonable performance. Better would be to store the decimal point as a varint, and the integer representation as a big-endian byte array + sign bit.