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

Investigate .expect potentially pulling in format code #746

Closed
ChaoticTempest opened this issue Mar 10, 2022 · 9 comments · Fixed by #1220
Closed

Investigate .expect potentially pulling in format code #746

ChaoticTempest opened this issue Mar 10, 2022 · 9 comments · Fixed by #1220
Assignees

Comments

@ChaoticTempest
Copy link
Member

ChaoticTempest commented Mar 10, 2022

Related to #745 (comment)

Investigate whether the following .expect call is pulling formatting code which would increase the code size:

near_sdk::borsh::BorshSerialize::try_to_vec(&result).expect("Failed to serialize the return value using Borsh.")
@sn99
Copy link

sn99 commented Nov 16, 2023

Hi @frol I would like to be assigned this issue.

@sn99
Copy link

sn99 commented Nov 20, 2023

Hi @frol, I got busy over the weekend.

Investigate whether the following .expect call is pulling formatting code which would increase the code size:

Yes it does, internally .expect(...) calls unwrap_failed(..., ...) which in turn calls our beloved panic!(...), and from the docs:

When using panic!() you can specify a string payload that is built using [formatting syntax].

This does seem to increase code size as stated in the rustwasm book.

The book mentions to use something like:

#![allow(unused_variables)]
fn main() {
#[inline]
pub fn unwrap_abort<T>(o: Option<T>) -> T {
    use std::process;
    match o {
        Some(t) => t,
        None => process::abort(),
    }
}
}

Stating:

Ultimately, panics translate into aborts in wasm32-unknown-unknown anyways, so this gives you the same behavior but without the code bloat.

But this would likely make us lose the message in expect.

On side note i was able to decrease the wasm file size by just adding:

[profile.release]
opt-level = 's'
codegen-units = 1

I can make a pr if needed.

@frol
Copy link
Collaborator

frol commented Dec 7, 2023

The book mentions to use something like:

@sn99 Well, sure, we already have near_sdk::env::panic_str() for that, but we don't want to give up on the standard features. Thinking about it now I realized that expect requires formatting to Debug-format the error itself.

How big is the impact on the Wasm binary size afterall? My guess is that near-sdk-rs pulls it a ton of code that has expect in it, so adding a user code with .expect won't change the picture much. Also, consider using https://github.com/austinabell/nesdie in addition to near-sdk-rs to compare the sizes (e.g. with nesdie I was able to build a meaningful contract in Rust that is under 1kb)

On side note i was able to decrease the wasm file size by just adding:

These are recommended options when creating a new project: https://docs.near.org/sdk/rust/get-started#create-a-new-project, but since you mention it, I believe we missed to overcommunicate it enough. Where would you want to add it?

@frol frol added the ODHack label Jul 29, 2024
@TropicalDog17
Copy link
Contributor

Hi @frol can I work on this issue? it seems the previous assignees was inactive for a while.

@frol frol assigned TropicalDog17 and unassigned sn99 Jul 29, 2024
@frol
Copy link
Collaborator

frol commented Jul 29, 2024

@TropicalDog17 Sure. Reassigned it to you

@TropicalDog17
Copy link
Contributor

Hi @frol, after replacing std expect with near-sdk's panic_str here and compile the fungible_token example, the wasm code size is reduced from 165.4KB to 165.1KB, which is 0.3KB (0.18%) reduction of code size. I'm not sure if it is significant or not, but actually remove the expect would decrease code size.
image

image

@frol
Copy link
Collaborator

frol commented Jul 29, 2024

@TropicalDog17 That is insignificant. Please, try replacing all .expect() calls in near-sdk-rs and in the code generated by near-sdk-macros, such as:

&::near_sdk::env::input().expect("Expected input since method has arguments.")
).expect("Failed to deserialize input from JSON.")
},
SerializerType::Borsh => quote! {
::near_sdk::borsh::BorshDeserialize::try_from_slice(
&::near_sdk::env::input().expect("Expected input since method has arguments.")

::near_sdk::serde_json::from_slice(&data).expect("Failed to deserialize callback using JSON")

@TropicalDog17
Copy link
Contributor

TropicalDog17 commented Jul 30, 2024

@frol
After replacing essentially all .expect() calls(#1220) here is the result, image

a decrease of 4kB, which is 2.42% reduction of code size compare to the original code in master branch.

@frol
Copy link
Collaborator

frol commented Jul 30, 2024

@TropicalDog17 I reviewed the PR, let's continue the discussion there

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

Successfully merging a pull request may close this issue.

4 participants