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

Enhance Decoding Performance #5

Open
malvidin opened this issue Nov 20, 2022 · 2 comments
Open

Enhance Decoding Performance #5

malvidin opened this issue Nov 20, 2022 · 2 comments

Comments

@malvidin
Copy link

I am having performance issues decoding large inputs (>10KB). The issue may be with bs58-rs, not this project.

function decode 1M (seconds) decode 256B, timeit 5k (seconds)
gmpy2.mpz(data, base=58) 0.0387 0.0472
recursive_base58_decode(data) 0.256 0.508
based58.b58decode(data) 21.6 0.251
base58.b58decode(data) 86.4 1.13

I don't know if there is a base58 project that uses rug or similar for better large integer performance.

@kevinheavey
Copy link
Owner

Thanks for raising. This library is a very thin wrapper around bs58-rs so I'm not sure if there's anything that can be done on our side, but I'll leave this open in case anyone has any ideas

@malvidin
Copy link
Author

This nested loop is the upstream issue: https://github.com/Nullus157/bs58-rs/blob/pr%C4%ABmum/src/decode.rs#L307

for byte in &mut output[..index] {
    val += (*byte as usize) * 58;
    *byte = (val & 0xFF) as u8;
    val >>= 8;
}

Using rug or num_bigint would almost certainly be better. rug has an unsafe method, assign_bytes_radix_unchecked(), and num_bigint has from_radix_be(). I expect assign_bytes_radix_unchecked() would be faster for very large inputs, but I don't know what additional input cleaning of the input would be required.

let translated_input = vec![1u8, 1, 1];
let b58_biguint = BigUint::from_radix_be(&translated_input, 58).unwrap();
let decoded_vec = b58_biguint.to_bytes_be();
assert_eq!(decoded_vec, "\r_".as_bytes());

Cleaning the input once, using BigUint, and moving the data back into the output appears to significantly faster for the 256_bytes/decode_bs58 benchmark.
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants