use serde::Serialize;
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Serialize)]
pub struct ProfileSummary {
pub(crate) network_depth: usize,
pub(crate) total_gates: usize,
pub(crate) network_size: usize,
pub(crate) preprocess_weight: usize,
pub(crate) associated_weight: usize,
}
const ONLINE_WEIGHT: usize = 64;
const NETWORK_ROUND_TIME: usize = 1 << 15;
const NETWORK_BYTE_DURATION: usize = 4;
const GATE_TIME: usize = 4;
impl ProfileSummary {
pub fn weight(&self) -> usize {
ONLINE_WEIGHT
* (self.network_depth * NETWORK_ROUND_TIME
+ self.total_gates * GATE_TIME
+ self.network_size * NETWORK_BYTE_DURATION)
+ self.preprocess_weight
+ self.associated_weight
}
pub fn weight_js() -> String {
let network_depth_weight = ProfileSummary {
network_depth: 1,
..Default::default()
}
.weight();
let gate_weight = ProfileSummary {
total_gates: 1,
..Default::default()
}
.weight();
let network_size_weight = ProfileSummary {
network_size: 1,
..Default::default()
}
.weight();
format!(
"function weight(x){{ return {} * x.network_depth + {} * x.total_gates + {} * x.network_size + x.preprocess_weight + x.associated_weight;}}",
network_depth_weight,
gate_weight,
network_size_weight)
}
pub fn new(
network_depth: usize,
total_gates: usize,
network_size: usize,
preprocess_weight: usize,
associated_weight: usize,
) -> Self {
Self {
network_depth,
total_gates,
network_size,
preprocess_weight,
associated_weight,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use boa_engine::{Context, Source};
#[test]
fn serialized_schema_matches_profiling_ui_fixture() {
let expected = serde_json::json!({
"network_depth": 1,
"total_gates": 2,
"network_size": 3,
"preprocess_weight": 4,
"associated_weight": 5,
});
let actual = serde_json::to_value(ProfileSummary::new(1, 2, 3, 4, 5))
.expect("ProfileSummary should serialize to JSON");
assert_eq!(actual, expected);
}
#[test]
fn test_weight_javascript() {
fn test_weight_js(profile_summary: ProfileSummary) {
let weight = profile_summary.weight();
let js_code = format!(
"{}\nweight({})",
ProfileSummary::weight_js(),
serde_json::to_string(&profile_summary).expect("Serialization failed.")
);
let mut context = Context::default();
let result = context
.eval(Source::from_bytes(&js_code))
.expect("Eval failed.");
assert_eq!(result.as_number().unwrap() as usize, weight);
}
test_weight_js(ProfileSummary::new(5, 0, 0, 0, 0));
test_weight_js(ProfileSummary::new(0, 9, 0, 0, 0));
test_weight_js(ProfileSummary::new(0, 0, 13, 0, 0));
test_weight_js(ProfileSummary::new(0, 0, 0, 17, 0));
test_weight_js(ProfileSummary::new(0, 0, 0, 0, 19));
test_weight_js(ProfileSummary::new(1, 2, 3, 4, 5));
test_weight_js(ProfileSummary::new(4, 3, 2, 1, 7));
}
}