Totals bgl_time_remove_vertex() { GraphType g; start_deadman(2); while (!had_alarm && boost::num_vertices(g)<MAX_VERTICES) boost::add_vertex(g); GraphSize gsize = bgl_size(g); size_t nv_orig = gsize.first; // Vertex removal is SO SLOW that we need more time to measure it accurately. To quote from chapter 11 "Performance // Guidelines" of the the "Boost Graph Library: User Guide and Reference Manual" book, // Other variations [than list-list] of adjacency list perform horribly on this operation because its // implementation is not of constant time complexity. start_deadman(6); Sawyer::Stopwatch t; for (size_t i=0; i<nv_orig && !had_alarm; ++i) { // Note that this won't work generically. It's only good for graphs where vertices are numbered sequentially across // the entire graph. typename boost::graph_traits<GraphType>::vertex_descriptor v = rand() % boost::num_vertices(g); boost::remove_vertex(v, g); } t.stop(); size_t nremoved = nv_orig - boost::num_vertices(g); return report("vert erase", gsize, nremoved, t, "verts/s"); }
Totals sage_time_add_vertex() { GraphType *g = new GraphType; start_deadman(2); Sawyer::Stopwatch t; while (!had_alarm && g->numberOfGraphNodes()<MAX_VERTICES) g->addNode(new SgGraphNode); t.stop(); return report("add vertex", sage_size(g), g->numberOfGraphNodes(), t, "verts/s"); }
Totals bgl_time_add_vertex() { GraphType g; start_deadman(2); Sawyer::Stopwatch t; while (!had_alarm && boost::num_vertices(g)<MAX_VERTICES) boost::add_vertex(g); t.stop(); return report("add vertex", bgl_size(g), boost::num_vertices(g), t, "verts/s"); }
Totals sgl_time_add_vertex() { GraphType g; start_deadman(2); Sawyer::Stopwatch t; while (!had_alarm && g.nVertices()<MAX_VERTICES) g.insertVertex(0); t.stop(); return report("add vertex", sgl_size(g), g.nVertices(), t, "verts/s"); }
Totals sgl_time_vertex_traversal() { GraphType g; sgl_random_graph(g, MAX_VERTICES, 2, 4.0); size_t niter=0; start_deadman(2); Sawyer::Stopwatch t; while (!had_alarm && niter<MAX_COUNT) { boost::iterator_range<typename GraphType::VertexNodeIterator> vi_pair = g.vertices(); for (typename GraphType::VertexNodeIterator iter=vi_pair.begin(); iter!=vi_pair.end() && !had_alarm; ++iter) ++niter; } t.stop(); return report("vert iter", sgl_size(g), niter, t, "verts/s"); }
Totals sage_time_vertex_traversal() { GraphType *g = new GraphType; sage_random_graph(g, MAX_VERTICES, 2, 4.0); size_t niter=0; start_deadman(2); Sawyer::Stopwatch t; while (!had_alarm && niter<MAX_COUNT) { std::set<SgGraphNode*> vertex_set = g->computeNodeSet(); for (std::set<SgGraphNode*>::iterator vi=vertex_set.begin(); vi!=vertex_set.end() && !had_alarm; ++vi) ++niter; } t.stop(); return report("vert iter", sage_size(g), niter, t, "verts/s"); }
Totals sgl_time_edge_traversal() { GraphType g; sgl_random_graph(g, MAX_VERTICES, 2, 4.0); size_t niter=0; start_deadman(2); Sawyer::Stopwatch t; while (!had_alarm && niter<MAX_COUNT) { boost::iterator_range<typename GraphType::EdgeNodeIterator> edges = g.edges(); for (typename GraphType::EdgeNodeIterator edge=edges.begin(); edge!=edges.end() && !had_alarm; ++edge) ++niter; } t.stop(); return report("edge iter", sgl_size(g), niter, t, "edges/s"); }
Totals bgl_time_edge_traversal() { GraphType g; bgl_random_graph(g, MAX_VERTICES, 2, 4.0); size_t niter=0; start_deadman(2); Sawyer::Stopwatch t; while (!had_alarm && niter<MAX_COUNT) { typename boost::graph_traits<GraphType>::edge_iterator ei, ei_end; for (boost::tie(ei, ei_end) = boost::edges(g); ei!=ei_end && !had_alarm; ++ei) ++niter; } t.stop(); return report("edge iter", bgl_size(g), niter, t, "edges/s"); }
static Totals sgl_time_remove_edge() { GraphType g; sgl_random_graph(g, MAX_VERTICES, 2, 4.0); GraphSize gsize = sgl_size(g); start_deadman(2); Sawyer::Stopwatch t; size_t ne_orig = g.nEdges(); for (size_t i=0; i<ne_orig && !had_alarm; ++i) g.eraseEdge(sgl_random_edge(g)); t.stop(); size_t nremoved = ne_orig - g.nEdges(); return report("edge erase", gsize, nremoved, t, "edges/s"); }
Totals bgl_time_vertex_traversal() { GraphType g; bgl_random_graph(g, MAX_VERTICES, 2, 4.0); size_t niter=0; start_deadman(2); Sawyer::Stopwatch t; while (!had_alarm && niter<MAX_COUNT) { typename boost::graph_traits<GraphType>::vertex_iterator vi, vi_end; for (boost::tie(vi, vi_end)=boost::vertices(g); vi!=vi_end && !had_alarm; ++vi) ++niter; } t.stop(); return report("vert iter", bgl_size(g), niter, t, "verts/s"); }
static Totals report(const std::string &title, const GraphSize gsize, size_t count, const Sawyer::Stopwatch &t, const std::string &units) { printf(" %-16s (%13s %13s) %13s / %6.3f ", title.c_str(), pretty(gsize.first).c_str(), pretty(gsize.second).c_str(), pretty(count).c_str(), t.report()); double rate = count / t.report(); if (rate >= 10e9) { printf("%13g", rate); } else { uint64_t irate = rate; printf("%13s", pretty(irate).c_str()); } printf(" %s\n", units.c_str()); return Totals(count, t.report()); }
Totals sgl_time_add_edge() { GraphType g; start_deadman(2); while (!had_alarm && g.nVertices()<MAX_VERTICES) g.insertVertex(0); start_deadman(2); Sawyer::Stopwatch t; while (!had_alarm && g.nEdges()<MAX_EDGES) { typename GraphType::VertexNodeIterator v1 = sgl_random_vertex(g); typename GraphType::VertexNodeIterator v2 = sgl_random_vertex(g); g.insertEdge(v1, v2, 0); } t.stop(); return report("add edge", sgl_size(g), g.nEdges(), t, "edges/s"); }
Totals yagi_time_add_edge() { GraphType g; start_deadman(2); while (!had_alarm && g.num_vertices()<MAX_VERTICES) g.add_vertex(); start_deadman(2); Sawyer::Stopwatch t; while (!had_alarm && g.num_edges()<MAX_EDGES) { typename GraphType::VertexDescriptor v1 = yagi_random_vertex(g); typename GraphType::VertexDescriptor v2 = yagi_random_vertex(g); g.add_edge(v1, v2); } t.stop(); return report("add edge", yagi_size(g), g.num_edges(), t, "edges/s"); }
Totals sgl_time_remove_vertex() { GraphType g; start_deadman(2); while (!had_alarm && g.nVertices()<MAX_VERTICES) g.insertVertex(0); GraphSize gsize = sgl_size(g); size_t nv_orig = gsize.first; start_deadman(2); Sawyer::Stopwatch t; for (size_t i=0; i<nv_orig && !had_alarm; ++i) g.eraseVertex(sgl_random_vertex(g)); t.stop(); size_t nremoved = nv_orig - g.nVertices(); return report("vert erase", gsize, nremoved, t, "verts/s"); }
Totals yagi_time_vertex_traversal() { GraphType g; yagi_random_graph(g, MAX_VERTICES, 2, 4.0); size_t niter=0; start_deadman(2); Sawyer::Stopwatch t; while (!had_alarm && niter<MAX_COUNT) { std::pair<typename GraphType::VertexIterator, typename GraphType::VertexIterator> vi_pair = g.vertices(); while (vi_pair.first!=vi_pair.second && !had_alarm) { ++niter; ++vi_pair.first; } } t.stop(); return report("vert iter", yagi_size(g), niter, t, "verts/s"); }
static Totals bgl_time_clear_vertex() { GraphType g; bgl_random_graph(g, MAX_VERTICES, 2, 4.0); std::vector<typename boost::graph_traits<GraphType>::vertex_descriptor> vertices = bgl_vertex_vector(g); shuffle(vertices); GraphSize gsize = bgl_size(g); size_t ncleared; start_deadman(2); Sawyer::Stopwatch t; for (ncleared=0; ncleared<gsize.first && !had_alarm; ++ncleared) boost::clear_vertex(vertices[ncleared], g); t.stop(); size_t ne_removed = gsize.second - boost::num_edges(g); report("vert clear", gsize, ncleared, t, "verts/s"); return report("vert clear", gsize, ne_removed, t, "edges/s"); }
Totals sage_time_edge_traversal() { GraphType *g = new GraphType; sage_random_graph(g, MAX_VERTICES, 2, 4.0); size_t niter=0; start_deadman(2); Sawyer::Stopwatch t; while (!had_alarm && niter<MAX_COUNT) { // SgGraph doesn't have a graph-wide edge iterator, so we have to iterator over the vertices and then each edge. std::set<SgGraphNode*> vertex_set = g->computeNodeSet(); for (std::set<SgGraphNode*>::iterator vi=vertex_set.begin(); vi!=vertex_set.end() && !had_alarm; ++vi) { std::set<SgGraphEdge*> edge_set = g->computeEdgeSet(*vi); for (std::set<SgGraphEdge*>::iterator ei=edge_set.begin(); ei!=edge_set.end() && !had_alarm; ++ei) ++niter; } } t.stop(); return report("edge iter", sage_size(g), niter, t, "edges/s"); }
static Totals sgl_time_clear_vertex() { GraphType g; sgl_random_graph(g, MAX_VERTICES, 2, 4.0); std::vector<typename GraphType::VertexNodeIterator> vertices; for (size_t i=0; i<g.nVertices(); ++i) vertices.push_back(g.findVertex(i)); shuffle(vertices); GraphSize gsize = sgl_size(g); size_t ncleared; start_deadman(6); // vertex clearing is SO SLOW that we need more time (see bgl_time_remove_vertex()) Sawyer::Stopwatch t; for (ncleared=0; ncleared<gsize.first && !had_alarm; ++ncleared) g.clearEdges(vertices[ncleared]); t.stop(); size_t ne_removed = gsize.second - g.nEdges(); report("vert clear", gsize, ncleared, t, "verts/s"); return report("vert clear", gsize, ne_removed, t, "edges/s"); }
// usage: testSort NTHINGS NTHREADS int main(int argc, char *argv[]) { size_t nvalues = 16; size_t nthreads = 1; if (argc>1) nvalues = strtoul(argv[1], NULL, 0); if (argc>2) nthreads = strtoul(argv[2], NULL, 0); std::cerr <<"Generating " <<nvalues <<" values... "; Sawyer::Stopwatch generation; LinearCongruentialGenerator random; std::vector<Thing> values; values.reserve(nvalues); for (size_t i=0; i<nvalues; ++i) { static const int maxval = 1000000; values.push_back(Thing(random() % maxval, random() % maxval)); } std::cerr <<"done (" <<generation.stop() <<" seconds)\n"; std::cerr <<"Sorting with " <<nthreads <<" threads... "; Sawyer::Stopwatch sorting; rose::ParallelSort::quicksort(&values[0], &values[0]+values.size(), compare, nthreads); std::cerr <<"done (" <<sorting.stop() <<" seconds)\n"; std::cerr <<"Checking results...\n"; size_t nfailures = 0; static const size_t failureLimit = 100; for (size_t i=1; i<values.size() && nfailures<failureLimit; ++i) { if (!compare(values[i-1], values[i]) && compare(values[i], values[i-1])) { std::cerr <<"sort failed: values[" <<i-1 <<", " <<i <<"] = (" <<values[i-1] <<", " <<values[i] <<")\n"; ++nfailures; } } if (nfailures>=failureLimit) std::cerr <<"additional failures suppressed.\n"; return nfailures ? 1 : 0; }
Totals sage_time_add_edge() { // Insert vertices GraphType *g = new GraphType; start_deadman(2); while (!had_alarm && g->numberOfGraphNodes()<MAX_VERTICES) g->addNode(new SgGraphNode); // Build a list of vertices that we can index in constant time. std::vector<SgGraphNode*> vertices = sage_vertex_vector(g); // The actual test start_deadman(2); Sawyer::Stopwatch t; while (!had_alarm && g->numberOfGraphEdges()<MAX_EDGES) { SgGraphNode *v1 = sage_random_vertex(g, vertices); SgGraphNode *v2 = sage_random_vertex(g, vertices); g->addEdge(v1, v2); } t.stop(); return report("add edge", sage_size(g), g->numberOfGraphEdges(), t, "edges/s"); }
Totals bgl_time_add_edge() { GraphType g; start_deadman(2); while (!had_alarm && boost::num_vertices(g)<MAX_VERTICES) boost::add_vertex(g); // Build a list of vertices that we can index in constant time, regardless of the BGL graph type typedef typename boost::graph_traits<GraphType>::vertex_descriptor VertexDescriptor; std::vector<VertexDescriptor> vertices = bgl_vertex_vector(g); assert(vertices.size()==boost::num_vertices(g)); // The actual test start_deadman(2); Sawyer::Stopwatch t; while (!had_alarm && boost::num_edges(g)<MAX_EDGES) { typename boost::graph_traits<GraphType>::vertex_descriptor v1 = bgl_random_vertex(g, vertices); typename boost::graph_traits<GraphType>::vertex_descriptor v2 = bgl_random_vertex(g, vertices); boost::add_edge(v1, v2, g); } t.stop(); return report("add edge", bgl_size(g), boost::num_edges(g), t, "edges/s"); }