ionspin / kotlin-multiplatform-bignum

A Kotlin multiplatform library for arbitrary precision arithmetics
Apache License 2.0
339 stars 40 forks source link

[PERF] longValue(exactRequired = true) is very slow #298

Open glureau opened 1 month ago

glureau commented 1 month ago

Describe the bug No problem with the returned value, but the cost of using exactRequired = true is order of magnitude more costly than using exactRequired = false.

To Reproduce I was working on some load tests on our mathematical library, so a lot of calls were involved (BD creation, addition, multiplication, ...). In my case the BigDecimal was always rounded just before the call to longValue(exactRequired = true).

With the exactRequired = true this test was taking 7.5 minutes, when I just changed the boolean to false, it took 1.4 seconds.

Sorry that's maybe not clear to reproduce, but I believe any attempts should show a similarly high impact. In my case, I'd prefer to use exactRequired = true as I'm actually expecting an exact value, but the performance wasn't explicit.

Platform

ionspin commented 1 month ago

Hi @glureau thanks for reporting, I'll give it a look when I have time, 7.5 minutes vs 1.4 sounds drastic :) There's probably room for improvement wherever you look in the library, and this might be one of the places that could be improved. I thing it's because of a naive check to see if the big decimal is an whole number by using division and then checking if the remainder is zero. There's probably a much better way to go around that.

    /**
     * @return true if "this" is a whole number, false if not
     */
    fun isWholeNumber(): Boolean {
        val res = abs().divrem(ONE)
        val isWholeNumber = res.second.isZero()
        return isWholeNumber
    }