Skip to content

Commit 6f49428

Browse files
authored
Merge pull request #520 from egraphs-good/oflatt-faster-serialize
Faster Serialization and Benchmark Serialization
2 parents aff2014 + 72f1f92 commit 6f49428

File tree

2 files changed

+52
-45
lines changed

2 files changed

+52
-45
lines changed

benches/example_benchmarks.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ fn run_example(filename: &str, program: &str, no_messages: bool) {
99
egraph
1010
.parse_and_run_program(Some(filename.to_owned()), program)
1111
.unwrap();
12+
// test performance of serialization as well
13+
let _ = egraph.serialize(egglog::SerializeConfig::default());
1214
}
1315

1416
pub fn criterion_benchmark(c: &mut Criterion) {

src/serialize.rs

Lines changed: 50 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ pub struct SerializeConfig {
1313
pub root_eclasses: Vec<(ArcSort, Value)>,
1414
}
1515

16+
struct Serializer<'a> {
17+
extractor: Extractor<'a>,
18+
termdag: TermDag,
19+
node_ids: NodeIDs,
20+
result: egraph_serialize::EGraph,
21+
}
22+
1623
/// Default is used for exporting JSON and will output all nodes.
1724
impl Default for SerializeConfig {
1825
fn default() -> Self {
@@ -124,7 +131,7 @@ impl EGraph {
124131
// Note that this is only for e-classes, primitives have e-classes equal to their node ID
125132
// This is for when we need to find what node ID to use for an edge to an e-class, we can rotate them evenly
126133
// amoung all possible options.
127-
let mut node_ids: NodeIDs = all_calls.iter().fold(
134+
let node_ids: NodeIDs = all_calls.iter().fold(
128135
HashMap::default(),
129136
|mut acc, (func, _input, _output, class_id, node_id)| {
130137
if func.schema.output.is_eq_sort() {
@@ -136,11 +143,18 @@ impl EGraph {
136143
},
137144
);
138145

139-
let mut egraph = egraph_serialize::EGraph::default();
146+
let mut termdag = TermDag::default();
147+
148+
let mut serializer = Serializer {
149+
extractor: Extractor::new(self, &mut termdag),
150+
node_ids,
151+
result: egraph_serialize::EGraph::default(),
152+
termdag,
153+
};
154+
140155
for (func, input, output, class_id, node_id) in all_calls {
141156
self.serialize_value(
142-
&mut egraph,
143-
&mut node_ids,
157+
&mut serializer,
144158
&func.schema.output,
145159
&output.value,
146160
&class_id,
@@ -151,16 +165,10 @@ impl EGraph {
151165
.iter()
152166
.zip(&func.schema.input)
153167
.map(|(v, sort)| {
154-
self.serialize_value(
155-
&mut egraph,
156-
&mut node_ids,
157-
sort,
158-
v,
159-
&self.value_to_class_id(sort, v),
160-
)
168+
self.serialize_value(&mut serializer, sort, v, &self.value_to_class_id(sort, v))
161169
})
162170
.collect();
163-
egraph.nodes.insert(
171+
serializer.result.nodes.insert(
164172
node_id,
165173
egraph_serialize::Node {
166174
op: func.decl.name.to_string(),
@@ -172,13 +180,13 @@ impl EGraph {
172180
);
173181
}
174182

175-
egraph.root_eclasses = config
183+
serializer.result.root_eclasses = config
176184
.root_eclasses
177185
.iter()
178186
.map(|(sort, v)| self.value_to_class_id(sort, v))
179187
.collect();
180188

181-
egraph
189+
serializer.result
182190
}
183191

184192
/// Gets the serialized class ID for a value.
@@ -264,29 +272,31 @@ impl EGraph {
264272
/// When this is called on an input of a node, we only use the node ID to know which node to point to.
265273
fn serialize_value(
266274
&self,
267-
egraph: &mut egraph_serialize::EGraph,
268-
node_ids: &mut NodeIDs,
275+
serializer: &mut Serializer,
269276
sort: &ArcSort,
270277
value: &Value,
271278
class_id: &egraph_serialize::ClassId,
272279
) -> egraph_serialize::NodeId {
273280
let node_id = if sort.is_eq_sort() {
274-
let node_ids = node_ids.entry(class_id.clone()).or_insert_with(|| {
275-
// If we don't find node IDs for this class, it means that all nodes for it were omitted due to size constraints
276-
// In this case, add a dummy node in this class to represent the missing nodes
277-
let node_id = self.to_node_id(Some(sort), SerializedNode::Dummy(*value));
278-
egraph.nodes.insert(
279-
node_id.clone(),
280-
egraph_serialize::Node {
281-
op: "[...]".to_string(),
282-
eclass: class_id.clone(),
283-
cost: NotNan::new(f64::INFINITY).unwrap(),
284-
children: vec![],
285-
subsumed: false,
286-
},
287-
);
288-
VecDeque::from(vec![node_id])
289-
});
281+
let node_ids = serializer
282+
.node_ids
283+
.entry(class_id.clone())
284+
.or_insert_with(|| {
285+
// If we don't find node IDs for this class, it means that all nodes for it were omitted due to size constraints
286+
// In this case, add a dummy node in this class to represent the missing nodes
287+
let node_id = self.to_node_id(Some(sort), SerializedNode::Dummy(*value));
288+
serializer.result.nodes.insert(
289+
node_id.clone(),
290+
egraph_serialize::Node {
291+
op: "[...]".to_string(),
292+
eclass: class_id.clone(),
293+
cost: NotNan::new(f64::INFINITY).unwrap(),
294+
children: vec![],
295+
subsumed: false,
296+
},
297+
);
298+
VecDeque::from(vec![node_id])
299+
});
290300
node_ids.rotate_left(1);
291301
node_ids.front().unwrap().clone()
292302
} else {
@@ -298,28 +308,23 @@ impl EGraph {
298308
.inner_values(value)
299309
.into_iter()
300310
.map(|(s, v)| {
301-
self.serialize_value(
302-
egraph,
303-
node_ids,
304-
&s,
305-
&v,
306-
&self.value_to_class_id(&s, &v),
307-
)
311+
self.serialize_value(serializer, &s, &v, &self.value_to_class_id(&s, &v))
308312
})
309313
.collect();
310314
// If this is a container sort, use the name, otherwise use the value
311315
let op = if sort.is_container_sort() {
312316
sort.serialized_name(value).to_string()
313317
} else {
314-
let mut termdag = TermDag::default();
315-
let extractor = Extractor::new(self, &mut termdag);
316318
let (_, term) = sort
317-
.extract_term(self, *value, &extractor, &mut termdag)
319+
.extract_term(self, *value, &serializer.extractor, &mut serializer.termdag)
318320
.expect("Extraction should be successful since extractor has been fully initialized");
319321

320-
termdag.term_to_expr(&term, Span::Panic).to_string()
322+
serializer
323+
.termdag
324+
.term_to_expr(&term, Span::Panic)
325+
.to_string()
321326
};
322-
egraph.nodes.insert(
327+
serializer.result.nodes.insert(
323328
node_id.clone(),
324329
egraph_serialize::Node {
325330
op,
@@ -332,7 +337,7 @@ impl EGraph {
332337
};
333338
node_id
334339
};
335-
egraph.class_data.insert(
340+
serializer.result.class_data.insert(
336341
class_id.clone(),
337342
egraph_serialize::ClassData {
338343
typ: Some(sort.name().to_string()),

0 commit comments

Comments
 (0)