Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve performance when storing/loading from ByteArrays #192

Open
BenjaminWarnke opened this issue Oct 21, 2021 · 3 comments
Open

Improve performance when storing/loading from ByteArrays #192

BenjaminWarnke opened this issue Oct 21, 2021 · 3 comments
Assignees
Labels
enhancement New feature or request
Milestone

Comments

@BenjaminWarnke
Copy link
Contributor

Additional context
I am implementing a database. Therefore my use case is:

  1. Instantiate a BigInteger once from a String
  2. convert it to ByteArray, save it to a File (once!) ... (right now the BigInteger is garbage-collected here)
  3. read it many many (million) times from that ByteArray/File
  4. do calculations with it (+-*/><= ...)
  5. eventually print it as String

Is your feature request related to a problem? Please describe.
In step 3 I am loading the BigInteger from an ByteArray - each time a new java-class is created.
This might be ok for a few values, but it is very bad for the garbage collector, if I have millions/billions of these.

Describe the solution you'd like
I'd like to skip step 3 entirely.
I want to call the calculation functions (+- ...) directly on the ByteArrays (possibly supply offset and length within the byte array, to support storing multiple BigIntegers in a single ByteArray) without instantiating any classes.

Describe alternatives you've considered
Reusing an existing BigInteger class.
Right now the function "fromByteArray" returns a new class instance.
We could add another parameter with an "old" class instance, which we want to override with the contents of the new ByteArray.
This would reduce the garbage collector load significantly as well.

The same applies for BigDecimal and the other targets like JS.

@ionspin
Copy link
Owner

ionspin commented Oct 21, 2021

Hi Benjamin,

Thanks for bringing this issue to attention, there was already some work done on improving the allocations (#28), but I am aware that there is much more to be done.

Your proposal to reduce allocations by reusing arrays is definitely a promising way to go, I even think I was experimenting with it at some point, but didn't have time to dig in.

I want to call the calculation functions (+- ...) directly on the ByteArrays (possibly supply offset and length within the byte array, to support storing multiple BigIntegers in a single ByteArray) without instantiating any classes.

One point of inspiration could be Java MutableBigInteger implementation that behaves exactly like you describe, with indexes and array reuse.

Implementing a counterpart in this library would be great, but also a lot of work, starting with defining the interface for the operations, since now they would also take the "old" instance.

I have currently very limited time to work on this, so contributions are welcome! If you want to help out and have time to work on this, please tell me so we can set up a project or something similar, as I think there would be a lot of work and communication on who does what and how would be very important.

Once again, thanks!

@ionspin
Copy link
Owner

ionspin commented Oct 21, 2021

I forgot to mention this:

I want to call the calculation functions (+- ...) directly on the ByteArrays (possibly supply offset and length within the byte array, to support storing multiple BigIntegers in a single ByteArray) without instantiating any classes.

You would incur performance penalty here because hardware is usually optimized for arithmetic operations on words instead of bytes, so you would need at least one conversion from ByteArray to ULongArray which is the backing array in BigNum at the moment.

@BenjaminWarnke
Copy link
Contributor Author

You would incur performance penalty here because hardware is usually optimized for arithmetic operations on words instead of bytes, so you would need at least one conversion from ByteArray to ULongArray which is the backing array in BigNum at the moment.

In JVM and JS I agree, that we need to convert the data to (U)LongArray, but we could at least reuse those LongArrays there. In Kotlin Native we can cast the ByteArray to a LongArray without actually copy the data around.

@ionspin ionspin added the enhancement New feature or request label Dec 8, 2021
@ionspin ionspin self-assigned this Dec 10, 2021
@ionspin ionspin added this to the 0.5.0 milestone Dec 10, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants