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

small wasm files example is actually huge! #1262

Closed
IcanDivideBy0 opened this issue Feb 15, 2019 · 17 comments
Closed

small wasm files example is actually huge! #1262

IcanDivideBy0 opened this issue Feb 15, 2019 · 17 comments

Comments

@IcanDivideBy0
Copy link

IcanDivideBy0 commented Feb 15, 2019

While the documentation claims the add_bg.wasm would be 710 byte, it's more like 700KB

Either using the online demo or building my own with --release flag produces a huge binary

Current demo file: https://rustwasm.github.io/wasm-bindgen/exbuild/add/23a8ffdd74ff21744bf0.module.wasm

Putting it into wasm2wat show that a huge zero filled data string is embeded inside the wasm file

image

rustc 1.34.0-nightly (f47ec2ad5 2019-02-14)

@alexcrichton
Copy link
Contributor

Thanks for the report! The extra size here is dwarf debugging information which is typically stripped by default in release builds but we has a misconfiguration that was fixed recently in #1255 and deployed pretty recently as well. The examples haven't fully rebuilt and redeployed yet but they'll be taken care of soon!

@IcanDivideBy0
Copy link
Author

Updated to 0.2.37, everything looks good!
As always, thanks for your reactivity :)

@jlb6740
Copy link

jlb6740 commented Mar 6, 2019

Just ran into this ... @IcanDivideBy0 what did you update to correct this? @alexcrichton looks like the fix #1255 is merged right? I am using 0.2.38 version wasm-bindgen but the issue is still there:

Compiling proc-macro2 v0.4.27
Compiling unicode-xid v0.1.0
Compiling wasm-bindgen-shared v0.2.38
Compiling cfg-if v0.1.7
Compiling lazy_static v1.3.0
Compiling wasm-bindgen v0.2.38
Compiling log v0.4.6
Compiling quote v0.6.11
Compiling syn v0.15.27
Compiling wasm-bindgen-backend v0.2.38
Compiling wasm-bindgen-macro-support v0.2.38
Compiling wasm-bindgen-macro v0.2.38

@IcanDivideBy0
Copy link
Author

@jlb6740 Simply updated wasm-bindgen to 0.2.37
did you compiled with the --release flag ?
also running the binaryen's utility wasm-opt can help a lot

@alexcrichton
Copy link
Contributor

@jlb6740 in addition to @IcanDivideBy0's suggestions, can you gist an example to reproduce what you're seeing? That might help us debug!

@jlb6740
Copy link

jlb6740 commented Mar 7, 2019

Hi .. Yes thanks @IcanDivideBy0 for the suggestion. I use the release flag and the file size is much smaller than the debug, but still larger than expected (180K instead of 989K). I have an example function where wasm-opt seemed to strip out code that I didn't consider dead .. I need to look at the options for this command more carefully but I agree this is a good suggestion. For now I have been doing wasm2wat and then wat2wasm instead of using bindgen or wasm-opt. @alexcrichton I put the code I am compiling here: https://gist.github.com/jlb6740/e31cf87f0906663995e654f3dea0caf5 . I have not been working with rust for long so I wouldn't be surprised if it is something trivial I am overlooking. Thanks.

@alexcrichton
Copy link
Contributor

alexcrichton commented Mar 7, 2019

@jlb6740 you may want to be sure to consult https://rustwasm.github.io/docs/book/reference/code-size.html when shrinking wasm, but if I check out that gist and run wasm-pack build it produces a 862 byte binary which I think is probably what you're looking for?

WebAssembly is a fundamentally low-level format that requires a lot of tools to work in concert right now so if you're just using rustc without wasm-bindgen and/or wasm-pack you'll need to reimplement the functionality that they bundle in with your workflow as well.

@IcanDivideBy0
Copy link
Author

IcanDivideBy0 commented Mar 7, 2019

As @alexcrichton pointed it out, after running the wasm-bindgen cli, you .wasm file shrink down to 862 bytes!
And wasm-opt make it 228 bytes

@jlb6740
Copy link

jlb6740 commented Mar 7, 2019

Hi ... 862 Bytes is a lot smaller than what I see with bindgen (180K). I don't know then what is different with my environment ... seems pretty straight forward but I would like to know. I am compiling with cargo build --release.

What you get from bindgen though is still discouraging. Nnot to get side tracked, but I am getting much smaller sizes ... 170 bytes by using wasm2wat:

cd wasm_binaries; cp fib.wasm fib.wasm.orig; wasm2wat fib.wasm.orig > fib.wasm; wat2wasm fib.wasm; cd ../;

