mirror of
https://github.com/speice-io/marketdata-shootout
synced 2024-11-23 16:38:22 -05:00
Output analysis results
Flatbuffers and SBE were much closer than expected
This commit is contained in:
parent
7ab549f489
commit
6628b5b6cd
62
src/main.rs
62
src/main.rs
@ -50,29 +50,40 @@ fn main() {
|
|||||||
file.read_to_end(&mut buf)
|
file.read_to_end(&mut buf)
|
||||||
.expect(&format!("Unable to read file={}", path.display()));
|
.expect(&format!("Unable to read file={}", path.display()));
|
||||||
|
|
||||||
let _capnp_unpacked = run_analysis(
|
let capnp_unpacked = run_analysis(
|
||||||
&buf,
|
&buf,
|
||||||
&mut capnp_runner::CapnpWriter::new(false),
|
&mut capnp_runner::CapnpWriter::new(false),
|
||||||
&mut capnp_runner::CapnpReader::new(false),
|
&mut capnp_runner::CapnpReader::new(false),
|
||||||
);
|
);
|
||||||
|
|
||||||
let _capnp_packed = run_analysis(
|
println!("Cap'n Proto Unpacked:\n{}\n", capnp_unpacked.timing_stats());
|
||||||
|
|
||||||
|
let capnp_packed = run_analysis(
|
||||||
&buf,
|
&buf,
|
||||||
&mut capnp_runner::CapnpWriter::new(true),
|
&mut capnp_runner::CapnpWriter::new(true),
|
||||||
&mut capnp_runner::CapnpReader::new(true),
|
&mut capnp_runner::CapnpReader::new(true),
|
||||||
);
|
);
|
||||||
|
|
||||||
let _flatbuffers = run_analysis(
|
assert_eq!(capnp_unpacked.summary_stats, capnp_packed.summary_stats);
|
||||||
|
println!("Cap'n Proto Packed:\n{}\n", capnp_packed.timing_stats());
|
||||||
|
|
||||||
|
let flatbuffers = run_analysis(
|
||||||
&buf,
|
&buf,
|
||||||
&mut flatbuffers_runner::FlatbuffersWriter::new(),
|
&mut flatbuffers_runner::FlatbuffersWriter::new(),
|
||||||
&mut flatbuffers_runner::FlatbuffersReader::new(),
|
&mut flatbuffers_runner::FlatbuffersReader::new(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let _sbe = run_analysis(
|
assert_eq!(capnp_packed.summary_stats, flatbuffers.summary_stats);
|
||||||
|
println!("Flatbuffers:\n{}\n", flatbuffers.timing_stats());
|
||||||
|
|
||||||
|
let sbe = run_analysis(
|
||||||
&buf,
|
&buf,
|
||||||
&mut sbe_runner::SBEWriter::new(),
|
&mut sbe_runner::SBEWriter::new(),
|
||||||
&mut sbe_runner::SBEReader::new(),
|
&mut sbe_runner::SBEReader::new(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
assert_eq!(flatbuffers.summary_stats, sbe.summary_stats);
|
||||||
|
println!("SBE:\n{}\n", sbe.timing_stats());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
@ -186,6 +197,33 @@ struct RunAnalysis {
|
|||||||
buf_len: usize,
|
buf_len: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl RunAnalysis {
|
||||||
|
fn timing_stats(&self) -> String {
|
||||||
|
format!(
|
||||||
|
concat!(
|
||||||
|
" serialize_50={}ns\n",
|
||||||
|
" serialize_99={}ns\n",
|
||||||
|
" serialize_999={}ns\n",
|
||||||
|
" deserialize_50={}ns\n",
|
||||||
|
" deserialize_99={}ns\n",
|
||||||
|
" deserialize_999={}ns\n",
|
||||||
|
" serialize_total={}ns\n",
|
||||||
|
" deserialize_total={}ns\n",
|
||||||
|
" write_len={}b"
|
||||||
|
),
|
||||||
|
self.serialize_hist.value_at_quantile(0.5),
|
||||||
|
self.serialize_hist.value_at_quantile(0.99),
|
||||||
|
self.serialize_hist.value_at_quantile(0.999),
|
||||||
|
self.deserialize_hist.value_at_quantile(0.5),
|
||||||
|
self.deserialize_hist.value_at_quantile(0.99),
|
||||||
|
self.deserialize_hist.value_at_quantile(0.999),
|
||||||
|
self.serialize_total_nanos,
|
||||||
|
self.deserialize_total_nanos,
|
||||||
|
self.buf_len
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn run_analysis<S, D>(iex_data: &Vec<u8>, serializer: &mut S, deserializer: &mut D) -> RunAnalysis
|
fn run_analysis<S, D>(iex_data: &Vec<u8>, serializer: &mut S, deserializer: &mut D) -> RunAnalysis
|
||||||
where
|
where
|
||||||
S: RunnerSerialize,
|
S: RunnerSerialize,
|
||||||
@ -201,21 +239,32 @@ where
|
|||||||
let mut serialize_msgs = 0;
|
let mut serialize_msgs = 0;
|
||||||
|
|
||||||
for iex_payload in iex_parser {
|
for iex_payload in iex_parser {
|
||||||
|
let output_len_start = output_buf.len();
|
||||||
let serialize_start = Instant::now();
|
let serialize_start = Instant::now();
|
||||||
|
|
||||||
serializer.serialize(&iex_payload, &mut output_buf);
|
serializer.serialize(&iex_payload, &mut output_buf);
|
||||||
|
|
||||||
let serialize_end = Instant::now().duration_since(serialize_start).as_nanos();
|
let serialize_end = Instant::now().duration_since(serialize_start).as_nanos();
|
||||||
|
|
||||||
serialize_hist.record(serialize_end as u64).unwrap();
|
serialize_hist.record(serialize_end as u64).unwrap();
|
||||||
serialize_nanos_total += serialize_end;
|
serialize_nanos_total += serialize_end;
|
||||||
|
|
||||||
|
// If the IEX payload is made up of messages we don't care about
|
||||||
|
// (a multi-message containing nothing but SystemEvent for example),
|
||||||
|
// Cap'n Proto doesn't write anything into the output buffer.
|
||||||
|
// As such, only increment `serialize_msgs` when something was written
|
||||||
|
// so that the read/write counts line up.
|
||||||
|
let write_size = output_buf.len() - output_len_start;
|
||||||
|
if write_size != 0 {
|
||||||
serialize_msgs += 1;
|
serialize_msgs += 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
let output_len = output_buf.len();
|
let output_len = output_buf.len();
|
||||||
|
|
||||||
let mut read_buf = StreamVec::new(output_buf);
|
let mut read_buf = StreamVec::new(output_buf);
|
||||||
let mut summarizer = Summarizer::default();
|
let mut summarizer = Summarizer::default();
|
||||||
let mut deserialize_hist = Histogram::<u64>::new(2).unwrap();
|
let mut deserialize_hist = Histogram::<u64>::new(2).unwrap();
|
||||||
let mut parsed_msgs: u64 = 0;
|
let mut parsed_msgs = 0usize;
|
||||||
let mut deserialize_nanos_total = 0u128;
|
let mut deserialize_nanos_total = 0u128;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
@ -234,7 +283,8 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dbg!(serialize_msgs, parsed_msgs);
|
assert_eq!(serialize_msgs, parsed_msgs);
|
||||||
|
//dbg!(serialize_all);
|
||||||
|
|
||||||
RunAnalysis {
|
RunAnalysis {
|
||||||
serialize_hist,
|
serialize_hist,
|
||||||
|
@ -213,7 +213,6 @@ pub mod multi_message {
|
|||||||
impl Pipeline {}
|
impl Pipeline {}
|
||||||
mod _private {
|
mod _private {
|
||||||
use capnp::private::layout;
|
use capnp::private::layout;
|
||||||
|
|
||||||
pub const STRUCT_SIZE: layout::StructSize = layout::StructSize {
|
pub const STRUCT_SIZE: layout::StructSize = layout::StructSize {
|
||||||
data: 1,
|
data: 1,
|
||||||
pointers: 1,
|
pointers: 1,
|
||||||
@ -508,7 +507,6 @@ pub mod message {
|
|||||||
impl Pipeline {}
|
impl Pipeline {}
|
||||||
mod _private {
|
mod _private {
|
||||||
use capnp::private::layout;
|
use capnp::private::layout;
|
||||||
|
|
||||||
pub const STRUCT_SIZE: layout::StructSize = layout::StructSize {
|
pub const STRUCT_SIZE: layout::StructSize = layout::StructSize {
|
||||||
data: 2,
|
data: 2,
|
||||||
pointers: 2,
|
pointers: 2,
|
||||||
@ -703,7 +701,6 @@ pub mod trade {
|
|||||||
impl Pipeline {}
|
impl Pipeline {}
|
||||||
mod _private {
|
mod _private {
|
||||||
use capnp::private::layout;
|
use capnp::private::layout;
|
||||||
|
|
||||||
pub const STRUCT_SIZE: layout::StructSize = layout::StructSize {
|
pub const STRUCT_SIZE: layout::StructSize = layout::StructSize {
|
||||||
data: 2,
|
data: 2,
|
||||||
pointers: 0,
|
pointers: 0,
|
||||||
@ -914,7 +911,6 @@ pub mod level_update {
|
|||||||
impl Pipeline {}
|
impl Pipeline {}
|
||||||
mod _private {
|
mod _private {
|
||||||
use capnp::private::layout;
|
use capnp::private::layout;
|
||||||
|
|
||||||
pub const STRUCT_SIZE: layout::StructSize = layout::StructSize {
|
pub const STRUCT_SIZE: layout::StructSize = layout::StructSize {
|
||||||
data: 2,
|
data: 2,
|
||||||
pointers: 0,
|
pointers: 0,
|
||||||
|
@ -1,20 +1,19 @@
|
|||||||
// automatically generated by the FlatBuffers compiler, do not modify
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
extern crate flatbuffers;
|
|
||||||
|
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
|
extern crate flatbuffers;
|
||||||
use self::flatbuffers::EndianScalar;
|
use self::flatbuffers::EndianScalar;
|
||||||
|
|
||||||
#[allow(unused_imports, dead_code)]
|
#[allow(unused_imports, dead_code)]
|
||||||
pub mod md_shootout {
|
pub mod md_shootout {
|
||||||
|
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
use self::flatbuffers::EndianScalar;
|
|
||||||
|
|
||||||
extern crate flatbuffers;
|
extern crate flatbuffers;
|
||||||
|
use self::flatbuffers::EndianScalar;
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
|
Loading…
Reference in New Issue
Block a user