Open xD0135 opened 2 years ago
Sure, happy to try. First, from what I can tell both projects were initially written in private repos without knowledge of the other. When we began working on membrane
in late 2020 or early 2021 there were no other end to end Rust <> Flutter FFI tools as far as I know. When I contributed the ZeroCopyBuffer feature back to the allo_isolate package one of my co-workers noticed that a newly open sourced project called flutter_rust_bridge had pulled the feature in as well and was trending on Reddit. All this to say... as far as I know neither project was created to "fix" a deficiency in the other. They are just different implementations and probably have slightly different priorities.
One of the first priorities of membrane is UI performance on the Flutter side, the second goal is developer ergonomics. We did benchmarking of various approaches and found that using a zero copy approach with bincode was extremely fast and stable resulting in no frame drops during high data throughput. If you're not familiar with bincode, it is a serialization protocol that is extremely lightweight as it only encodes the data as opposed to also encoding schema information. Since we control the code on both sides of the FFI boundary we can use this high performance schema-less approach and safely access/free it from Dart using the VM's DartNativeExternalTypedData
.
From what I can see these are some of the differences between the two projects:
serde
for reflection of Rust data types and bincode
to transfer complex data while frb does its own codegen and uses primitive types. (in membrane serde
features such as rename
can be leveraged by the developer for modifying struct fields)Result<T, E>
(or impl Stream<Item = Result<T, E>>
for streams) for all function return types and throws the custom error on the Dart side if any Err
is returned, frb appears to leave the return style up to the developer but also throws an Err
if it's returned#[async_dart]
or #[sync_dart]
macros and has options such as timeout
that can be configured per function, frb provides a CLI tool that generates Rust and Dart bridge code from parsing an api.rs
filepub
package with all data types, the API, and a lazy dynamic library loader which can be pulled into a plain Dart project or a Flutter project as a dependency, frb generates bridge files which can then be used as the developer likes#[async_dart(namespace = "foo")]
and #[async_dart(namespace = "bar")]
do not share types and are organized into separate barrel files in the generated pub package.main
branch] membrane provides a C compatible handle which can be handed from Rust to C to allow data to be sent asynchronously from a C thread to Dartmain
branch] membrane allows each function to be separately configured between async (tokio::spawn
), sync (block the Dart isolate), blocking thread pool (tokio::spawn_blocking
), or an emitter style which allows full control over the threading model.
Hi, is it possible to provide a high-level comparison between membrane and https://github.com/fzyzcjy/flutter_rust_bridge?