Even if ignore all the \00 , the code is not as barebones as when I exclude bindgen. Code without bindgen:

(module
(type (;0;) (func))
(type (;1;) (func (param i32) (result i32)))
(func (;0;) (type 0))
(func (;1;) (type 1) (param i32) (result i32)
(local i32)
i32.const 1
set_local 1
block ;; label = @1
get_local 0
i32.const -1
i32.add
tee_local 0
i32.const 2
i32.lt_u
br_if 0 (;@1;)
i32.const 1
set_local 1
loop ;; label = @2
get_local 0
call 1
get_local 1
i32.add
set_local 1
get_local 0
i32.const -2
i32.add
tee_local 0
i32.const 1
i32.gt_u
br_if 0 (;@2;)
end
end
get_local 1)
(table (;0;) 1 1 anyfunc)
(memory (;0;) 16)
(global (;0;) (mut i32) (i32.const 1048576))
(global (;1;) i32 (i32.const 1048576))
(global (;2;) i32 (i32.const 1048576))
(export "memory" (memory 0))
(export "__heap_base" (global 1))
(export "__data_end" (global 2))
(export "_call" (func 1)))

Code with bindgen includes a lot of references to bindgen.. including a lot of calls some placeholder import stuff which I am not sure the purpose.

@alexcrichton @IcanDivideBy0 Any comments on this later size discrepancy? What is Bindgen adding for you that is not included in my wat printout above?

@IcanDivideBy0
Copy link
Author

cargo build --release
wasm-bindgen target/wasm32-unknown-unknown/release/fib.wasm --out-dir .
wasm-opt -Os  fib_bg.wasm -o fib_bg.wasm
stat -c %s fib_bg.wasm 
228

@IcanDivideBy0
Copy link
Author

and here is the text format i get

(module
  (type $t0 (func (param i32) (result i32)))
  (func $f0 (type $t0) (param $p0 i32) (result i32)
    (local $l1 i32)
    (local.set $l1
      (i32.const 1))
    (if $I0
      (i32.ge_u
        (local.tee $p0
          (i32.add
            (local.get $p0)
            (i32.const -1)))
        (i32.const 2))
      (then
        (loop $L1
          (local.set $l1
            (i32.add
              (call $f0
                (local.get $p0))
              (local.get $l1)))
          (br_if $L1
            (i32.gt_u
              (local.tee $p0
                (i32.add
                  (local.get $p0)
                  (i32.const -2)))
              (i32.const 1))))))
    (local.get $l1))
  (func $_call (export "_call") (type $t0) (param $p0 i32) (result i32)
    (call $f0
      (local.get $p0)))
  (memory $memory (export "memory") 17))

@IcanDivideBy0
Copy link
Author

IcanDivideBy0 commented Mar 7, 2019

Using --remove-producers-section flag, i went down to 104 bytes.
So I guess that's where the difference with the WAT size comes from.

wasm-bindgen \
  target/wasm32-unknown-unknown/release/fib.wasm \
  --remove-producers-section \
  --out-dir .

@jlb6740
Copy link

jlb6740 commented Mar 7, 2019

@IcanDivideBy0 Ok, cool. That actually looks like it should be fewer bytes smaller in binary than the file I am producing. I am not using wasm-opt though for the reason I mentioned. What is the size before wasm_opt .. just using bindgen? If I use wasm opt I can get the binary down further to 142 bytes instead of 170 bytes and my wat printout is also a little smaller. I definitely will try to use this after understanding the one example it appeared to break for me.

W.r.t your binary size, I suppose the WASM binary you have has some metadata that is not output here. My WASM binary size for what I posted is only 170 bytes. The size of the WASM file is critical for me because I am taking the files, dumping the file with hexdump and then embedding this as a data array in a tiny footprint interpreter I am running. I am curious now between bindgen vs wasm-opt w.r.t. the wat file you show and which is having the greater impact on wat size. I am also curious if I need to keep running wasm2wat and wat2wasm to get a small binary or if either bindgen or wasm-opt can get rid of whatever data is making your binary larger than it needs to be for my use case.

@jlb6740
Copy link

jlb6740 commented Mar 7, 2019

@IcanDivideBy0 lol .. cool. We had the same question. I will give this a try as soon as I can get past my first size problem and get down to 228bytes
.

@JeanMertz
Copy link

I'm seeing something similar, with latest versions. On top of seeing zero-filled data, I also see some assertion failure data creeping in the binary:

use wasm_bindgen::prelude::*;

