WebAssembly is slow

Hi!
I use Trunk to serve my app, and I use Tobj crate toparse my obj. file.

After I loaded my file, I try to parse it like this

let ( models, materials ) = load_model_from_slice( &buffer, "vokselia_spawn", &tobj::GPU_LOAD_OPTIONS ).await.expect( "Failed to load OBJ file" );
async fn load_model_from_slice( obj_buffer : &[ u8 ], material_folder : &str, load_options : &tobj::LoadOptions ) -> tobj::LoadResult
{
  let obj_cursor = Cursor::new( obj_buffer );
  let mut obj_reader = BufReader::new( obj_cursor );

  tobj::load_obj_buf_async
  (
    &mut obj_reader,
    load_options,
    move | p |
    {
      async move 
      {
        gl::console::time_with_label( "Load mtl" );
        // This just fetches the file from the server and returns Vec<u8>
        let mtl = gl::file::load( &format!( "{}/{}", material_folder, p ) ).await;

        if mtl.is_err()
        {
          gl::log::error!( "{:#?}", mtl );
          return Err( tobj::LoadError::OpenFileFailed );
        }
        let mtl = mtl.unwrap();
        let mtl_cursor = Cursor::new( mtl );
        let m = tobj::load_mtl_buf( &mut BufReader::new( mtl_cursor ) );
        gl::console::time_end_with_label( "Load mtl" );
        m
      }
    }
  )
  .await
}

The code above in WebAssembly take 44 seconds to parse a file, while the native version takes only 8 to parse the same file. Any idea why there is such a big difference in performance?

Did you build and run with -- release? If not, you're running a debug build.

1 Like

Yeah, I'm stupid. I ran both in debug build and got this difference. I thought that there shouldn't be this big of a difference, since they are both in the same build, so I didn't even think to try in release build.
For reference, in release, native parses in 1 second and WebAssembly in 4 seconds.

Thank you.

1 Like

You don't need any of the reader wrappers either. &[u8] already implements BufRead and Cursor only gives you Seek, which isn't needed by these functions.

async fn load_model_from_slice(
    obj_buffer: &[u8],
    material_folder: &str,
    load_options: &tobj::LoadOptions,
) -> tobj::LoadResult {
    tobj::load_obj_buf_async(&mut obj_buffer, load_options, |p| {
        async move {
            gl::console::time_with_label("Load mtl");
            // This just fetches the file from the server and returns Vec<u8>
            let mtl = gl::file::load(&format!("{}/{}", material_folder, p)).await;

            if mtl.is_err() {
                gl::log::error!("{:#?}", mtl);
                return Err(tobj::LoadError::OpenFileFailed);
            }
            let mtl = mtl.unwrap();
            let m = tobj::load_mtl_buf(&mut mtl.as_slice());
            gl::console::time_end_with_label("Load mtl");
            m
        }
    })
    .await
}

Thanks, didn't know about it

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.