summaryrefslogtreecommitdiffstats
path: root/third_party/rust/petgraph/benches
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/petgraph/benches')
-rw-r--r--third_party/rust/petgraph/benches/common/factories.rs250
-rw-r--r--third_party/rust/petgraph/benches/common/mod.rs2
-rw-r--r--third_party/rust/petgraph/benches/dijkstra.rs32
-rw-r--r--third_party/rust/petgraph/benches/iso.rs52
-rw-r--r--third_party/rust/petgraph/benches/matrix_graph.rs235
-rw-r--r--third_party/rust/petgraph/benches/ograph.rs52
-rw-r--r--third_party/rust/petgraph/benches/stable_graph.rs85
-rw-r--r--third_party/rust/petgraph/benches/unionfind.rs156
8 files changed, 864 insertions, 0 deletions
diff --git a/third_party/rust/petgraph/benches/common/factories.rs b/third_party/rust/petgraph/benches/common/factories.rs
new file mode 100644
index 0000000000..8ab8068629
--- /dev/null
+++ b/third_party/rust/petgraph/benches/common/factories.rs
@@ -0,0 +1,250 @@
+use std::marker::PhantomData;
+
+use petgraph::data::Build;
+use petgraph::prelude::*;
+use petgraph::visit::NodeIndexable;
+
+use petgraph::EdgeType;
+
+/// Petersen A and B are isomorphic
+///
+/// http://www.dharwadker.org/tevet/isomorphism/
+const PETERSEN_A: &str = "
+ 0 1 0 0 1 0 1 0 0 0
+ 1 0 1 0 0 0 0 1 0 0
+ 0 1 0 1 0 0 0 0 1 0
+ 0 0 1 0 1 0 0 0 0 1
+ 1 0 0 1 0 1 0 0 0 0
+ 0 0 0 0 1 0 0 1 1 0
+ 1 0 0 0 0 0 0 0 1 1
+ 0 1 0 0 0 1 0 0 0 1
+ 0 0 1 0 0 1 1 0 0 0
+ 0 0 0 1 0 0 1 1 0 0
+";
+
+const PETERSEN_B: &str = "
+ 0 0 0 1 0 1 0 0 0 1
+ 0 0 0 1 1 0 1 0 0 0
+ 0 0 0 0 0 0 1 1 0 1
+ 1 1 0 0 0 0 0 1 0 0
+ 0 1 0 0 0 0 0 0 1 1
+ 1 0 0 0 0 0 1 0 1 0
+ 0 1 1 0 0 1 0 0 0 0
+ 0 0 1 1 0 0 0 0 1 0
+ 0 0 0 0 1 1 0 1 0 0
+ 1 0 1 0 1 0 0 0 0 0
+";
+
+/// An almost full set, isomorphic
+const FULL_A: &str = "
+ 1 1 1 1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1 1 1 1
+ 1 1 1 1 0 1 1 1 0 1
+ 1 1 1 1 1 1 1 1 1 1
+";
+
+const FULL_B: &str = "
+ 1 1 1 1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1 1 1 1
+ 1 1 0 1 1 1 0 1 1 1
+ 1 1 1 1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1 1 1 1
+";
+
+/// Praust A and B are not isomorphic
+const PRAUST_A: &str = "
+ 0 1 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
+ 1 0 1 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0
+ 1 1 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0
+ 1 1 1 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0
+ 1 0 0 0 0 1 1 1 0 0 0 0 1 0 0 0 0 0 0 0
+ 0 1 0 0 1 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0
+ 0 0 1 0 1 1 0 1 0 0 0 0 0 0 1 0 0 0 0 0
+ 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0
+ 1 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0 0 0
+ 0 1 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 1 0 0
+ 0 0 1 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 1 0
+ 0 0 0 1 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1
+ 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 1 0 1 0 0
+ 0 0 0 0 0 1 0 0 0 0 0 0 1 0 1 1 1 0 0 0
+ 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 1 0 0 0 1
+ 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 0 0 0 1 0
+ 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 1 1
+ 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 1 1
+ 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 0 1
+ 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 1 1 0
+";
+
+const PRAUST_B: &str = "
+ 0 1 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
+ 1 0 1 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0
+ 1 1 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0
+ 1 1 1 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0
+ 1 0 0 0 0 1 1 1 0 0 0 0 1 0 0 0 0 0 0 0
+ 0 1 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1
+ 0 0 1 0 1 1 0 1 0 0 0 0 0 0 1 0 0 0 0 0
+ 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0
+ 1 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0 0 0
+ 0 1 0 0 0 0 0 0 1 0 1 1 0 1 0 0 0 0 0 0
+ 0 0 1 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 1 0
+ 0 0 0 1 0 0 0 0 1 1 1 0 0 0 0 1 0 0 0 0
+ 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 0 0 1 0 1
+ 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 1 0 1 0
+ 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 1 0 1
+ 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 1 0 1 0
+ 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 0 1 1 0
+ 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 0 1 0 0 1
+ 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 1 0 0 1
+ 0 0 0 0 0 1 0 0 0 0 0 0 1 0 1 0 0 1 1 0
+";
+
+const BIGGER: &str = "
+ 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 1 0 1 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 1 0 1 0 1 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0
+ 0 1 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 1 0 1 0 0
+ 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 1 1 1 0 0 0
+ 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 1 0 0 0 1
+ 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 0 0 0 1 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 1 0 1 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 1 1
+ 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 1 1 0 1 1 1 0 0 0 0 0 1 0 0 1 0 0 0 1 0 1 1
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 0 1
+ 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 1 1 0
+ 0 1 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
+ 1 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 1 0 1 0 1 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 1 0 1 1 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 1 1 0 1 0 0 0 0 0 0 1 0 0 0 0 0
+ 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0
+ 1 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0 0 0
+ 0 1 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 1 0 0
+ 0 0 1 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 1 0
+ 0 0 0 1 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1
+ 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 1 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 1 0 1 0 0
+ 0 0 0 0 0 1 0 0 0 0 0 0 1 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 1 1 1 0 0 0
+ 0 1 0 0 0 0 1 0 0 0 0 0 1 1 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 1 0 0 0 1
+ 0 1 0 0 0 0 0 1 0 0 0 0 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 0 0 0 1 0
+ 0 1 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 1 1
+ 0 1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 1 1
+ 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 0 1
+ 0 1 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 1 1 0
+";
+
+/// Parse a text adjacency matrix format into a directed graph
+fn parse_graph<Ty, G>(s: &str) -> G
+where
+ Ty: EdgeType,
+ G: Default + Build<NodeWeight = (), EdgeWeight = ()> + NodeIndexable,
+{
+ let mut g: G = Default::default();
+ let s = s.trim();
+ let lines = s.lines().filter(|l| !l.is_empty());
+ for (row, line) in lines.enumerate() {
+ for (col, word) in line.split(' ').filter(|s| !s.is_empty()).enumerate() {
+ let has_edge = word.parse::<i32>().unwrap();
+ assert!(has_edge == 0 || has_edge == 1);
+ if has_edge == 0 {
+ continue;
+ }
+ while col >= g.node_count() || row >= g.node_count() {
+ g.add_node(());
+ }
+ let a = g.from_index(row);
+ let b = g.from_index(col);
+ g.update_edge(a, b, ());
+ }
+ }
+ g
+}
+
+pub struct GraphFactory<Ty, G = Graph<(), (), Ty>> {
+ ty: PhantomData<Ty>,
+ g: PhantomData<G>,
+}
+
+impl<Ty, G> GraphFactory<Ty, G>
+where
+ Ty: EdgeType,
+ G: Default + Build<NodeWeight = (), EdgeWeight = ()> + NodeIndexable,
+{
+ fn new() -> Self {
+ GraphFactory {
+ ty: PhantomData,
+ g: PhantomData,
+ }
+ }
+
+ pub fn petersen_a(self) -> G {
+ parse_graph::<Ty, _>(PETERSEN_A)
+ }
+
+ pub fn petersen_b(self) -> G {
+ parse_graph::<Ty, _>(PETERSEN_B)
+ }
+
+ pub fn full_a(self) -> G {
+ parse_graph::<Ty, _>(FULL_A)
+ }
+
+ pub fn full_b(self) -> G {
+ parse_graph::<Ty, _>(FULL_B)
+ }
+
+ pub fn praust_a(self) -> G {
+ parse_graph::<Ty, _>(PRAUST_A)
+ }
+
+ pub fn praust_b(self) -> G {
+ parse_graph::<Ty, _>(PRAUST_B)
+ }
+
+ pub fn bigger(self) -> G {
+ parse_graph::<Ty, _>(BIGGER)
+ }
+}
+
+pub fn graph<Ty: EdgeType>() -> GraphFactory<Ty, Graph<(), (), Ty>> {
+ GraphFactory::new()
+}
+
+pub fn ungraph() -> GraphFactory<Undirected, Graph<(), (), Undirected>> {
+ graph()
+}
+
+pub fn digraph() -> GraphFactory<Directed, Graph<(), (), Directed>> {
+ graph()
+}
+
+pub fn stable_graph<Ty: EdgeType>() -> GraphFactory<Ty, StableGraph<(), (), Ty>> {
+ GraphFactory::new()
+}
+
+pub fn stable_ungraph() -> GraphFactory<Undirected, StableGraph<(), (), Undirected>> {
+ stable_graph()
+}
+
+pub fn stable_digraph() -> GraphFactory<Directed, StableGraph<(), (), Directed>> {
+ stable_graph()
+}
diff --git a/third_party/rust/petgraph/benches/common/mod.rs b/third_party/rust/petgraph/benches/common/mod.rs
new file mode 100644
index 0000000000..739c04197a
--- /dev/null
+++ b/third_party/rust/petgraph/benches/common/mod.rs
@@ -0,0 +1,2 @@
+mod factories;
+pub use factories::*;
diff --git a/third_party/rust/petgraph/benches/dijkstra.rs b/third_party/rust/petgraph/benches/dijkstra.rs
new file mode 100644
index 0000000000..7901983ffd
--- /dev/null
+++ b/third_party/rust/petgraph/benches/dijkstra.rs
@@ -0,0 +1,32 @@
+#![feature(test)]
+
+extern crate petgraph;
+extern crate test;
+
+use petgraph::prelude::*;
+use std::cmp::{max, min};
+use test::Bencher;
+
+use petgraph::algo::dijkstra;
+
+#[bench]
+fn dijkstra_bench(bench: &mut Bencher) {
+ static NODE_COUNT: usize = 10_000;
+ let mut g = Graph::new_undirected();
+ let nodes: Vec<NodeIndex<_>> = (0..NODE_COUNT).into_iter().map(|i| g.add_node(i)).collect();
+ for i in 0..NODE_COUNT {
+ let n1 = nodes[i];
+ let neighbour_count = i % 8 + 3;
+ let j_from = max(0, i as i32 - neighbour_count as i32 / 2) as usize;
+ let j_to = min(NODE_COUNT, j_from + neighbour_count);
+ for j in j_from..j_to {
+ let n2 = nodes[j];
+ let distance = (i + 3) % 10;
+ g.add_edge(n1, n2, distance);
+ }
+ }
+
+ bench.iter(|| {
+ let _scores = dijkstra(&g, nodes[0], None, |e| *e.weight());
+ });
+}
diff --git a/third_party/rust/petgraph/benches/iso.rs b/third_party/rust/petgraph/benches/iso.rs
new file mode 100644
index 0000000000..f0875c1109
--- /dev/null
+++ b/third_party/rust/petgraph/benches/iso.rs
@@ -0,0 +1,52 @@
+#![feature(test)]
+
+extern crate petgraph;
+extern crate test;
+
+use test::Bencher;
+
+#[allow(dead_code)]
+mod common;
+use common::*;
+
+use petgraph::algo::is_isomorphic;
+
+#[bench]
+fn petersen_iso_bench(bench: &mut Bencher) {
+ let a = digraph().petersen_a();
+ let b = digraph().petersen_b();
+
+ bench.iter(|| is_isomorphic(&a, &b));
+}
+
+#[bench]
+fn petersen_undir_iso_bench(bench: &mut Bencher) {
+ let a = ungraph().petersen_a();
+ let b = ungraph().petersen_b();
+
+ bench.iter(|| is_isomorphic(&a, &b));
+}
+
+#[bench]
+fn full_iso_bench(bench: &mut Bencher) {
+ let a = ungraph().full_a();
+ let b = ungraph().full_b();
+
+ bench.iter(|| is_isomorphic(&a, &b));
+}
+
+#[bench]
+fn praust_dir_no_iso_bench(bench: &mut Bencher) {
+ let a = digraph().praust_a();
+ let b = digraph().praust_b();
+
+ bench.iter(|| is_isomorphic(&a, &b));
+}
+
+#[bench]
+fn praust_undir_no_iso_bench(bench: &mut Bencher) {
+ let a = ungraph().praust_a();
+ let b = ungraph().praust_b();
+
+ bench.iter(|| is_isomorphic(&a, &b));
+}
diff --git a/third_party/rust/petgraph/benches/matrix_graph.rs b/third_party/rust/petgraph/benches/matrix_graph.rs
new file mode 100644
index 0000000000..72f5aae692
--- /dev/null
+++ b/third_party/rust/petgraph/benches/matrix_graph.rs
@@ -0,0 +1,235 @@
+#![feature(test)]
+
+extern crate petgraph;
+extern crate test;
+
+use test::Bencher;
+
+use petgraph::algo;
+use petgraph::matrix_graph::{node_index, MatrixGraph};
+use petgraph::{Directed, EdgeType, Incoming, Outgoing};
+
+#[bench]
+fn add_100_nodes(b: &mut test::Bencher) {
+ b.iter(|| {
+ let mut g = MatrixGraph::<(), ()>::with_capacity(100);
+
+ for _ in 0..100 {
+ let _ = g.add_node(());
+ }
+ });
+}
+
+#[bench]
+fn add_100_edges_to_self(b: &mut test::Bencher) {
+ let mut g = MatrixGraph::<(), ()>::with_capacity(100);
+ let nodes: Vec<_> = (0..100).map(|_| g.add_node(())).collect();
+ let g = g;
+
+ b.iter(|| {
+ let mut g = g.clone();
+
+ for &node in nodes.iter() {
+ g.add_edge(node, node, ());
+ }
+ });
+}
+
+#[bench]
+fn add_5_edges_for_each_of_100_nodes(b: &mut test::Bencher) {
+ let mut g = MatrixGraph::<(), ()>::with_capacity(100);
+ let nodes: Vec<_> = (0..100).map(|_| g.add_node(())).collect();
+ let g = g;
+
+ let edges_to_add: Vec<_> = nodes
+ .iter()
+ .enumerate()
+ .map(|(i, &node)| {
+ let edges: Vec<_> = (0..5)
+ .map(|j| (i + j + 1) % nodes.len())
+ .map(|j| (node, nodes[j]))
+ .collect();
+
+ edges
+ })
+ .flatten()
+ .collect();
+
+ b.iter(|| {
+ let mut g = g.clone();
+
+ for &(source, target) in edges_to_add.iter() {
+ g.add_edge(source, target, ());
+ }
+ });
+}
+
+#[bench]
+fn add_edges_from_root(bench: &mut test::Bencher) {
+ bench.iter(|| {
+ let mut gr = MatrixGraph::new();
+ let a = gr.add_node(());
+
+ for _ in 0..100 {
+ let b = gr.add_node(());
+ gr.add_edge(a, b, ());
+ }
+ });
+}
+
+#[bench]
+fn add_adjacent_edges(bench: &mut test::Bencher) {
+ bench.iter(|| {
+ let mut gr = MatrixGraph::new();
+ let mut prev = None;
+ for _ in 0..100 {
+ let b = gr.add_node(());
+
+ if let Some(a) = prev {
+ gr.add_edge(a, b, ());
+ }
+
+ prev = Some(b);
+ }
+ });
+}
+
+/// An almost full set
+const FULL: &str = "
+ 1 1 1 1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1 1 1 1
+ 1 1 1 1 0 1 1 1 0 1
+ 1 1 1 1 1 1 1 1 1 1
+";
+
+const BIGGER: &str = "
+ 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 1 0 1 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 1 0 1 0 1 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0
+ 0 1 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 1 0 1 0 0
+ 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 1 1 1 0 0 0
+ 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 1 0 0 0 1
+ 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 0 0 0 1 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 1 0 1 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 1 1
+ 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 1 1 0 1 1 1 0 0 0 0 0 1 0 0 1 0 0 0 1 0 1 1
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 0 1
+ 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 1 1 0
+ 0 1 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
+ 1 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 1 0 1 0 1 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 1 0 1 1 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 1 1 0 1 0 0 0 0 0 0 1 0 0 0 0 0
+ 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0
+ 1 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0 0 0
+ 0 1 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 1 0 0
+ 0 0 1 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 1 0
+ 0 0 0 1 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1
+ 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 1 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 1 0 1 0 0
+ 0 0 0 0 0 1 0 0 0 0 0 0 1 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 1 1 1 0 0 0
+ 0 1 0 0 0 0 1 0 0 0 0 0 1 1 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 1 0 0 0 1
+ 0 1 0 0 0 0 0 1 0 0 0 0 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 0 0 0 1 0
+ 0 1 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 1 1
+ 0 1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 1 1
+ 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 0 1
+ 0 1 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 1 1 0
+";
+
+/// Parse a text adjacency matrix format into a directed graph
+fn parse_matrix<Ty: EdgeType>(s: &str) -> MatrixGraph<(), (), Ty> {
+ let mut gr = MatrixGraph::default();
+ let s = s.trim();
+ let lines = s.lines().filter(|l| !l.is_empty());
+ for (row, line) in lines.enumerate() {
+ for (col, word) in line.split(' ').filter(|s| !s.is_empty()).enumerate() {
+ let has_edge = word.parse::<i32>().unwrap();
+ assert!(has_edge == 0 || has_edge == 1);
+ if has_edge == 0 {
+ continue;
+ }
+ while col >= gr.node_count() || row >= gr.node_count() {
+ gr.add_node(());
+ }
+ gr.add_edge(node_index(row), node_index(col), ());
+ }
+ }
+ gr
+}
+
+#[bench]
+fn full_edges_out(bench: &mut Bencher) {
+ let a = parse_matrix::<Directed>(FULL);
+ bench.iter(|| a.edges_directed(node_index(1), Outgoing).count())
+}
+
+#[bench]
+fn full_edges_in(bench: &mut Bencher) {
+ let a = parse_matrix::<Directed>(FULL);
+ bench.iter(|| a.edges_directed(node_index(1), Incoming).count())
+}
+
+#[bench]
+fn full_neighbors_out(bench: &mut Bencher) {
+ let a = parse_matrix::<Directed>(FULL);
+ bench.iter(|| a.neighbors_directed(node_index(1), Outgoing).count())
+}
+
+#[bench]
+fn full_neighbors_in(bench: &mut Bencher) {
+ let a = parse_matrix::<Directed>(FULL);
+
+ bench.iter(|| a.neighbors_directed(node_index(1), Incoming).count())
+}
+
+#[bench]
+fn full_sccs(bench: &mut Bencher) {
+ let a = parse_matrix::<Directed>(FULL);
+ bench.iter(|| algo::kosaraju_scc(&a));
+}
+
+#[bench]
+fn bigger_edges_out(bench: &mut Bencher) {
+ let a = parse_matrix::<Directed>(BIGGER);
+ bench.iter(|| a.edges_directed(node_index(1), Outgoing).count())
+}
+
+#[bench]
+fn bigger_edges_in(bench: &mut Bencher) {
+ let a = parse_matrix::<Directed>(BIGGER);
+ bench.iter(|| a.edges_directed(node_index(1), Incoming).count())
+}
+
+#[bench]
+fn bigger_neighbors_out(bench: &mut Bencher) {
+ let a = parse_matrix::<Directed>(BIGGER);
+ bench.iter(|| a.neighbors_directed(node_index(1), Outgoing).count())
+}
+
+#[bench]
+fn bigger_neighbors_in(bench: &mut Bencher) {
+ let a = parse_matrix::<Directed>(BIGGER);
+
+ bench.iter(|| a.neighbors_directed(node_index(1), Incoming).count())
+}
+
+#[bench]
+fn bigger_sccs(bench: &mut Bencher) {
+ let a = parse_matrix::<Directed>(BIGGER);
+ bench.iter(|| algo::kosaraju_scc(&a));
+}
diff --git a/third_party/rust/petgraph/benches/ograph.rs b/third_party/rust/petgraph/benches/ograph.rs
new file mode 100644
index 0000000000..d3f29869c8
--- /dev/null
+++ b/third_party/rust/petgraph/benches/ograph.rs
@@ -0,0 +1,52 @@
+#![feature(test)]
+
+extern crate petgraph;
+extern crate test;
+
+use petgraph::graph::Graph;
+
+#[bench]
+fn bench_inser(b: &mut test::Bencher) {
+ let mut og = Graph::new();
+ let fst = og.add_node(0i32);
+ for x in 1..125 {
+ let n = og.add_node(x);
+ og.add_edge(fst, n, ());
+ }
+ b.iter(|| og.add_node(1))
+}
+
+#[bench]
+fn bench_add_edge(b: &mut test::Bencher) {
+ let mut og = Graph::new();
+ for _ in 0..100 {
+ og.add_node(());
+ }
+
+ b.iter(|| {
+ for (a, b) in og.node_indices().zip(og.node_indices().skip(1)) {
+ og.add_edge(a, b, ());
+ }
+ og.clear_edges();
+ })
+}
+
+#[bench]
+fn bench_remove(b: &mut test::Bencher) {
+ // removal is very slow in a big graph.
+ // and this one doesn't even have many nodes.
+ let mut og = Graph::new();
+ let fst = og.add_node(0i32);
+ let mut prev = fst;
+ for x in 1..1250 {
+ let n = og.add_node(x);
+ og.add_edge(prev, n, ());
+ prev = n;
+ }
+ //println!("{}", og);
+ b.iter(|| {
+ for _ in 0..100 {
+ og.remove_node(fst);
+ }
+ })
+}
diff --git a/third_party/rust/petgraph/benches/stable_graph.rs b/third_party/rust/petgraph/benches/stable_graph.rs
new file mode 100644
index 0000000000..9dffd91cf4
--- /dev/null
+++ b/third_party/rust/petgraph/benches/stable_graph.rs
@@ -0,0 +1,85 @@
+#![feature(test)]
+
+extern crate petgraph;
+extern crate test;
+
+use petgraph::prelude::*;
+use test::Bencher;
+
+#[allow(dead_code)]
+mod common;
+use common::*;
+
+use petgraph::stable_graph::node_index;
+
+#[bench]
+fn full_edges_default(bench: &mut Bencher) {
+ let a = stable_digraph().full_a();
+ bench.iter(|| a.edges(node_index(1)).count())
+}
+
+#[bench]
+fn full_edges_out(bench: &mut Bencher) {
+ let a = stable_digraph().full_a();
+ bench.iter(|| a.edges_directed(node_index(1), Outgoing).count())
+}
+
+#[bench]
+fn full_edges_in(bench: &mut Bencher) {
+ let a = stable_digraph().full_a();
+ bench.iter(|| a.edges_directed(node_index(1), Incoming).count())
+}
+
+#[bench]
+fn neighbors_default(bench: &mut Bencher) {
+ let a = stable_digraph().full_a();
+ bench.iter(|| a.neighbors(node_index(1)).count())
+}
+
+#[bench]
+fn neighbors_out(bench: &mut Bencher) {
+ let a = stable_digraph().full_a();
+ bench.iter(|| a.neighbors_directed(node_index(1), Outgoing).count())
+}
+
+#[bench]
+fn neighbors_in(bench: &mut Bencher) {
+ let a = stable_digraph().full_a();
+ bench.iter(|| a.neighbors_directed(node_index(1), Incoming).count())
+}
+
+#[bench]
+fn sccs_stable_graph(bench: &mut Bencher) {
+ let a = stable_digraph().bigger();
+ bench.iter(|| petgraph::algo::kosaraju_scc(&a));
+}
+
+#[bench]
+fn sccs_graph(bench: &mut Bencher) {
+ let a = digraph().bigger();
+ bench.iter(|| petgraph::algo::kosaraju_scc(&a));
+}
+
+#[bench]
+fn stable_graph_map(bench: &mut Bencher) {
+ let a = stable_digraph().bigger();
+ bench.iter(|| a.map(|i, _| i, |i, _| i));
+}
+
+#[bench]
+fn graph_map(bench: &mut Bencher) {
+ let a = digraph().bigger();
+ bench.iter(|| a.map(|i, _| i, |i, _| i));
+}
+
+#[bench]
+fn stable_graph_retain_nodes(bench: &mut Bencher) {
+ let mut a = stable_digraph().bigger();
+ bench.iter(|| a.retain_nodes(|_gr, i| (i.index() + 1) % 3700 != 0));
+}
+
+#[bench]
+fn stable_graph_retain_edges(bench: &mut Bencher) {
+ let mut a = stable_digraph().bigger();
+ bench.iter(|| a.retain_edges(|_gr, i| (i.index() + 1) % 3700 != 0));
+}
diff --git a/third_party/rust/petgraph/benches/unionfind.rs b/third_party/rust/petgraph/benches/unionfind.rs
new file mode 100644
index 0000000000..dd4446a52b
--- /dev/null
+++ b/third_party/rust/petgraph/benches/unionfind.rs
@@ -0,0 +1,156 @@
+#![feature(test)]
+
+extern crate petgraph;
+extern crate test;
+
+use test::Bencher;
+
+#[allow(dead_code)]
+mod common;
+use common::*;
+
+use petgraph::algo::{connected_components, is_cyclic_undirected, min_spanning_tree};
+
+#[bench]
+fn connected_components_praust_undir_bench(bench: &mut Bencher) {
+ let a = ungraph().praust_a();
+ let b = ungraph().praust_b();
+
+ bench.iter(|| (connected_components(&a), connected_components(&b)));
+}
+
+#[bench]
+fn connected_components_praust_dir_bench(bench: &mut Bencher) {
+ let a = digraph().praust_a();
+ let b = digraph().praust_b();
+
+ bench.iter(|| (connected_components(&a), connected_components(&b)));
+}
+
+#[bench]
+fn connected_components_full_undir_bench(bench: &mut Bencher) {
+ let a = ungraph().full_a();
+ let b = ungraph().full_b();
+
+ bench.iter(|| (connected_components(&a), connected_components(&b)));
+}
+
+#[bench]
+fn connected_components_full_dir_bench(bench: &mut Bencher) {
+ let a = digraph().full_a();
+ let b = digraph().full_b();
+
+ bench.iter(|| (connected_components(&a), connected_components(&b)));
+}
+
+#[bench]
+fn connected_components_petersen_undir_bench(bench: &mut Bencher) {
+ let a = ungraph().petersen_a();
+ let b = ungraph().petersen_b();
+
+ bench.iter(|| (connected_components(&a), connected_components(&b)));
+}
+
+#[bench]
+fn connected_components_petersen_dir_bench(bench: &mut Bencher) {
+ let a = digraph().petersen_a();
+ let b = digraph().petersen_b();
+
+ bench.iter(|| (connected_components(&a), connected_components(&b)));
+}
+
+#[bench]
+fn is_cyclic_undirected_praust_undir_bench(bench: &mut Bencher) {
+ let a = ungraph().praust_a();
+ let b = ungraph().praust_b();
+
+ bench.iter(|| (is_cyclic_undirected(&a), is_cyclic_undirected(&b)));
+}
+
+#[bench]
+fn is_cyclic_undirected_praust_dir_bench(bench: &mut Bencher) {
+ let a = digraph().praust_a();
+ let b = digraph().praust_b();
+
+ bench.iter(|| (is_cyclic_undirected(&a), is_cyclic_undirected(&b)));
+}
+
+#[bench]
+fn is_cyclic_undirected_full_undir_bench(bench: &mut Bencher) {
+ let a = ungraph().full_a();
+ let b = ungraph().full_b();
+
+ bench.iter(|| (is_cyclic_undirected(&a), is_cyclic_undirected(&b)));
+}
+
+#[bench]
+fn is_cyclic_undirected_full_dir_bench(bench: &mut Bencher) {
+ let a = digraph().full_a();
+ let b = digraph().full_b();
+
+ bench.iter(|| (is_cyclic_undirected(&a), is_cyclic_undirected(&b)));
+}
+
+#[bench]
+fn is_cyclic_undirected_petersen_undir_bench(bench: &mut Bencher) {
+ let a = ungraph().petersen_a();
+ let b = ungraph().petersen_b();
+
+ bench.iter(|| (is_cyclic_undirected(&a), is_cyclic_undirected(&b)));
+}
+
+#[bench]
+fn is_cyclic_undirected_petersen_dir_bench(bench: &mut Bencher) {
+ let a = digraph().petersen_a();
+ let b = digraph().petersen_b();
+
+ bench.iter(|| (is_cyclic_undirected(&a), is_cyclic_undirected(&b)));
+}
+
+#[bench]
+fn min_spanning_tree_praust_undir_bench(bench: &mut Bencher) {
+ let a = ungraph().praust_a();
+ let b = ungraph().praust_b();
+
+ bench.iter(|| (min_spanning_tree(&a), min_spanning_tree(&b)));
+}
+
+#[bench]
+fn min_spanning_tree_praust_dir_bench(bench: &mut Bencher) {
+ let a = digraph().praust_a();
+ let b = digraph().praust_b();
+
+ bench.iter(|| (min_spanning_tree(&a), min_spanning_tree(&b)));
+}
+
+#[bench]
+fn min_spanning_tree_full_undir_bench(bench: &mut Bencher) {
+ let a = ungraph().full_a();
+ let b = ungraph().full_b();
+
+ bench.iter(|| (min_spanning_tree(&a), min_spanning_tree(&b)));
+}
+
+#[bench]
+fn min_spanning_tree_full_dir_bench(bench: &mut Bencher) {
+ let a = digraph().full_a();
+ let b = digraph().full_b();
+
+ bench.iter(|| (min_spanning_tree(&a), min_spanning_tree(&b)));
+}
+
+#[bench]
+fn min_spanning_tree_petersen_undir_bench(bench: &mut Bencher) {
+ let a = ungraph().petersen_a();
+ let b = ungraph().petersen_b();
+
+ bench.iter(|| (min_spanning_tree(&a), min_spanning_tree(&b)));
+}
+
+#[bench]
+fn min_spanning_tree_petersen_dir_bench(bench: &mut Bencher) {
+ let a = digraph().petersen_a();
+ let b = digraph().petersen_b();
+
+ bench.iter(|| (min_spanning_tree(&a), min_spanning_tree(&b)));
+}