solana icon indicating copy to clipboard operation
solana copied to clipboard

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

Open nonergodic opened this issue 4 years ago • 4 comments

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).

nonergodic avatar Sep 01 '21 15:09 nonergodic

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.

sargarass avatar Jun 30 '22 17:06 sargarass

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.

kevinheavey avatar Apr 16 '23 20:04 kevinheavey

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.

nonergodic avatar Apr 21 '23 02:04 nonergodic

pr the change? seems fairly clean to swap

CantelopePeel avatar Jan 22 '24 21:01 CantelopePeel

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

nonergodic avatar May 09 '24 19:05 nonergodic