#[wasm_bindgen(start)]
pub fn run() -> Result<(), JsValue> {
    Ok(())
}
$ cargo build --release
$ wasm-bindgen --version
wasm-bindgen 0.2.47
$ wasm-bindgen --remove-producers-section --remove-name-section --out-dir . target/wasm32-unknown-unknown/release/test.wasm
(module
  (type (;0;) (func))
  (func (;0;) (type 0))
  (memory (;0;) 17)
  (export "memory" (memory 0))
  (export "run" (func 0))
  (export "__wbindgen_start" (func 0))
  (data (;0;) (i32.const 1048576) "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00")
  (data (;1;) (i32.const 1049152) "\00\00\00\00assertion failed: `(left == right)`\0a  left: ``,\0a right: ``\00\00D\02\10\00-\00\00\00q\02\10\00\0c\00\00\00}\02\10\00\01\00\00\00/Users/jean/.cargo/registry/src/git.luolix.top-1ecc6299db9ec823/wasm-bindgen-0.2.47/src/lib.rs\00\00\98\02\10\00Z\00\00\003\04\00\00\09\00\00\00\03\00\00\00\04\00\00\00\04\00\00\00\04\00\00\00\05\00\00\00\06\00\00\00\07\00\00\00\00\00\00\00\01\00\00\00\08\00\00\00called `Option::unwrap()` on a `None` valuesrc/libcore/option.rs,\03\10\00+\00\00\00W\03\10\00\15\00\00\00[\01\00\00\15\00\00\00\09\00\00\00\10\00\00\00\04\00\00\00\0a\00\00\00\0b\00\00\00\0c\00\00\00\0c\00\00\00\04\00\00\00\0d\00\00\00src/liballoc/raw_vec.rscapacity overflow\bf\03\10\00\11\00\00\00\a8\03\10\00\17\00\00\00\ec\02\00\00\05\00\00\00\10\00\00\00\00\00\00\00\01\00\00\00\11\00\00\00index out of bounds: the len is  but the index is \00\00\f8\03\10\00 \00\00\00\18\04\10\00\12\00\00\00called `Option::unwrap()` on a `None` valuesrc/libcore/option.rs<\04\10\00+\00\00\00g\04\10\00\15\00\00\00[\01\00\00\15\00\00\00src/libcore/slice/mod.rsslice index starts at  but ends at \00\ac\04\10\00\16\00\00\00\c2\04\10\00\0d\00\00\00\94\04\10\00\18\00\00\00\01\0a\00\00\05\00\00\000x00010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899\00\00\00\00\00\00src/libcore/fmt/mod.rs\00\00\c0\05\10\00\16\00\00\00H\04\00\00(\00\00\00\c0\05\10\00\16\00\00\00T\04\00\00\11\00\00\00"))
[package]
name = "test"
version = "0.1.0"
edition = "2018"

[lib]
crate-type = ["cdylib"]

[dependencies]
wasm-bindgen = "0.2"
$ cargo tree
test v0.1.0 (/Users/jean/code/test)
└── wasm-bindgen v0.2.47
    └── wasm-bindgen-macro v0.2.47
        ├── quote v0.6.12
        │   └── proc-macro2 v0.4.30
        │       └── unicode-xid v0.1.0
        └── wasm-bindgen-macro-support v0.2.47
            ├── proc-macro2 v0.4.30 (*)
            ├── quote v0.6.12 (*)
            ├── syn v0.15.38
            │   ├── proc-macro2 v0.4.30 (*)
            │   ├── quote v0.6.12 (*)
            │   └── unicode-xid v0.1.0 (*)
            ├── wasm-bindgen-backend v0.2.47
            │   ├── bumpalo v2.4.3
            │   ├── lazy_static v1.3.0
            │   ├── log v0.4.6
            │   │   └── cfg-if v0.1.9
            │   ├── proc-macro2 v0.4.30 (*)
            │   ├── quote v0.6.12 (*)
            │   ├── syn v0.15.38 (*)
            │   └── wasm-bindgen-shared v0.2.47
            └── wasm-bindgen-shared v0.2.47 (*)

running wasm-opt removes the zero-filled data object but the second one is still there.

@Pauan
Copy link
Contributor

Pauan commented Jun 26, 2019

@JeanMertz Do you get the same result when using the rust-webpack-template?

(Make sure to use npm run build for maximum optimizations)

@alexcrichton
Copy link
Contributor

@JeanMertz the issue about panic/assertion strings should be fixed by d9e53ac, it was a recent regression but hasn't been published to crates.io yet

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

No branches or pull requests

5 participants