English | 中文
prust is a protobuf implementation for Rust. prust generates simple
and high performance code from proto2 or proto3 files.
Compare to other implementations
- Highly optimized code,
prustcalculates everything when generating, so less calculating at runtime - Zero dependency,
prustdo not need that, no extra bloat grpcis supported by default (with tonic)- Less build time, since we don't need to expand proc macros
groupis not supported, since it is deprecated too.- No more
protoc,prusthandles parsing itself.
prust generates structs and implements Deserialize and Serialize,
so the generated file is a little bit larger than prost, but still
smaller than the prost's expanded code.
| File | Crate | Lines | Sizes |
|---|---|---|---|
| proto2/data_types.proto | prust | 423 | 18054 |
| prost | 165 | 6571 | |
| proto3/data_types.proto | prust | 383 | 17540 |
| prost | 165 | 6603 |
With our workload which covers lots of cases, prust works very well.
The decoding performance almost catch up quick-protobuf, which uses Cow to
improve performance(while prust don't ). And the encoding performance is around 2x
faster than prost. With different workload, prust performance will be different
too, users must verify it if you want to switch to prust.
Decoding 6000 times
prost: 964.93 op/s, 377.62 M/s, 6.22s
quick: 1426.05 op/s, 558.08 M/s, 4.21s
prust: 1235.72 op/s, 483.60 M/s, 4.86s
Encoding 6000 times
prost: 1577.11 op/s, 617.20 M/s, 3.80s
quick: 1956.55 op/s, 765.69 M/s, 3.07s
prust: 3375.67 op/s, 1321.06 M/s, 1.78s
NOTE: prost seems leak memory, it takes 2.1G to finish our test, while others takes only 1.1M.
- Add
prustandprust-buildto your Cargo.toml
[build-dependencies]
prust-build = 0.1
[dependencies]
prust = 0.1- add compile functions to
build.rs
fn main() {
prust_build::Config::default()
.compile(&["/path/to/include"], &["/path/to/your.proto"])
.unwrap();
}- Include whatever the prust generated
Note: by default, generated filename is package field in *.proto, if it is not specified,
prust will use the proto's filename.
mod proto {
include!(concat!(env!("OUT_DIR"), "/package.rs"));
}
use proto::Data;
use prust::{Deserialize, Serialize};
fn main() {
let data = Data::decode(input).unwrap();
let len = data.encoded_len();
let buf = vec![0; len];
data.encode(&mut buf).unwrap();
}Grpc is supported and the generated file works with tonic,
and the generated file is just like tonic does, so switching from tonic
to prust is very easy.
- enable
tonicfeature ofprust - fix the use path in your rust file
- running your program or test
A running example can be found in the conformance/tests/services/health.rs
implement default value for map's key and value, which will reduce encoded size and resource usageit hurt the performance a little bit.- it seems that access data via
*const u8is better thanslice[pos], more test needed. - support Well-Known Types
prustcannot handle recursive types