├── .gitignore ├── Cargo.toml ├── LICENSE ├── Readme.md ├── benches └── marshal_bench.rs ├── src ├── bench_async_rustbus.rs ├── bench_dbus_bytestream.rs ├── bench_dbus_message_parser.rs ├── bench_dbus_native.rs ├── bench_dbus_pure.rs ├── bench_dbusrs.rs ├── bench_rustbus.rs ├── bench_zvariant.rs └── lib.rs └── tools └── make_table.py /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | Cargo.lock 3 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "dbus_benches" 3 | version = "0.1.0" 4 | authors = ["Moritz Borcherding "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | async-std = "1.12.0" 11 | async-rustbus = "0.1.2" 12 | rustbus = "0.19.1" 13 | dbus = "0.9.6" 14 | 15 | dbus-bytestream = "0.1.4" 16 | dbus-serialize = "0.1.2" 17 | 18 | serde = "1.0.0" 19 | zbus = "5" 20 | 21 | dbus-pure = {git = "https://github.com/Arnavion/dbus-pure", rev = "cd238a268095e560801048332d82c5ec208f4e44"} 22 | 23 | dbus-message-parser = "4.3.1" 24 | bytes = "1.1.0" 25 | 26 | dbus-native = {git = "https://github.com/diwic/dbus-rs", rev = "2c29b4393f2073a019f2c9a2a96b140dd3ceb6ba"} 27 | 28 | [dev-dependencies] 29 | criterion = "0.4" 30 | 31 | [[bench]] 32 | name = "marshal_bench" 33 | harness = false 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Moritz Borcherding 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # What is this 2 | This repo tries to give an overview over the landscape of the the different dbus implementations that exists in the rust ecosystem. 3 | 4 | 1. https://github.com/KillingSpark/rustbus 5 | 1. https://github.com/diwic/dbus-rs/ (bindings to C library) 6 | 1. https://github.com/diwic/dbus-rs/tree/master/dbus-native 7 | 1. https://github.com/dbus2/zbus/ 8 | 1. https://github.com/Arnavion/dbus-pure 9 | 1. https://github.com/srwalter/dbus-bytestream 10 | 1. https://github.com/LinkTed/dbus-message-parser 11 | 1. https://github.com/cmaves/async-rustbus 12 | 13 | Note that I am the author of rustbus, but of course I am trying to be as objective as possible here. 14 | 15 | ## Current state 16 | Some benchmarks exist. I plan to add equivalent ones for the missing libs, and more kinds of benchmarks. 17 | 18 | ## The benchmarks 19 | 1. MarshalMix: Build a signal message with mixed params and marshal it 20 | 1. MarshalBigArray: Build a signal message with a big u64 array and marshal it 21 | 1. MarshalStrArray: Build a signal message with a big String array and marshal it 22 | 1. Marshal + Send: Connect to the sessionbus, build a signal and send it to the bus 23 | 24 | The dbus-message-parser does not provide any means of sending messages, so this benchmark is omitted. 25 | 26 | ## Current results 27 | I am running this on a Ryzen 3800X (/proc/cpuinfo says: AMD Ryzen 7 3800X). Your values might vary a bit. 28 | 29 | I used `rustc 1.65.0 (897e37553 2022-11-02)` to run these benchmarks. 30 | 31 | To replicate these results just run: `cargo bench`. That will run all benchmarks. 32 | 33 | | Library | MarshalMixed | MarshalStrArray | MarshalBigArray | Marshal + Send | 34 | |---------------------|--------------|-----------------|-----------------|----------------| 35 | | rustbus | 3.4257 µs | 98.394 µs | 2.1689 µs | 132.86 µs | 36 | | dbus-rs | 168.82 µs | 1.3286 ms | 377.54 µs | 282.87 µs | 37 | | dbus-native | 3.3086 µs | 826.04 µs | 67.291 µs | 87.377 µs | 38 | | dbus-bytestream | 14.002 µs | 1.1528 ms | 150.70 µs | 112.88 µs | 39 | | dbus-message-parser | 35.968 µs | 4.6027 ms | 700.71 µs | NaN | 40 | | dbus-pure | 14.657 µs | 226.58 µs | 23.864 µs | 90.029 µs | 41 | | zvariant | 9.1030 µs | 202.62 µs | 47.606 µs | NaN | 42 | | zvariant-derive | 9.1303 µs | 203.39 µs | 47.352 µs | NaN | 43 | | rustbus-async | 4.5583 µs | 104.72 µs | 2.2329 µs | 168.23 µs | 44 | -------------------------------------------------------------------------------- /benches/marshal_bench.rs: -------------------------------------------------------------------------------- 1 | use criterion::{black_box, criterion_group, criterion_main, Criterion}; 2 | use dbus_benches::make_async_rustbus_message; 3 | use dbus_benches::make_dbus_bytestream_message; 4 | use dbus_benches::make_dbus_message_parser_message; 5 | use dbus_benches::make_dbus_native_message; 6 | use dbus_benches::make_dbus_pure_message; 7 | use dbus_benches::make_dbusrs_message; 8 | use dbus_benches::make_rustbus_message; 9 | use dbus_benches::make_zvariant_derive_message; 10 | use dbus_benches::make_zvariant_message; 11 | use dbus_benches::MessageParts; 12 | use dbus_benches::ZVField; 13 | use dbus_benches::ZVStruct; 14 | 15 | fn make_mixed_message() -> MessageParts { 16 | let mut dict = std::collections::HashMap::new(); 17 | dict.insert("A".to_owned(), 1234567i32); 18 | dict.insert("B".to_owned(), 1234567i32); 19 | dict.insert("C".to_owned(), 1234567i32); 20 | dict.insert("D".to_owned(), 1234567i32); 21 | dict.insert("E".to_owned(), 1234567i32); 22 | 23 | MessageParts { 24 | string1: "Testtest".to_owned(), 25 | string2: "TesttestTestest".to_owned(), 26 | int1: 0xFFFFFFFFFFFFFFFFu64, 27 | int2: 0xFFFFFFFFFFFFFFFFu64, 28 | 29 | int_array: vec![ 30 | 0xFFFFFFFFFFFFFFFFu64, 31 | 0xFFFFFFFFFFFFFFFFu64, 32 | 0xFFFFFFFFFFFFFFFFu64, 33 | 0xFFFFFFFFFFFFFFFFu64, 34 | 0xFFFFFFFFFFFFFFFFu64, 35 | 0xFFFFFFFFFFFFFFFFu64, 36 | 0xFFFFFFFFFFFFFFFFu64, 37 | 0xFFFFFFFFFFFFFFFFu64, 38 | 0xFFFFFFFFFFFFFFFFu64, 39 | 0xFFFFFFFFFFFFFFFFu64, 40 | 0xFFFFFFFFFFFFFFFFu64, 41 | 0xFFFFFFFFFFFFFFFFu64, 42 | 0xFFFFFFFFFFFFFFFFu64, 43 | 0xFFFFFFFFFFFFFFFFu64, 44 | 0xFFFFFFFFFFFFFFFFu64, 45 | ], 46 | string_array: vec!["".into()], 47 | dict, 48 | interface: "io.killing.spark".into(), 49 | member: "TestSignal".into(), 50 | object: "/io/killing/spark".into(), 51 | repeat: 10, 52 | } 53 | } 54 | fn make_big_array_message() -> MessageParts { 55 | let mut dict = std::collections::HashMap::new(); 56 | dict.insert("A".to_owned(), 1234567i32); 57 | let mut int_array = Vec::new(); 58 | int_array.resize(1024 * 10, 0u64); 59 | 60 | MessageParts { 61 | string1: "Testtest".to_owned(), 62 | string2: "TesttestTestest".to_owned(), 63 | int1: 0xFFFFFFFFFFFFFFFFu64, 64 | int2: 0xFFFFFFFFFFFFFFFFu64, 65 | 66 | int_array, 67 | string_array: vec!["".into()], 68 | dict, 69 | interface: "io.killing.spark".into(), 70 | member: "TestSignal".into(), 71 | object: "/io/killing/spark".into(), 72 | repeat: 1, 73 | } 74 | } 75 | fn make_big_string_array_message() -> MessageParts { 76 | let mut dict = std::collections::HashMap::new(); 77 | dict.insert("A".to_owned(), 1234567i32); 78 | let mut string_array = Vec::new(); 79 | for idx in 0..1024 * 10 { 80 | string_array.push(format!( 81 | "{}{}{}{}{}{}{}{}{}{}{}{}", 82 | idx, idx, idx, idx, idx, idx, idx, idx, idx, idx, idx, idx 83 | )) 84 | } 85 | 86 | MessageParts { 87 | string1: "Testtest".to_owned(), 88 | string2: "TesttestTestest".to_owned(), 89 | int1: 0xFFFFFFFFFFFFFFFFu64, 90 | int2: 0xFFFFFFFFFFFFFFFFu64, 91 | 92 | string_array, 93 | int_array: vec![0], 94 | dict, 95 | interface: "io.killing.spark".into(), 96 | member: "TestSignal".into(), 97 | object: "/io/killing/spark".into(), 98 | repeat: 1, 99 | } 100 | } 101 | 102 | fn run_marshal_benches(group_name: &str, c: &mut Criterion, parts: &MessageParts) { 103 | let mut group = c.benchmark_group(group_name); 104 | group.bench_function("marshal_rustbus", |b| { 105 | b.iter(|| { 106 | black_box(make_rustbus_message(parts, false)); 107 | }) 108 | }); 109 | group.bench_function("marshal_dbusrs", |b| { 110 | b.iter(|| { 111 | black_box(make_dbusrs_message(parts, false)); 112 | }) 113 | }); 114 | group.bench_function("marshal_dbus_native", |b| { 115 | b.iter(|| { 116 | black_box(make_dbus_native_message(parts, false)); 117 | }) 118 | }); 119 | group.bench_function("marshal_dbus_bytestream", |b| { 120 | b.iter(|| { 121 | black_box(make_dbus_bytestream_message(parts, false)); 122 | }) 123 | }); 124 | group.bench_function("marshal_dbus_msg_parser", |b| { 125 | b.iter(|| { 126 | black_box(make_dbus_message_parser_message(parts, false)); 127 | }) 128 | }); 129 | group.bench_function("marshal_dbus_pure", |b| { 130 | b.iter(|| { 131 | black_box(make_dbus_pure_message(parts, false)); 132 | }) 133 | }); 134 | group.bench_function("marshal_zvariant", |b| { 135 | b.iter(|| { 136 | black_box(make_zvariant_message(parts, false)); 137 | }) 138 | }); 139 | group.bench_function("marshal_zvariant_derive", |b| { 140 | // We don't necessarily need to clone anything here and keep refs in the structs but let's 141 | // avoid all the lifetimes fun, shall we? :) The struct creation is (intentionally) not 142 | // part of the benchmark anyway. 143 | let field = ZVField { 144 | int2: parts.int2, 145 | string2: parts.string2.clone(), 146 | }; 147 | 148 | let mut elements = vec![]; 149 | 150 | for _ in 0..parts.repeat { 151 | let element = ZVStruct { 152 | string1: parts.string1.clone(), 153 | int1: parts.int1, 154 | field: field.clone(), 155 | dict: parts.dict.clone(), 156 | int_array: parts.int_array.clone(), 157 | string_array: parts.string_array.clone(), 158 | }; 159 | elements.push(element); 160 | } 161 | 162 | b.iter(|| { 163 | black_box(make_zvariant_derive_message(parts, &elements, false)); 164 | }) 165 | }); 166 | group.bench_function("marshal_async_rustbus", |b| { 167 | b.iter(|| { 168 | black_box(make_async_rustbus_message(parts, false)); 169 | }); 170 | }); 171 | 172 | group.finish(); 173 | } 174 | 175 | fn criterion_benchmark(c: &mut Criterion) { 176 | // 177 | // This tests only marshalling speed 178 | // I think that libdbus and by that dbus-rs marshal values as they are added 179 | // so just creating the message is equivalent to create+marshal in rustbus? 180 | // 181 | let mixed_parts = make_mixed_message(); 182 | run_marshal_benches("MarshalMixed", c, &mixed_parts); 183 | let big_array_parts = make_big_array_message(); 184 | run_marshal_benches("MarshalBigArray", c, &big_array_parts); 185 | let big_str_array_parts = make_big_string_array_message(); 186 | run_marshal_benches("MarshalBigStrArray", c, &big_str_array_parts); 187 | let mut group = c.benchmark_group("Sending"); 188 | // 189 | // This tests the flow of: 190 | // 1. Connect to the session bus (including authentication with the session bus AND the hello message handshake!) 191 | // 2. Create and marshal a signal message 192 | // 3. Send the signal to the bus 193 | // 194 | group.bench_function("send_rustbus", |b| { 195 | b.iter(|| { 196 | black_box(make_rustbus_message(&mixed_parts, true)); 197 | }) 198 | }); 199 | group.bench_function("send_dbusrs", |b| { 200 | b.iter(|| { 201 | black_box(make_dbusrs_message(&mixed_parts, true)); 202 | }) 203 | }); 204 | group.bench_function("send_dbusnative", |b| { 205 | b.iter(|| { 206 | black_box(make_dbus_native_message(&mixed_parts, true)); 207 | }) 208 | }); 209 | group.bench_function("send_dbus_bytestream", |b| { 210 | b.iter(|| { 211 | black_box(make_dbus_bytestream_message(&mixed_parts, true)); 212 | }) 213 | }); 214 | group.bench_function("send_dbus_pure", |b| { 215 | b.iter(|| { 216 | black_box(make_dbus_pure_message(&mixed_parts, true)); 217 | }) 218 | }); 219 | group.bench_function("send_zvariant", |b| { 220 | b.iter(|| { 221 | black_box(make_zvariant_message(&mixed_parts, true)); 222 | }) 223 | }); 224 | group.bench_function("send_zvariant_derive", |b| { 225 | // We don't necessarily need to clone anything here and keep refs in the structs but let's 226 | // avoid all the lifetimes fun, shall we? :) The struct creation is (intentionally) not 227 | // part of the benchmark anyway. 228 | let field = ZVField { 229 | int2: mixed_parts.int2, 230 | string2: mixed_parts.string2.clone(), 231 | }; 232 | 233 | let mut elements = vec![]; 234 | 235 | for _ in 0..mixed_parts.repeat { 236 | let element = ZVStruct { 237 | string1: mixed_parts.string1.clone(), 238 | int1: mixed_parts.int1, 239 | field: field.clone(), 240 | dict: mixed_parts.dict.clone(), 241 | int_array: mixed_parts.int_array.clone(), 242 | string_array: mixed_parts.string_array.clone(), 243 | }; 244 | elements.push(element); 245 | } 246 | 247 | b.iter(|| { 248 | black_box(make_zvariant_derive_message(&mixed_parts, &elements, true)); 249 | }) 250 | }); 251 | group.bench_function("send_async_rustbus", |b| { 252 | b.iter(|| { 253 | black_box(make_async_rustbus_message(&mixed_parts, true)); 254 | }) 255 | }); 256 | 257 | group.finish(); 258 | } 259 | 260 | criterion_group!(benches, criterion_benchmark); 261 | criterion_main!(benches); 262 | -------------------------------------------------------------------------------- /src/bench_async_rustbus.rs: -------------------------------------------------------------------------------- 1 | use std::num::NonZeroU32; 2 | 3 | use crate::MessageParts; 4 | use async_rustbus::rustbus_core; 5 | 6 | pub fn make_async_rustbus_message(parts: &MessageParts, send_it: bool) -> Option> { 7 | let mut msg = rustbus_core::message_builder::MessageBuilder::new() 8 | .signal( 9 | parts.interface.clone(), 10 | parts.member.clone(), 11 | parts.object.clone(), 12 | ) 13 | .build(); 14 | 15 | for _ in 0..parts.repeat { 16 | msg.body.push_param(parts.string1.as_str()).unwrap(); 17 | msg.body.push_param(parts.int1).unwrap(); 18 | msg.body 19 | .push_param((parts.int2, parts.string2.as_str())) 20 | .unwrap(); 21 | msg.body.push_param(&parts.dict).unwrap(); 22 | msg.body.push_param(parts.int_array.as_slice()).unwrap(); 23 | msg.body.push_param(parts.string_array.as_slice()).unwrap(); 24 | } 25 | 26 | if send_it { 27 | async_std::task::block_on(async { 28 | let conn = async_rustbus::RpcConn::session_conn(false).await?; 29 | conn.send_msg_wo_rsp(&msg).await.map(|_| ()) 30 | }) 31 | .unwrap(); 32 | None 33 | } else { 34 | let mut buf = Vec::new(); 35 | msg.marshal_header(NonZeroU32::new(1).unwrap(), &mut buf) 36 | .unwrap(); 37 | Some(buf) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/bench_dbus_bytestream.rs: -------------------------------------------------------------------------------- 1 | use super::MessageParts; 2 | 3 | pub fn make_dbus_bytestream_message(parts: &MessageParts, send_it: bool) -> Option> { 4 | let mut msg = 5 | dbus_bytestream::message::create_signal(&parts.interface, &parts.member, &parts.object); 6 | 7 | let map: std::collections::HashMap<_, _> = parts 8 | .dict 9 | .iter() 10 | .map(|(k, v)| { 11 | ( 12 | dbus_serialize::types::BasicValue::String(k.clone()), 13 | dbus_serialize::types::Value::BasicValue(dbus_serialize::types::BasicValue::Int32( 14 | *v, 15 | )), 16 | ) 17 | }) 18 | .collect(); 19 | 20 | let int_array: Vec<_> = parts 21 | .int_array 22 | .iter() 23 | .map(|i| { 24 | dbus_serialize::types::Value::BasicValue(dbus_serialize::types::BasicValue::Uint64(*i)) 25 | }) 26 | .collect(); 27 | let string_array: Vec<_> = parts 28 | .string_array 29 | .iter() 30 | .cloned() 31 | .map(|i| { 32 | dbus_serialize::types::Value::BasicValue(dbus_serialize::types::BasicValue::String(i)) 33 | }) 34 | .collect(); 35 | 36 | let strct = dbus_serialize::types::Struct { 37 | objects: vec![ 38 | dbus_serialize::types::Value::BasicValue(dbus_serialize::types::BasicValue::Uint64( 39 | parts.int2, 40 | )), 41 | dbus_serialize::types::Value::BasicValue(dbus_serialize::types::BasicValue::String( 42 | parts.string2.clone(), 43 | )), 44 | ], 45 | signature: dbus_serialize::types::Signature("ts".to_owned()), 46 | }; 47 | 48 | for _ in 0..parts.repeat { 49 | msg = msg.add_arg(&parts.string1); 50 | msg = msg.add_arg(&parts.int1); 51 | msg = msg.add_arg(&strct); 52 | msg = msg.add_arg(&map); 53 | msg = msg.add_arg(&int_array); 54 | msg = msg.add_arg(&string_array); 55 | } 56 | 57 | if send_it { 58 | let conn = dbus_bytestream::connection::Connection::connect_session().unwrap(); 59 | conn.send(msg).unwrap(); 60 | None 61 | } else { 62 | let mut buf = Vec::new(); 63 | use dbus_bytestream::marshal::Marshal; 64 | msg.dbus_encode(&mut buf); 65 | Some(buf) 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/bench_dbus_message_parser.rs: -------------------------------------------------------------------------------- 1 | use super::MessageParts; 2 | use std::convert::TryInto; 3 | 4 | pub fn make_dbus_message_parser_message( 5 | parts: &MessageParts, 6 | send_it: bool, 7 | ) -> Option { 8 | let mut signal = dbus_message_parser::message::Message::signal( 9 | parts.object.as_str().try_into().unwrap(), 10 | parts.interface.as_str().try_into().unwrap(), 11 | parts.member.as_str().try_into().unwrap(), 12 | ); 13 | 14 | let dict_content = parts 15 | .dict 16 | .iter() 17 | .map(|(k, v)| { 18 | dbus_message_parser::value::Value::DictEntry(Box::new(( 19 | dbus_message_parser::value::Value::String(k.clone()), 20 | dbus_message_parser::value::Value::Int32(*v), 21 | ))) 22 | }) 23 | .collect(); 24 | let dict = dbus_message_parser::value::Value::Array( 25 | dbus_message_parser::value::Array::new(dict_content, "{si}".try_into().unwrap()).unwrap(), 26 | ); 27 | 28 | let array = dbus_message_parser::value::Value::Array( 29 | dbus_message_parser::value::Array::new( 30 | parts 31 | .int_array 32 | .iter() 33 | .copied() 34 | .map(|i| dbus_message_parser::value::Value::Uint64(i)) 35 | .collect(), 36 | "t".try_into().unwrap(), 37 | ) 38 | .unwrap(), 39 | ); 40 | 41 | let stringarray = dbus_message_parser::value::Value::Array( 42 | dbus_message_parser::value::Array::new( 43 | parts 44 | .string_array 45 | .iter() 46 | .cloned() 47 | .map(|i| dbus_message_parser::value::Value::String(i)) 48 | .collect(), 49 | "s".try_into().unwrap(), 50 | ) 51 | .unwrap(), 52 | ); 53 | 54 | for _ in 0..parts.repeat { 55 | signal.add_value(dbus_message_parser::value::Value::String( 56 | parts.string1.clone(), 57 | )); 58 | signal.add_value(dbus_message_parser::value::Value::Uint64(parts.int1)); 59 | signal.add_value(dbus_message_parser::value::Value::Struct( 60 | vec![ 61 | dbus_message_parser::value::Value::Uint64(parts.int2), 62 | dbus_message_parser::value::Value::String(parts.string2.clone()), 63 | ] 64 | .try_into() 65 | .unwrap(), 66 | )); 67 | signal.add_value(dict.clone()); 68 | signal.add_value(array.clone()); 69 | signal.add_value(stringarray.clone()); 70 | } 71 | if send_it { 72 | // no send implemented 73 | None 74 | } else { 75 | let buffer = signal.encode().unwrap(); 76 | Some(buffer) 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/bench_dbus_native.rs: -------------------------------------------------------------------------------- 1 | use super::MessageParts; 2 | 3 | pub fn make_dbus_native_message(parts: &MessageParts, send_it: bool) -> Option> { 4 | use dbus_native::marshalled::Marshal; 5 | use dbus_native::strings::{DBusStr, StringLike}; 6 | 7 | let ksig = <&DBusStr>::default().signature().into(); 8 | let vsig = i32::default().signature().into(); 9 | let mut dict = dbus_native::marshalled::DictBuf::new(ksig, vsig).unwrap(); 10 | for (key, value) in &parts.dict { 11 | let key = dbus_native::strings::DBusStr::new(key).unwrap(); 12 | dict.append(key, value).unwrap(); 13 | } 14 | 15 | let mut intarr = dbus_native::marshalled::ArrayBuf::new(u64::default().signature()).unwrap(); 16 | for x in &parts.int_array { 17 | intarr.append(x).unwrap(); 18 | } 19 | 20 | let stringarr = dbus_native::marshalled::ArrayBuf::from_iter( 21 | parts 22 | .string_array 23 | .iter() 24 | .map(|x| dbus_native::strings::DBusStr::new(x).unwrap()), 25 | ) 26 | .unwrap(); 27 | 28 | let string1 = dbus_native::strings::DBusStr::new(&parts.string1).unwrap(); 29 | let string2 = dbus_native::strings::DBusStr::new(&parts.string2).unwrap(); 30 | let mut stru = dbus_native::marshalled::MultiBuf::new(); 31 | stru.append(&parts.int2).unwrap(); 32 | stru.append(string2).unwrap(); 33 | let stru = dbus_native::marshalled::StructBuf::new(stru).unwrap(); 34 | let mut body = dbus_native::marshalled::MultiBuf::new(); 35 | for _ in 0..parts.repeat { 36 | body.append(string1).unwrap(); 37 | body.append(&parts.int1).unwrap(); 38 | body.append(&stru).unwrap(); 39 | body.append(&dict).unwrap(); 40 | body.append(&intarr).unwrap(); 41 | body.append(&stringarr).unwrap(); 42 | } 43 | 44 | let path = dbus_native::strings::ObjectPath::new(&parts.object).unwrap(); 45 | let interface = dbus_native::strings::InterfaceName::new(&parts.interface).unwrap(); 46 | let member = dbus_native::strings::MemberName::new(&parts.member).unwrap(); 47 | let mut msg = 48 | dbus_native::message::Message::new_signal(path.into(), interface.into(), member.into()) 49 | .unwrap(); 50 | msg.set_body(body); 51 | 52 | if send_it { 53 | let addr = dbus_native::address::read_session_address().unwrap(); 54 | let stream = dbus_native::address::connect_blocking(&addr).unwrap(); 55 | 56 | let mut reader = std::io::BufReader::new(&stream); 57 | let mut writer = &stream; 58 | assert!(!dbus_native::authentication::Authentication::blocking( 59 | &mut reader, 60 | &mut writer, 61 | false 62 | ) 63 | .unwrap()); 64 | writer.flush().unwrap(); 65 | 66 | let hellomsg = dbus_native::message::get_hello_message() 67 | .marshal(std::num::NonZeroU32::new(1u32).unwrap(), false) 68 | .unwrap(); 69 | use std::io::Write; 70 | writer.write_all(&hellomsg).unwrap(); 71 | writer.flush().unwrap(); 72 | 73 | let mut mr = dbus_native::message::MessageReader::new(); 74 | let reply = mr.block_until_next_message(&mut reader).unwrap(); 75 | let reply = dbus_native::message::Message::demarshal(&reply) 76 | .unwrap() 77 | .unwrap(); 78 | let _our_id = reply 79 | .read_body() 80 | .iter() 81 | .next() 82 | .unwrap() 83 | .unwrap() 84 | .parse() 85 | .unwrap(); 86 | 87 | let buf = msg 88 | .marshal(std::num::NonZeroU32::new(2u32).unwrap(), false) 89 | .unwrap(); 90 | writer.write_all(&buf).unwrap(); 91 | writer.flush().unwrap(); 92 | None 93 | } else { 94 | let buf = msg 95 | .marshal(std::num::NonZeroU32::new(1u32).unwrap(), false) 96 | .unwrap(); 97 | Some(buf) 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/bench_dbus_pure.rs: -------------------------------------------------------------------------------- 1 | use super::MessageParts; 2 | 3 | pub fn make_dbus_pure_message(parts: &MessageParts, send_it: bool) -> Option> { 4 | let mut header = dbus_pure::proto::MessageHeader { 5 | r#type: dbus_pure::proto::MessageType::Signal { 6 | interface: parts.interface.as_str().into(), 7 | member: parts.member.as_str().into(), 8 | path: dbus_pure::proto::ObjectPath(parts.object.as_str().into()), 9 | }, 10 | flags: dbus_pure::proto::message_flags::NO_REPLY_EXPECTED, 11 | body_len: 0, 12 | serial: 0, 13 | fields: (&[][..]).into(), 14 | }; 15 | 16 | let dict_content: Vec<_> = parts 17 | .dict 18 | .iter() 19 | .map(|(k, v)| { 20 | ( 21 | dbus_pure::proto::Variant::String(k.as_str().into()), 22 | dbus_pure::proto::Variant::I32(*v), 23 | ) 24 | }) 25 | .collect(); 26 | let dict_content: Vec<_> = dict_content 27 | .iter() 28 | .map(|(k, v)| dbus_pure::proto::Variant::DictEntry { 29 | key: k.into(), 30 | value: v.into(), 31 | }) 32 | .collect(); 33 | let dict = dbus_pure::proto::Variant::Array { 34 | element_signature: dbus_pure::proto::Signature::DictEntry { 35 | key: Box::new(dbus_pure::proto::Signature::String), 36 | value: Box::new(dbus_pure::proto::Signature::I32), 37 | }, 38 | elements: dict_content.into(), 39 | }; 40 | 41 | let array = dbus_pure::proto::Variant::ArrayU64((&parts.int_array).into()); 42 | let strs = parts 43 | .string_array 44 | .iter() 45 | .map(|s| dbus_pure::proto::Variant::String(s.as_str().into())) 46 | .collect::>(); 47 | let strarray = dbus_pure::proto::Variant::Array { 48 | elements: strs.into(), 49 | element_signature: dbus_pure::proto::Signature::String, 50 | }; 51 | 52 | let mut elements = vec![]; 53 | 54 | for _ in 0..parts.repeat { 55 | elements.push(dbus_pure::proto::Variant::String( 56 | parts.string1.as_str().into(), 57 | )); 58 | elements.push(dbus_pure::proto::Variant::U64(parts.int1)); 59 | elements.push(dbus_pure::proto::Variant::Struct { 60 | fields: vec![ 61 | dbus_pure::proto::Variant::U64(parts.int2), 62 | dbus_pure::proto::Variant::String(parts.string2.as_str().into()), 63 | ] 64 | .into(), 65 | }); 66 | elements.push(dict.clone()); 67 | elements.push(array.clone()); 68 | elements.push(strarray.clone()); 69 | } 70 | 71 | let body = dbus_pure::proto::Variant::Tuple { 72 | elements: elements.into(), 73 | }; 74 | 75 | if send_it { 76 | let connection = 77 | dbus_pure::Connection::new(dbus_pure::BusPath::System, dbus_pure::SaslAuthType::Uid) 78 | .unwrap(); 79 | let mut dbus_client = dbus_pure::Client::new(connection).unwrap(); 80 | let _ = dbus_client.send(&mut header, Some(&body)).unwrap(); 81 | None 82 | } else { 83 | let mut buf = Vec::new(); 84 | dbus_pure::proto::serialize_message( 85 | &mut header, 86 | Some(&body), 87 | &mut buf, 88 | dbus_pure::proto::Endianness::Little, 89 | ) 90 | .unwrap(); 91 | Some(buf) 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/bench_dbusrs.rs: -------------------------------------------------------------------------------- 1 | use super::MessageParts; 2 | 3 | pub fn make_dbusrs_message(parts: &MessageParts, send_it: bool) -> Option { 4 | let mut msg = dbus::message::Message::signal( 5 | &dbus::strings::Path::from(&parts.object), 6 | &dbus::strings::Interface::from(&parts.interface), 7 | &dbus::strings::Member::from(&parts.member), 8 | ); 9 | 10 | let dict = dbus::arg::Dict::new(parts.dict.iter().map(|(k, v)| (k, v))); 11 | 12 | for _ in 0..parts.repeat { 13 | msg = msg.append3(&parts.string1, parts.int1, (parts.int2, &parts.string2)); 14 | msg = msg.append3(&dict, &parts.int_array, &parts.string_array); 15 | } 16 | 17 | if send_it { 18 | use dbus::channel::Sender; 19 | let conn = dbus::blocking::Connection::new_session().unwrap(); 20 | conn.send(msg).unwrap(); 21 | None 22 | } else { 23 | // no need to marshal, that happend while building 24 | Some(msg) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/bench_rustbus.rs: -------------------------------------------------------------------------------- 1 | use crate::MessageParts; 2 | use rustbus::wire::marshal::marshal; 3 | 4 | pub fn make_rustbus_message(parts: &MessageParts, send_it: bool) -> Option> { 5 | let mut msg = rustbus::message_builder::MessageBuilder::new() 6 | .signal( 7 | parts.interface.clone(), 8 | parts.member.clone(), 9 | parts.object.clone(), 10 | ) 11 | .build(); 12 | 13 | for _ in 0..parts.repeat { 14 | msg.body.push_param(parts.string1.as_str()).unwrap(); 15 | msg.body.push_param(parts.int1).unwrap(); 16 | msg.body 17 | .push_param((parts.int2, parts.string2.as_str())) 18 | .unwrap(); 19 | msg.body.push_param(&parts.dict).unwrap(); 20 | msg.body.push_param(parts.int_array.as_slice()).unwrap(); 21 | msg.body.push_param(parts.string_array.as_slice()).unwrap(); 22 | } 23 | 24 | if send_it { 25 | let mut rustbus_con = rustbus::connection::rpc_conn::RpcConn::session_conn( 26 | rustbus::connection::Timeout::Infinite, 27 | ) 28 | .unwrap(); 29 | let serial = rustbus_con 30 | .send_message(&mut rustbus::standard_messages::hello()) 31 | .unwrap() 32 | .write_all() 33 | .unwrap(); 34 | let _name_resp = rustbus_con 35 | .wait_response(serial, rustbus::connection::Timeout::Infinite) 36 | .unwrap(); 37 | let _serial = rustbus_con 38 | .send_message(&mut msg) 39 | .unwrap() 40 | .write_all() 41 | .unwrap(); 42 | None 43 | } else { 44 | let mut buf = Vec::new(); 45 | marshal(&msg, 1, &mut buf).unwrap(); 46 | Some(buf) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/bench_zvariant.rs: -------------------------------------------------------------------------------- 1 | use super::MessageParts; 2 | 3 | pub fn make_zvariant_message(parts: &MessageParts, send_it: bool) -> Option { 4 | let struct_field = (parts.int2, &parts.string2); 5 | 6 | let mut elements = vec![]; 7 | 8 | for _ in 0..parts.repeat { 9 | let element = ( 10 | parts.string1.as_str(), 11 | parts.int1, 12 | &struct_field, 13 | &parts.dict, 14 | &parts.int_array, 15 | &parts.string_array, 16 | ); 17 | elements.push(element); 18 | } 19 | let msg = zbus::Message::signal( 20 | parts.object.as_str(), 21 | parts.interface.as_str(), 22 | parts.member.as_str(), 23 | ) 24 | .unwrap() 25 | .build(&elements) 26 | .unwrap(); 27 | 28 | if send_it { 29 | let con = zbus::blocking::Connection::session().unwrap(); 30 | con.send(&msg).unwrap(); 31 | None 32 | } else { 33 | Some(msg) 34 | } 35 | } 36 | 37 | use serde::{Deserialize, Serialize}; 38 | use zbus::zvariant::Type; 39 | 40 | #[derive(Deserialize, Serialize, Type, PartialEq, Debug, Clone)] 41 | pub struct ZVField { 42 | pub int2: u64, 43 | pub string2: String, 44 | } 45 | 46 | #[derive(Deserialize, Serialize, Type, PartialEq, Debug)] 47 | pub struct ZVStruct { 48 | pub string1: String, 49 | pub int1: u64, 50 | pub field: ZVField, 51 | pub dict: std::collections::HashMap, 52 | pub int_array: Vec, 53 | pub string_array: Vec, 54 | } 55 | 56 | pub fn make_zvariant_derive_message( 57 | parts: &MessageParts, 58 | elements: &[ZVStruct], 59 | send_it: bool, 60 | ) -> Option { 61 | let msg = zbus::Message::signal( 62 | parts.object.as_str(), 63 | parts.interface.as_str(), 64 | parts.member.as_str(), 65 | ) 66 | .unwrap() 67 | .build(&elements) 68 | .unwrap(); 69 | if send_it { 70 | let con = zbus::blocking::Connection::session().unwrap(); 71 | con.send(&msg).unwrap(); 72 | None 73 | } else { 74 | Some(msg) 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | mod bench_async_rustbus; 2 | mod bench_dbus_bytestream; 3 | mod bench_dbus_message_parser; 4 | mod bench_dbus_native; 5 | mod bench_dbus_pure; 6 | mod bench_dbusrs; 7 | mod bench_rustbus; 8 | mod bench_zvariant; 9 | 10 | pub use bench_async_rustbus::*; 11 | pub use bench_dbus_bytestream::*; 12 | pub use bench_dbus_message_parser::*; 13 | pub use bench_dbus_native::*; 14 | pub use bench_dbus_pure::*; 15 | pub use bench_dbusrs::*; 16 | pub use bench_rustbus::*; 17 | pub use bench_zvariant::*; 18 | 19 | pub struct MessageParts { 20 | pub interface: String, 21 | pub member: String, 22 | pub object: String, 23 | 24 | pub string1: String, 25 | pub string2: String, 26 | pub int1: u64, 27 | pub int2: u64, 28 | 29 | pub dict: std::collections::HashMap, 30 | pub int_array: Vec, 31 | pub string_array: Vec, 32 | 33 | pub repeat: usize, 34 | } 35 | 36 | /* 37 | // This was meant as a compatibility test but it got cumbersome and uninteresting to maintain 38 | #[cfg(test)] 39 | mod tests { 40 | use rustbus::params::Container; 41 | use rustbus::params::DictMap; 42 | use rustbus::params::Param; 43 | use rustbus::wire::marshal::marshal; 44 | 45 | fn marsh(msg: &rustbus::message_builder::OutMessage, buf: &mut Vec) { 46 | marshal(msg, rustbus::message::ByteOrder::LittleEndian, &[], buf).unwrap(); 47 | } 48 | 49 | struct MessageParts { 50 | interface: String, 51 | member: String, 52 | object: String, 53 | 54 | string1: String, 55 | string2: String, 56 | int1: u64, 57 | int2: u64, 58 | 59 | dict: std::collections::HashMap, 60 | int_array: Vec, 61 | string_array: Vec, 62 | 63 | repeat: usize, 64 | } 65 | 66 | fn make_rustbus_message<'a, 'e>(parts: &'a MessageParts) -> Vec { 67 | let mut params: Vec = Vec::new(); 68 | 69 | let mut dict = DictMap::new(); 70 | for (key, value) in &parts.dict { 71 | dict.insert(key.as_str().into(), value.into()); 72 | } 73 | 74 | use std::convert::TryFrom; 75 | let dict: Param = Container::try_from(dict).unwrap().into(); 76 | 77 | let intarr: Vec = parts 78 | .int_array 79 | .iter() 80 | .copied() 81 | .map(|i| { 82 | let x: Param = i.into(); 83 | x 84 | }) 85 | .collect(); 86 | let sig = intarr[0].sig(); 87 | let intarr = rustbus::params::ArrayRef { 88 | values: &intarr, 89 | element_sig: sig, 90 | }; 91 | let intarray: Param = Param::Container(Container::ArrayRef(intarr)); 92 | 93 | let stringarr: Vec = parts 94 | .string_array 95 | .iter() 96 | .map(|i| { 97 | let x: Param = i.as_str().into(); 98 | x 99 | }) 100 | .collect(); 101 | let sig = stringarr[0].sig(); 102 | let stringarr = rustbus::params::ArrayRef { 103 | values: &stringarr, 104 | element_sig: sig, 105 | }; 106 | let stringarray: Param = Param::Container(Container::ArrayRef(stringarr)); 107 | 108 | for _ in 0..parts.repeat { 109 | params.push(parts.string1.as_str().into()); 110 | params.push(parts.int1.into()); 111 | params.push( 112 | Container::Struct(vec![parts.string2.as_str().into(), parts.int2.into()]).into(), 113 | ); 114 | params.push(dict.clone()); 115 | params.push(intarray.clone()); 116 | params.push(stringarray.clone()); 117 | } 118 | 119 | let mut msg = rustbus::message_builder::MessageBuilder::new() 120 | .signal( 121 | parts.interface.clone(), 122 | parts.member.clone(), 123 | parts.object.clone(), 124 | ) 125 | .build(); 126 | msg.body.push_old_params(¶ms).unwrap(); 127 | msg.serial = Some(1); 128 | 129 | let mut buf = Vec::new(); 130 | marsh(&msg, &mut buf); 131 | buf 132 | } 133 | 134 | fn make_dbus_message_parser_message(parts: &MessageParts) -> Vec { 135 | let mut signal = 136 | dbus_message_parser::Message::signal(&parts.object, &parts.interface, &parts.member); 137 | 138 | let dict_content = parts 139 | .dict 140 | .iter() 141 | .map(|(k, v)| { 142 | dbus_message_parser::Value::DictEntry(Box::new(( 143 | dbus_message_parser::Value::String(k.clone()), 144 | dbus_message_parser::Value::Int32(*v), 145 | ))) 146 | }) 147 | .collect(); 148 | let dict = dbus_message_parser::Value::Array(dict_content, "{si}".into()); 149 | 150 | let array = dbus_message_parser::Value::Array( 151 | parts 152 | .int_array 153 | .iter() 154 | .copied() 155 | .map(|i| dbus_message_parser::Value::Uint64(i)) 156 | .collect(), 157 | "t".to_owned(), 158 | ); 159 | let stringarray = dbus_message_parser::Value::Array( 160 | parts 161 | .string_array 162 | .iter() 163 | .cloned() 164 | .map(|i| dbus_message_parser::Value::String(i)) 165 | .collect(), 166 | "s".to_owned(), 167 | ); 168 | 169 | for _ in 0..parts.repeat { 170 | signal.add_value(dbus_message_parser::Value::Uint64(parts.int1)); 171 | signal.add_value(dbus_message_parser::Value::String(parts.string1.clone())); 172 | signal.add_value(dbus_message_parser::Value::Struct(vec![ 173 | dbus_message_parser::Value::Uint64(parts.int2), 174 | dbus_message_parser::Value::String(parts.string2.clone()), 175 | ])); 176 | signal.add_value(dict.clone()); 177 | signal.add_value(array.clone()); 178 | signal.add_value(stringarray.clone()); 179 | } 180 | let mut buffer = bytes::BytesMut::new(); 181 | signal.encode(&mut buffer).unwrap(); 182 | buffer.to_vec() 183 | } 184 | 185 | fn make_dbus_pure_message(parts: &MessageParts) -> Vec { 186 | let mut header = dbus_pure::proto::MessageHeader { 187 | r#type: dbus_pure::proto::MessageType::Signal { 188 | interface: parts.interface.as_str().into(), 189 | member: parts.member.as_str().into(), 190 | path: dbus_pure::proto::ObjectPath(parts.object.as_str().into()), 191 | }, 192 | flags: dbus_pure::proto::message_flags::NO_REPLY_EXPECTED, 193 | body_len: 0, 194 | serial: 0, 195 | fields: (&[][..]).into(), 196 | }; 197 | 198 | let dict_content: Vec = parts 199 | .dict 200 | .iter() 201 | .map(|(k, v)| dbus_pure::proto::Variant::DictEntry { 202 | key: Box::new(dbus_pure::proto::Variant::String(k.as_str().into())).into(), 203 | value: Box::new(dbus_pure::proto::Variant::I32(*v)).into(), 204 | }) 205 | .collect(); 206 | 207 | let dict = dbus_pure::proto::Variant::Array { 208 | element_signature: dbus_pure::proto::Signature::DictEntry { 209 | key: Box::new(dbus_pure::proto::Signature::String), 210 | value: Box::new(dbus_pure::proto::Signature::I32), 211 | }, 212 | elements: dict_content.into(), 213 | }; 214 | 215 | let array = dbus_pure::proto::Variant::ArrayU64((&parts.int_array).into()); 216 | let strs = parts 217 | .string_array 218 | .iter() 219 | .map(|s| dbus_pure::proto::Variant::String(s.as_str().into())) 220 | .collect::>(); 221 | let strarray = dbus_pure::proto::Variant::Array { 222 | elements: strs.into(), 223 | element_signature: dbus_pure::proto::Signature::String, 224 | }; 225 | 226 | let mut elements = vec![]; 227 | 228 | for _ in 0..parts.repeat { 229 | elements.push(dbus_pure::proto::Variant::U64(parts.int1)); 230 | elements.push(dbus_pure::proto::Variant::String( 231 | parts.string1.as_str().into(), 232 | )); 233 | elements.push(dbus_pure::proto::Variant::Struct { 234 | fields: vec![ 235 | dbus_pure::proto::Variant::U64(0xFFFFFFFFFFFFFFFFu64), 236 | dbus_pure::proto::Variant::String("TesttestTesttest".into()), 237 | ] 238 | .into(), 239 | }); 240 | elements.push(dict.clone()); 241 | elements.push(array.clone()); 242 | elements.push(strarray.clone()); 243 | } 244 | 245 | let body = dbus_pure::proto::Variant::Tuple { 246 | elements: elements.into(), 247 | }; 248 | 249 | let mut buf = Vec::new(); 250 | dbus_pure::proto::serialize_message( 251 | &mut header, 252 | Some(&body), 253 | &mut buf, 254 | dbus_pure::proto::Endianness::Little, 255 | ) 256 | .unwrap(); 257 | buf 258 | } 259 | 260 | fn make_dbus_bytestream_message(parts: &MessageParts) -> Vec { 261 | let mut msg = 262 | dbus_bytestream::message::create_signal(&parts.interface, &parts.member, &parts.object); 263 | 264 | let map: std::collections::HashMap<_, _> = parts 265 | .dict 266 | .iter() 267 | .map(|(k, v)| { 268 | ( 269 | dbus_serialize::types::BasicValue::String(k.clone()), 270 | dbus_serialize::types::Value::BasicValue( 271 | dbus_serialize::types::BasicValue::Int32(*v), 272 | ), 273 | ) 274 | }) 275 | .collect(); 276 | 277 | let int_array: Vec<_> = parts 278 | .int_array 279 | .iter() 280 | .map(|i| { 281 | dbus_serialize::types::Value::BasicValue(dbus_serialize::types::BasicValue::Uint64( 282 | *i, 283 | )) 284 | }) 285 | .collect(); 286 | let string_array: Vec<_> = parts 287 | .string_array 288 | .iter() 289 | .cloned() 290 | .map(|i| { 291 | dbus_serialize::types::Value::BasicValue(dbus_serialize::types::BasicValue::String( 292 | i, 293 | )) 294 | }) 295 | .collect(); 296 | 297 | let strct = dbus_serialize::types::Struct { 298 | objects: vec![ 299 | dbus_serialize::types::Value::BasicValue( 300 | dbus_serialize::types::BasicValue::Uint64(parts.int2), 301 | ), 302 | dbus_serialize::types::Value::BasicValue( 303 | dbus_serialize::types::BasicValue::String(parts.string2.clone()), 304 | ), 305 | ], 306 | signature: dbus_serialize::types::Signature("ts".to_owned()), 307 | }; 308 | 309 | for _ in 0..parts.repeat { 310 | msg = msg.add_arg(&parts.string1); 311 | msg = msg.add_arg(&parts.int1); 312 | msg = msg.add_arg(&strct); 313 | msg = msg.add_arg(&map); 314 | msg = msg.add_arg(&int_array); 315 | msg = msg.add_arg(&string_array); 316 | } 317 | 318 | let mut buf = Vec::new(); 319 | 320 | use dbus_bytestream::marshal::Marshal; 321 | msg.dbus_encode(&mut buf); 322 | buf 323 | } 324 | 325 | fn make_mixed_message() -> MessageParts { 326 | let mut dict = std::collections::HashMap::new(); 327 | dict.insert("A".to_owned(), 1234567i32); 328 | dict.insert("B".to_owned(), 1234567i32); 329 | dict.insert("C".to_owned(), 1234567i32); 330 | dict.insert("D".to_owned(), 1234567i32); 331 | dict.insert("E".to_owned(), 1234567i32); 332 | 333 | MessageParts { 334 | string1: "Testtest".to_owned(), 335 | string2: "TesttestTestest".to_owned(), 336 | int1: 0xFFFFFFFFFFFFFFFFu64, 337 | int2: 0xFFFFFFFFFFFFFFFFu64, 338 | 339 | int_array: vec![ 340 | 0xFFFFFFFFFFFFFFFFu64, 341 | 0xFFFFFFFFFFFFFFFFu64, 342 | 0xFFFFFFFFFFFFFFFFu64, 343 | 0xFFFFFFFFFFFFFFFFu64, 344 | 0xFFFFFFFFFFFFFFFFu64, 345 | 0xFFFFFFFFFFFFFFFFu64, 346 | 0xFFFFFFFFFFFFFFFFu64, 347 | 0xFFFFFFFFFFFFFFFFu64, 348 | 0xFFFFFFFFFFFFFFFFu64, 349 | 0xFFFFFFFFFFFFFFFFu64, 350 | 0xFFFFFFFFFFFFFFFFu64, 351 | 0xFFFFFFFFFFFFFFFFu64, 352 | 0xFFFFFFFFFFFFFFFFu64, 353 | 0xFFFFFFFFFFFFFFFFu64, 354 | 0xFFFFFFFFFFFFFFFFu64, 355 | ], 356 | string_array: vec!["".into()], 357 | dict, 358 | interface: "io.killing.spark".into(), 359 | member: "TestSignal".into(), 360 | object: "/io/killing/spark".into(), 361 | repeat: 10, 362 | } 363 | } 364 | fn make_big_array_message() -> MessageParts { 365 | let mut dict = std::collections::HashMap::new(); 366 | dict.insert("A".to_owned(), 1234567i32); 367 | let mut int_array = Vec::new(); 368 | int_array.resize(1024, 0u64); 369 | 370 | MessageParts { 371 | string1: "Testtest".to_owned(), 372 | string2: "TesttestTestest".to_owned(), 373 | int1: 0xFFFFFFFFFFFFFFFFu64, 374 | int2: 0xFFFFFFFFFFFFFFFFu64, 375 | 376 | int_array, 377 | string_array: vec!["".into()], 378 | dict, 379 | interface: "io.killing.spark".into(), 380 | member: "TestSignal".into(), 381 | object: "/io/killing/spark".into(), 382 | repeat: 1, 383 | } 384 | } 385 | fn make_big_string_array_message() -> MessageParts { 386 | let mut dict = std::collections::HashMap::new(); 387 | dict.insert("A".to_owned(), 1234567i32); 388 | let mut string_array = Vec::new(); 389 | for idx in 0..1024 { 390 | string_array.push(format!( 391 | "{}{}{}{}{}{}{}{}{}{}{}{}", 392 | idx, idx, idx, idx, idx, idx, idx, idx, idx, idx, idx, idx 393 | )) 394 | } 395 | 396 | MessageParts { 397 | string1: "Testtest".to_owned(), 398 | string2: "TesttestTestest".to_owned(), 399 | int1: 0xFFFFFFFFFFFFFFFFu64, 400 | int2: 0xFFFFFFFFFFFFFFFFu64, 401 | 402 | string_array, 403 | int_array: vec![0], 404 | dict, 405 | interface: "io.killing.spark".into(), 406 | member: "TestSignal".into(), 407 | object: "/io/killing/spark".into(), 408 | repeat: 1, 409 | } 410 | } 411 | 412 | fn make_and_compare(parts: &MessageParts) { 413 | let rb = make_rustbus_message(parts); 414 | let bs = make_dbus_bytestream_message(parts); 415 | let mp = make_dbus_message_parser_message(parts); 416 | let dp = make_dbus_pure_message(parts); 417 | let ab = make_async_rustbus_message(parts); 418 | 419 | assert_eq!(rb, bs); 420 | assert_eq!(rb, mp); 421 | assert_eq!(rb, dp); 422 | assert_eq!(rb, ab); 423 | } 424 | 425 | #[test] 426 | fn test_marshalling() { 427 | let mixed = make_mixed_message(); 428 | make_and_compare(&mixed); 429 | let array = make_big_string_array_message(); 430 | make_and_compare(&array); 431 | let array = make_big_array_message(); 432 | make_and_compare(&array); 433 | } 434 | } 435 | */ 436 | -------------------------------------------------------------------------------- /tools/make_table.py: -------------------------------------------------------------------------------- 1 | #! /bin/python3 2 | 3 | import os 4 | 5 | stream = os.popen('bash -c "cargo bench | grep time"') 6 | #stream = os.popen('bash -c "cargo bench rustbus | grep time"') 7 | output = stream.read() 8 | 9 | table_lines = [] 10 | results = {} 11 | benches = [] 12 | 13 | def filter_empty(var): 14 | return len(var) != 0 15 | 16 | lines = output.split("\n") 17 | for line in lines: 18 | if len(line) == 0: 19 | continue 20 | 21 | words = line.split(" ") 22 | words = list(filter(filter_empty, words)) 23 | 24 | name_split = words[0].split("_") 25 | benchname = name_split[0] 26 | libname = "_".join(name_split[1:]) 27 | timings = " ".join(words[2:]) 28 | 29 | if not benchname in benches: 30 | benches.append(benchname) 31 | 32 | if not libname in results: 33 | results[libname] = {} 34 | results[libname][benchname] = timings 35 | 36 | for libname in results: 37 | print(libname) 38 | line = "|" + libname + "|" 39 | for bench in benches: 40 | libbenches = results[libname] 41 | if bench in libbenches: 42 | line += libbenches[bench] 43 | line += "|" 44 | 45 | table_lines.append(line) 46 | 47 | header = "|Library|" 48 | for bench in benches: 49 | header += bench + "|" 50 | print(header) 51 | header = "|-|" 52 | for bench in benches: 53 | header += "-|" 54 | print(header) 55 | 56 | for line in table_lines: 57 | print(line) --------------------------------------------------------------------------------