When passing a UInt8List to a Rust function from Dart, the UI hangs for approximately 1 second per MB on my machine. I have created a minimal example, below.
The Rust function in question here doesn't actually do anything with the passed blob, it just returns a fixed string. The hang does not occur until the rust function is called, which implies to me that this is related to how types are translated and/or transferred.
#[flutter_rust_bridge::frb(sync)] // i've omitted this with no effect
pub fn do_nothing_with_blob(blob: Vec<u8>) -> String {
format!("Hello, I didn't even look at the blob! Nyah!")
}
Future<String?> _processBlob() async {
print("Making blob.");
Uint8List blob = Uint8List(1024 * 1024 * 10); // 10MB
print("Blob made, sending to Rust."); // this occurs immediately
return doNothingWithBlob(blob: blob); // this hangs the UI for about 10 seconds
}
My end goal is to process a file in Rust that is "uploaded" from Dart via a file picker.
Describe the bug
When passing a
UInt8List
to a Rust function from Dart, the UI hangs for approximately 1 second per MB on my machine. I have created a minimal example, below.The Rust function in question here doesn't actually do anything with the passed blob, it just returns a fixed string. The hang does not occur until the rust function is called, which implies to me that this is related to how types are translated and/or transferred.
My end goal is to process a file in Rust that is "uploaded" from Dart via a file picker.
Steps to reproduce
Here's a repo that reproduces this behaviour: https://github.com/isosphere/frb_large_transfer_hang_reproduction
Logs
collapsable logs section
```shell frb_large_transfer_hang_reproduction git:(main) RUST_LOG=debug flutter_rust_bridge_codegen generate [2024-09-15T23:54:00.964Z DEBUG /home/matt/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.4.0/src/main.rs:24] cli=Cli { verbose: false, command: Generate(GenerateCommandArgs { watch: false, primary: GenerateCommandArgsPrimary { config_file: None, rust_input: None, dart_output: None, c_output: None, duplicated_c_output: None, rust_root: None, rust_output: None, dart_entrypoint_class_name: None, dart_format_line_length: None, dart_preamble: None, rust_preamble: None, no_dart_enums_style: false, no_add_mod_to_lib: false, llvm_path: None, llvm_compiler_opts: None, dart_root: None, no_build_runner: false, extra_headers: None, no_web: false, no_deps_check: false, default_external_library_loader_web_prefix: None, no_dart3: false, full_dep: false, local: false, enable_lifetime: false, type_64bit_int: false, no_default_dart_async: false, stop_on_error: false, dump: None, dump_all: false } }) } [2024-09-15T23:54:00.964Z DEBUG /home/matt/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.4.0/src/library/codegen/config/config_parser.rs:51] Found config file flutter_rust_bridge.yaml [2024-09-15T23:54:00.964Z DEBUG /home/matt/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.4.0/src/library/codegen/mod.rs:23] config=Config { base_dir: Some(""), rust_input: Some("crate::api"), dart_output: Some("lib/src/rust"), c_output: None, duplicated_c_output: None, rust_root: Some("rust/"), rust_output: None, dart_entrypoint_class_name: None, dart_format_line_length: None, dart_preamble: None, rust_preamble: None, dart_enums_style: None, add_mod_to_lib: None, llvm_path: None, llvm_compiler_opts: None, dart_root: None, build_runner: None, extra_headers: None, web: None, deps_check: None, dart3: None, full_dep: None, local: None, default_external_library_loader_web_prefix: None, dart_type_rename: None, enable_lifetime: None, type_64bit_int: None, default_dart_async: None, stop_on_error: None, dump: None, dump_all: None } meta_config=MetaConfig { watch: false } [2024-09-15T23:54:00.964Z DEBUG /home/matt/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.4.0/src/library/codegen/config/internal_config_parser/mod.rs:33] InternalConfig.parse base_dir="/home/matt/src/frb_large_transfer_hang_reproduction" [2024-09-15T23:54:01.123Z DEBUG /home/matt/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.4.0/src/library/codegen/mod.rs:26] internal_config=InternalConfig { controller: ControllerInternalConfig { watch: false, watching_paths: ["/home/matt/src/frb_large_transfer_hang_reproduction/rust/src"], exclude_paths: ["/home/matt/src/frb_large_transfer_hang_reproduction/rust/src/frb_generated.rs"], max_count: None }, preparer: PreparerInternalConfig { dart_root: "/home/matt/src/frb_large_transfer_hang_reproduction", deps_check: true, needs_ffigen: false }, parser: ParserInternalConfig { hir: ParserHirInternalConfig { rust_input_namespace_pack: RustInputNamespacePack { rust_input_namespace_prefixes: [Namespace { joined_path: "crate::api" }], rust_output_path_namespace: Namespace { joined_path: "crate::frb_generated" } }, rust_crate_dir: "/home/matt/src/frb_large_transfer_hang_reproduction/rust", third_party_crate_names: [] }, mir: ParserMirInternalConfig { rust_input_namespace_pack: RustInputNamespacePack { rust_input_namespace_prefixes: [Namespace { joined_path: "crate::api" }], rust_output_path_namespace: Namespace { joined_path: "crate::frb_generated" } }, force_codec_mode_pack: Some(CodecModePack { dart2rust: Pde, rust2dart: Pde }), default_stream_sink_codec: Sse, default_rust_opaque_codec: Moi, stop_on_error: false, enable_lifetime: false, type_64bit_int: false, default_dart_async: true } }, generator: GeneratorInternalConfig { api_dart: GeneratorApiDartInternalConfig { dart_enums_style: true, dart3: true, dart_decl_base_output_path: "/home/matt/src/frb_large_transfer_hang_reproduction/lib/src/rust", dart_impl_output_path: TargetOrCommonMap { common: "/home/matt/src/frb_large_transfer_hang_reproduction/lib/src/rust/frb_generated.dart", io: "/home/matt/src/frb_large_transfer_hang_reproduction/lib/src/rust/frb_generated.io.dart", web: "/home/matt/src/frb_large_transfer_hang_reproduction/lib/src/rust/frb_generated.web.dart" }, dart_entrypoint_class_name: "RustLib", dart_preamble: "", dart_type_rename: {} }, wire: GeneratorWireInternalConfig { dart: GeneratorWireDartInternalConfig { has_ffigen: false, web_enabled: true, llvm_path: ["/opt/homebrew/opt/llvm", "/usr/local/opt/llvm", "/usr/lib/llvm-9", "/usr/lib/llvm-10", "/usr/lib/llvm-11", "/usr/lib/llvm-12", "/usr/lib/llvm-13", "/usr/lib/llvm-14", "/usr/lib/", "/usr/lib64/", "C:/Program Files/llvm", "C:/msys64/mingw64"], llvm_compiler_opts: "", dart_root: "/home/matt/src/frb_large_transfer_hang_reproduction", extra_headers: "", dart_impl_output_path: TargetOrCommonMap { common: "/home/matt/src/frb_large_transfer_hang_reproduction/lib/src/rust/frb_generated.dart", io: "/home/matt/src/frb_large_transfer_hang_reproduction/lib/src/rust/frb_generated.io.dart", web: "/home/matt/src/frb_large_transfer_hang_reproduction/lib/src/rust/frb_generated.web.dart" }, dart_output_class_name_pack: DartOutputClassNamePack { entrypoint_class_name: "RustLib", api_class_name: "RustLibApi", api_impl_class_name: "RustLibApiImpl", api_impl_platform_class_name: "RustLibApiImplPlatform", wire_class_name: "RustLibWire", wasm_module_name: "RustLibWasmModule" }, default_external_library_loader: GeneratorWireDartDefaultExternalLibraryLoaderInternalConfig { stem: "rust_lib_frb_large_transfer_hang_reproduction", io_directory: "rust/target/release/", web_prefix: "pkg/" }, c_symbol_prefix: "frbgen_frb_large_transfer_hang_reproduction_" }, rust: GeneratorWireRustInternalConfig { rust_crate_dir: "/home/matt/src/frb_large_transfer_hang_reproduction/rust", web_enabled: true, rust_output_path: "/home/matt/src/frb_large_transfer_hang_reproduction/rust/src/frb_generated.rs", c_symbol_prefix: "frbgen_frb_large_transfer_hang_reproduction_", has_ffigen: false, default_stream_sink_codec: Sse, default_rust_opaque_codec: Moi, rust_preamble: "" }, c: GeneratorWireCInternalConfig { enable: false, rust_crate_dir: "/home/matt/src/frb_large_transfer_hang_reproduction/rust", rust_output_path: "/home/matt/src/frb_large_transfer_hang_reproduction/rust/src/frb_generated.rs", c_output_path: None, c_symbol_prefix: "frbgen_frb_large_transfer_hang_reproduction_" } } }, polisher: PolisherInternalConfig { duplicated_c_output_path: [], dart_format_line_length: 80, add_mod_to_lib: true, build_runner: true, web_enabled: true, dart_root: "/home/matt/src/frb_large_transfer_hang_reproduction", rust_crate_dir: "/home/matt/src/frb_large_transfer_hang_reproduction/rust", rust_output_path: "/home/matt/src/frb_large_transfer_hang_reproduction/rust/src/frb_generated.rs", c_output_path: None, enable_auto_upgrade: true }, dumper: DumperInternalConfig { dump_contents: [], dump_directory: "/home/matt/src/frb_large_transfer_hang_reproduction/rust/target/frb_dump" } } [2024-09-15T23:54:01.123Z DEBUG /home/matt/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.4.0/src/library/utils/dart_repository/dart_repo.rs:21] Guessing toolchain the runner is run into [2024-09-15T23:54:01.124Z DEBUG /home/matt/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.4.0/src/library/commands/command_runner.rs:129] execute command: bin=sh args="-c \"flutter\" \"--version\"" current_dir=None cmd="sh" "-c" "\"flutter\" \"--version\"" [2024-09-15T23:54:01.398Z DEBUG /home/matt/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.4.0/src/library/commands/command_runner.rs:140] command="sh" "-c" "\"flutter\" \"--version\"" stdout=Flutter 3.24.3 • channel stable • https://github.com/flutter/flutter.git Framework • revision 2663184aa7 (4 days ago) • 2024-09-11 16:27:48 -0500 Engine • revision 36335019a8 Tools • Dart 3.5.3 • DevTools 2.37.3 stderr= [2024-09-15T23:54:01.398Z DEBUG /home/matt/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.4.0/src/library/commands/cargo_expand/mod.rs:26] run_cargo_expand manifest_dir= rust_crate_dir="/home/matt/src/frb_large_transfer_hang_reproduction/rust" [2024-09-15T23:54:01.399Z DEBUG /home/matt/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.4.0/src/library/commands/cargo_expand/real.rs:60] Running cargo expand in '"/home/matt/src/frb_large_transfer_hang_reproduction/rust"' [2024-09-15T23:54:01.399Z DEBUG /home/matt/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.4.0/src/library/commands/command_runner.rs:129] execute command: bin=cargo args="expand --lib --theme=none --ugly" current_dir=Some("/home/matt/src/frb_large_transfer_hang_reproduction/rust") cmd=cd "/home/matt/src/frb_large_transfer_hang_reproduction/rust" && RUSTFLAGS="--cfg frb_expand" "cargo" "expand" "--lib" "--theme=none" "--ugly" [2024-09-15T23:54:01.638Z DEBUG /home/matt/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.4.0/src/library/commands/command_runner.rs:140] command=cd "/home/matt/src/frb_large_transfer_hang_reproduction/rust" && RUSTFLAGS="--cfg frb_expand" "cargo" "expand" "--lib" "--theme=none" "--ugly" stdout=#![feature(prelude_import)] #[prelude_import] use std::prelude::rust_2021::*; #[macro_use] extern crate std; pub mod api { pub mod simple { #[doc = "frb_encoded(235b6672622873796e63295d)"] pub fn do_nothing_with_blob(blob: Vec