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

Decimal optimization #1

Open
homonoidian opened this issue Aug 1, 2022 · 0 comments
Open

Decimal optimization #1

homonoidian opened this issue Aug 1, 2022 · 0 comments
Labels
optimization Improvements to the speed

Comments

@homonoidian
Copy link
Collaborator

Numbers (they're called Decimals in Novika) are a vital part of the language. Looping, math, sizing (getting/setting insertion point, obtaining the amount of items in blocks or the amount of characters in a string, etc.) -- all this requires Decimals, and all this requires decimals to be fast.

And they're not.

The Decimal struct can be found in src/novika/forms/decimal.cr. It uses BigDecimal, and BigDecimal only. That's perfectly fine for a prototype, but now is time for optimization. Just remembering BigDecimal is always heap allocated sends shivers down my spine. Some of my benchmarks have shown that big decimal loops are almost 400x times slower than even a badly-designed number promotion engine.

For integers, the goal is to climb the type ladder (promote) with as little overhead as possible. That is, if two (unoptimized) int32 additions happen in X, we should aim at ~2X or less, if being optimistic. Same for all other types: Int64, (maybe) Int128, BigInt. The only expense that can be tolerated is promotion itself. Most of the time, it is not needed at all (e.g., loop counters almost always are int32s and rarely exceed the type's limits). This way, we stay at comfortable speed and 0 memory use, and upon a single promotion, may slow down a bit and use a bit of memory, to then speed up again.

That said, Novika is, and will be a high level, human-oriented language (although one that looks pretty strange). We cannot afford to lose precision. Therefore, floats must always use BigFloat or something like that. In my practice, fast floats are rarely needed (at the moment of writing, Novika doesn't even parse floats; the only way to obtain them is division: `1 2 / ). We'd always be able to implement a similar promotion engine for floats; decimals are much more important and will lead to a much larger, and more easily achievable performance improvement.

If anyone wants to address this, go to the decimal file. The struct is completely isolated. You can yank it out and work with it outside Novika (removing the extends and includes, I guess), and hopefully write tests for it (I really have to make this a habit). Just don't violate the type signatures, and theoretically you'd be able to paste your modified decimal back in and Novika will work fine.

@homonoidian homonoidian added enhancement New feature or request optimization Improvements to the speed and removed enhancement New feature or request labels Aug 1, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
optimization Improvements to the speed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant