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 fee estimation performance / fix accidentally quadratic function #2116

Merged
merged 4 commits into from
Sep 8, 2020

Conversation

KtorZ
Copy link
Member

@KtorZ KtorZ commented Sep 7, 2020

Issue Number

#2032 & rel

Overview

  • ca9dd1e
    📍 remove use of DerivingVia in Sqlite types: can't build with --profile with it

  • bc1bacc
    📍 avoid re-creating and folding on a map to compute balance of a list of resolved inputs
    This is somehow causing massive slowness in the fee estimation. Changing this reduces the time in benchmarks from 18,000ms to 3,000ms!!

  • f82a7fe
    📍 use standard random generator for picking random UTxO
    There's really no need for strong cryptographic randomness at this level, this is needlessly slower than it could be an called pretty often during fee calculation.

  • 94d4812
    📍 do not re-compute the full balance after picking new inputs
    Instead, compute the balance incrementally. The 'coverRemainingFee' was computing the balance of the extra inputs selected to cover for fee. In worst-case scenario where many inputs needed to be selected, for example, 1000 extra inputs, it'll recompute the balance of an ever growing list a thousand times! Not only this is accidentally quadratic, but, it is also completely unbounded and will potentially select way too many inputs. In theory, this should not select more than the max allowed inputs. Next commit will fix this.

Comments

Before:

Latency with 500 utxos scenario
    postTransactionFee  - 16756.3 ms

After:

    Latencies for 2 fixture wallets with 500 utxos scenario
        postTransactionFee  - 119.0 ms

@KtorZ KtorZ added the IMPROVEMENT Mark a PR as an improvement, for auto-generated CHANGELOG label Sep 7, 2020
@KtorZ KtorZ requested review from Anviking and rvl September 7, 2020 17:40
@KtorZ KtorZ self-assigned this Sep 7, 2020
@KtorZ KtorZ force-pushed the KtorZ/2032/fee-estimation-slow branch from 94d4812 to d4b0fd9 Compare September 7, 2020 18:42
Copy link
Contributor

@rvl rvl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice improvement but I have 2 questions.

@@ -109,12 +107,12 @@ data TargetRange = TargetRange
-- we set.
-- @
random
:: forall m e. MonadRandom m
:: forall e. ()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps in future, rather than using IO, we could explicity pass around the DRG state. Or maybe provide an infinite list of random UTxO to the function (if possible).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, testing was made a little harder because of this, plus, we also now loose the nice type signature that was nicely indicating which side-effects were needed. I might as well flag it as a technical debt to address later on and restore some purity in this.

:: Fee
-> StateT UTxO (ExceptT ErrAdjustForFee IO) ([(TxIn, TxOut)], Coin)
coverRemainingFee (Fee fee) = go [] 0 where
go additionalInputs surplus
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Just entry ->
go (entry : acc)
Just input@(_, out) ->
go (input : additionalInputs) (getCoin $ coin out)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the value of out need to be added to surplus here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤦 .... yes. That's the whole point.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fortunately our test suite catches it too 💪

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aaaand, fixed, tests are now passing :)

@@ -1231,7 +1228,10 @@ balance =
-- | Compute the balance of a unwrapped UTxO
balance' :: [(TxIn, TxOut)] -> Word64
balance' =
fromIntegral . balance . UTxO . Map.fromList
foldl' fn 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about just sum . map (getCoin . coin . snd)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've went for sum initially and switch to foldl' for consistency with the other balance calculation. It makes it more obvious that the same thing is happening.

…f resolved inputs

  This is somehow causing massive slowness in the fee estimation. Changing this reduces the time in benchmarks from 18,000ms to 3,000ms!!
  There's really no need for strong cryptographic randomness at this level, this is needlessly slower than it could be an called pretty often during fee calculation.
  Instead, compute the balance incrementally. The 'coverRemainingFee' was computing the balance of the extra inputs selected to cover for fee. In worst-case scenario where many inputs needed to be selected, for example, 1000 extra inputs, it'll recompute the balance of an ever growing list a thousand times! Not only this is accidentally quadratic, but, it is also completely unbounded and will potentially select way too many inputs. In theory, this should not select more than the max allowed inputs. Next commit will fix this.
@KtorZ KtorZ force-pushed the KtorZ/2032/fee-estimation-slow branch from d4b0fd9 to 89f8a06 Compare September 8, 2020 07:20
@KtorZ
Copy link
Member Author

KtorZ commented Sep 8, 2020

bors r+

@iohk-bors
Copy link
Contributor

iohk-bors bot commented Sep 8, 2020

Build succeeded:

@iohk-bors iohk-bors bot merged commit 82075c3 into master Sep 8, 2020
@iohk-bors iohk-bors bot deleted the KtorZ/2032/fee-estimation-slow branch September 8, 2020 09:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
IMPROVEMENT Mark a PR as an improvement, for auto-generated CHANGELOG
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants