cgal/Hash_map/benchmark/Hash_map/hm.cpp

271 lines
6.5 KiB
C++

#define NOHASH 1
#include <iostream>
#include <fstream>
#include <map>
#include <algorithm>
#include <CGAL/Surface_mesh.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/IO/Polyhedron_iostream.h>
#include <CGAL/boost/graph/graph_traits_Surface_mesh.h>
#include <CGAL/boost/graph/graph_traits_Polyhedron_3.h>
#include <CGAL/boost/graph/helpers.h>
#include <CGAL/Timer.h>
#include<boost/range/iterator_range.hpp>
#include <boost/unordered_map.hpp>
#include <unordered_map>
#include <boost/random/random_number_generator.hpp>
#include <boost/random/linear_congruential.hpp>
typedef CGAL::Simple_cartesian<double> Kernel;
typedef Kernel::Point_3 Point_3;
typedef Kernel::Vector_3 Vector_3;
typedef CGAL::Timer Timer;
template <typename G, typename Map>
void
run(const G& g)
{
typedef typename boost::graph_traits<G>::vertex_descriptor vertex_descriptor;
typedef typename boost::property_map<G,CGAL::vertex_point_t>::const_type VPM;
VPM vpm = get(CGAL::vertex_point,g);
std::vector<vertex_descriptor> V, V2;
std::vector<Point_3> P1, P2;
for(vertex_descriptor vd : vertices(g)){
V.push_back(vd);
V2.push_back(vd);
}
boost::rand48 random;
boost::random_number_generator<boost::rand48> rng(random);
std::random_shuffle(V.begin(), V.end(), rng);
Timer t;
#if 0
t.start();
Map vm;
for(vertex_descriptor vd : V){
vm[vd] = get(vpm,vd);
}
t.stop(); std::cerr << "Insertion: " << t.time() << " sec. " << std::endl;
#endif
Vector_3 v(0,0,0);
std::size_t st=0;
#if 0
std::cerr << "foreach std::vector<vertex_descriptor)\n";
t.reset(); t.start();
for(int i=0; i<100; i++){
for(vertex_descriptor vd : V2){
#ifdef NOHASH
st += std::size_t(vd);
#else
typename Map::iterator it = vm.find(vd);
v = v + ((*it).second - CGAL::ORIGIN);
#endif
}
}
t.stop(); std::cerr << " " <<t.time() << " sec. " << std::endl;
#endif
#if 1
std::cerr << "foreach boost::iterator_range r = vertices(g))\n";
t.reset(); t.start();
for(int i=0; i<100; i++){
boost::iterator_range<typename boost::graph_traits<G>::vertex_iterator> r = vertices(g);
for(vertex_descriptor vd : r) {
#ifdef NOHASH
st += std::size_t(vd);
// v = v + (get(vpm,vd) - CGAL::ORIGIN);
#else
typename Map::iterator it = vm.find(vd);
v = v + ((*it).second - CGAL::ORIGIN);
#endif
}
}
t.stop(); std::cerr << " " <<t.time() << " sec. " << std::endl;
#endif
#if 1
std::cerr << "foreach CGAL::Iterator_range r = vertices(g))\n";
t.reset(); t.start();
for(int i=0; i<100; i++){
CGAL::Iterator_range<typename boost::graph_traits<G>::vertex_iterator> ir = vertices(g);
for(vertex_descriptor vd : ir) {
#ifdef NOHASH
st += std::size_t(vd);
//v = v + (get(vpm,vd) - CGAL::ORIGIN);
#else
typename Map::iterator it = vm.find(vd);
v = v + ((*it).second - CGAL::ORIGIN);
#endif
}
}
t.stop(); std::cerr << " " <<t.time() << " sec. " << std::endl;
#endif
#if 1
std::cerr << "foreach vertices(g))\n";
t.reset(); t.start();
for(int i=0; i<100; i++){
for(vertex_descriptor vd : vertices(g)) {
#ifdef NOHASH
st += std::size_t(vd);
//v = v + (get(vpm,vd) - CGAL::ORIGIN);
#else
typename Map::iterator it = vm.find(vd);
v = v + ((*it).second - CGAL::ORIGIN);
#endif
}
}
t.stop(); std::cerr << " " <<t.time() << " sec. " << std::endl;
#endif
#if 1
std::cerr << "for vertices(g))\n";
t.reset(); t.start();
for(int i=0; i<100; i++){
for(vertex_descriptor vd : vertices(g)) {
#ifdef NOHASH
st += std::size_t(vd);
//v = v + (get(vpm,vd) - CGAL::ORIGIN);
#else
typename Map::iterator it = vm.find(vd);
v = v + ((*it).second - CGAL::ORIGIN);
#endif
}
}
t.stop(); std::cerr << " " <<t.time() << " sec. " << std::endl;
#endif
#if 0
std::cerr << "boost::tie(vb,ve) = vertices(g);\n";
t.reset(); t.start();
for(int i=0; i<100; i++){
typename boost::graph_traits<G>::vertex_iterator vb, ve;
boost::tie(vb,ve) = vertices(g);
for(; vb != ve; ++vb) {
vertex_descriptor vd = *vb;
#ifdef NOHASH
st += std::size_t(vd);
//v = v + (get(vpm,vd) - CGAL::ORIGIN);
#else
typename Map::iterator it = vm.find(vd);
v = v + ((*it).second - CGAL::ORIGIN);
#endif
}
}
t.stop(); std::cerr << " " <<t.time() << " sec. " << std::endl;
#endif
std::cerr << "v = " << v << " " << st << std::endl;
}
struct blob {
int a, b, c, d, e, f, g;
};
int main(int , char* argv[])
{
{
typedef CGAL::Surface_mesh<Point_3> Mesh;
typedef boost::graph_traits<Mesh>::vertex_descriptor vertex_descriptor;
typedef std::map<vertex_descriptor,Point_3> SM;
typedef std::unordered_map<vertex_descriptor,Point_3> SUM;
typedef boost::unordered_map<vertex_descriptor,Point_3> BUM;
Mesh m;
std::ifstream input(argv[1]);
input >> m;
std::cerr << num_vertices(m) << " items\n";
std::cerr << "\nSurface_mesh std::map"<< std::endl;
run<Mesh,SM>(m);
#if 0
std::cerr << "\nSurface_mesh std::unordered_map"<< std::endl;
run<Mesh,SUM>(m);
std::cerr << "\nSurface_mesh boost::unordered_map"<< std::endl;
run<Mesh,BUM>(m);
#endif
}
#if 0
{
typedef CGAL::Polyhedron_3<Kernel> Mesh;
typedef boost::graph_traits<Mesh>::vertex_descriptor vertex_descriptor;
typedef std::map<vertex_descriptor,Point_3> SM;
typedef std::unordered_map<vertex_descriptor,Point_3> SUM;
typedef boost::unordered_map<vertex_descriptor,Point_3> BUM;
Mesh m;
std::ifstream input(argv[1]);
input >> m;
std::cerr << "\nPolyhedron_3 std::map" << std::endl;
run<Mesh,SM>(m);
std::cerr << "\nPolyhedron_3 std::unordered_map"<< std::endl;
run<Mesh,SUM>(m);
std::cerr << "\nPolyhedron_3 boost::unordered_map"<< std::endl;
run<Mesh,BUM>(m);
}
{
const int N = 3165798;
std::cerr << "\nHashing "<< N << " pointers\n";
std::vector<int> ints(N);
std::vector<blob> data(N);
for(int i =0; i <N ; i++){
ints[i]=i;
}
std::random_shuffle(ints.begin(), ints.end());
{
boost::unordered_map<blob*,int> um;
Timer t;
t.start();
for(int i= 0; i < N; i++){
um[& (data[ints[i]])] = i;
}
t.stop();
std::cerr << " boost::unordered_map: " << t.time() << " sec.\n";
}
{
std::unordered_map<blob*,int> um;
Timer t;
t.start();
for(int i= 0; i < N; i++){
um[& (data[ints[i]])] = i;
}
t.stop();
std::cerr << " std::unordered_map: " << t.time() << " sec.\n";
}
}
#endif
return 0;
}