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

How fast can decimals be if implemented in userland? #78

Open
sffc opened this issue Mar 15, 2023 · 4 comments
Open

How fast can decimals be if implemented in userland? #78

sffc opened this issue Mar 15, 2023 · 4 comments

Comments

@sffc
Copy link

sffc commented Mar 15, 2023

It would be compelling for the Decimal proposal if it meant that calculations in decimal space were faster than is achievable using plain JS code (or perhaps WASM code).

Do you have data on whether either decimal128 or BigDecimal can be implemented efficiently in JS code, and what the performance numbers look like versus an implementation in C/Rust?

@jessealama
Copy link
Collaborator

I'm not aware of any userland implementations of Decimal128 in JS (not even partially, for, say, addition and multiplication only). One route would be to take a C++ library for Decimal128 (say, Bloomberg's BDE), compile it to Wasm, and hook that into JS.

BigDecimal is much easier to test since there are a few good userland libraries out there that do pretty much everything we could want.

In other words, getting benchmarks might be a bit tricky (because of Decimal128).

In addition to measuring speed, I'd also be interested in getting some numbers on memory consumption. One worry about arbitrary-precision decimals is that, when faced with complex calculations, the number of digits involved might unintentionally get big, quickly, unless one were careful to always limit the precision of the operations to something reasonably small.

@jessealama
Copy link
Collaborator

The following is not a knock-down argument (it's not based on any data), but just thinking about the ways that one could represent decimals in JavaScript, the only two options that occur to me for the underlying data are:

  1. digit strings ("123.456")
  2. BigInts (e.g., two of them, one for before and one for after the decimal point).

I'd be surprised if working with digit strings could possibly be as fast as, say, a native Decimal128 implementation. One would work digit by digit through the string.

@michaelficarra
Copy link
Member

@jessealama By manually interning (hoisting all "constant" constructions of decimals to the top of the program), you would avoid parsing the string more than once. And parsing the string once is ~equivalent to the engine parsing the decimal out of the source text as a literal, so there's not much harm there other than the footgun of having to do the interning or you get bad perf.

As far as perf compared to a wasm or JS library impl, a native impl could take advantage of hardware acceleration that has become available in recent processors. That said, Decimal128 was designed in a way that a userland (wasm) bit-twiddling implementation would be decently performant anyway. So it may not make all that much of a difference.

@sffc
Copy link
Author

sffc commented Oct 6, 2023

Basically what I'm asking is to benchmark a little script that takes a decimal performs some operation on it in pure Rust/C++ and then across the WASM boundary.

You should also note the code size of this WASM file. If you get a file that is several MB in size after you perform code size optimizations (i.e. building your Rust code with opt-level=s, #![no_std], etc) that could also be a motivator.

Here are some 128-bit decimal libraries in Rust; not sure if they are what you are looking for:

https://docs.rs/dec/latest/dec/struct.Decimal128.html (this one wraps decNumber which is a C library)

https://docs.rs/rust_decimal/latest/rust_decimal/struct.Decimal.html (this one is in pure Rust)

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

3 participants