Skip to content
This repository has been archived by the owner on Jan 22, 2025. It is now read-only.

built-in u128 has abysmal compute budget use on divison and is inferior to uint crate U128 #19549

Closed
nonergodic opened this issue Sep 1, 2021 · 5 comments

Comments

@nonergodic
Copy link

use uint::construct_uint;
construct_uint! {
    pub struct U128(2);
}

//[...]
fn compare_compute_budget_consumption() {
    let x = 17234u64; //some arbitrary number
    let y = 3273u64; //some arbitrary number
    
    //u64
    let v1 = x*10u64.pow(9);
    let v2 = y;
    sol_log_compute_units();
    let _add = v1+v2;
    sol_log_compute_units();
    let _sub = v1-v2;
    sol_log_compute_units();
    let _mul = v1*v2;
    sol_log_compute_units();
    let _div = v1/v2;
    sol_log_compute_units();
    
    //u128
    let v1 = (x as u128)*10u128.pow(19);
    let v2 = y as u128;
    sol_log_compute_units();
    let _add = v1+v2;
    sol_log_compute_units();
    let _sub = v1-v2;
    sol_log_compute_units();
    let _mul = v1*v2;
    sol_log_compute_units();
    let _div = v1/v2;
    sol_log_compute_units();
    
    //U128
    let v1 = U128::from(x)*U128::from(10).pow(19.into());
    let v2 = U128::from(y);
    sol_log_compute_units();
    let _add = v1+v2;
    sol_log_compute_units();
    let _sub = v1-v2;
    sol_log_compute_units();
    let _mul = v1*v2;
    sol_log_compute_units();
    let _div = v1/v2;
    sol_log_compute_units();
}

results (adding u64 for comparison):
u64:
add: 5
sub: 5
mul: 5
div: 6

u128:
add: 14
sub: 14
mul: 49
div: 3694 !!!

U128:
add: 8
sub: 8
mul: 8
div: 427

U128 is superior to the built-in u128 in every respect, except for .leading_zeros() and has correct overflow behavior (panicks as intended).

@sargarass
Copy link

any progress on this?
Tested on solana-test-validator 1.9.30 (src:30e47c2b; feat:462418899)
Same issue, when performing 31545460800000000000000000000000u128 / 120000000000000u128, takes 6854 compute units for this.

@kevinheavey
Copy link
Contributor

kevinheavey commented Apr 16, 2023

Any idea why I get very different numbers here?

u64:
add: 101
sub: 101
mul: 101
div: 101

u128:
add: 101
sub: 101
mul: 101
div: 101

U128:
add: 103
sub: 198
mul: 104
div: 404

I'm using solana-cli 1.14.10 and anchor-cli 0.26.0.

@nonergodic
Copy link
Author

Any idea why I get very different numbers here?

Logging a u64 by itself takes 100 compute units. Disable the release build (which almost certainly runs the optimizer which will replace all hardcoded calculations at compile time). Alternatively use Clock::get().unwrap().unix_timestamp as u64 as a dynamic seed for your numbers.

@CantelopePeel
Copy link

pr the change? seems fairly clean to swap

@nonergodic
Copy link
Author

Looks like this has been fixed. Reran the tests and CUs seem much lower now.

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

No branches or pull requests

4 participants