/* Note: This module uses the 'unofficial' bench that works with Stable Rust as of 2018. This may conflict with "official" bench which is in "Nightly" Rust */ #[macro_use] extern crate bencher; extern crate earcutr; extern crate serde; extern crate serde_json; use bencher::Bencher; use std::fs::File; use std::fs::OpenOptions; use std::io::Read; use std::io::Write; //extern crate cpuprofiler; //use cpuprofiler::PROFILER; // this is to "force" optimized code to measure results, by outputting fn mkoutput(filename_w_dashes: &str, triangles: Vec) { let filename = str::replace(filename_w_dashes, "-", "_"); let outfile = &format!("benches/benchoutput/{}.js", filename); match OpenOptions::new() .write(true) .create(true) .truncate(true) .open(outfile) { Err(e) => println!("error writing {} {}", outfile, e), Ok(f) => writeln!( &f, r###"testOutput["{}"]["benchmark"]=[{:?},{:?},{:?}];"###, filename, 0, triangles.len(), triangles ) .unwrap(), }; } fn parse_json(rawdata: &str) -> Option>>> { let mut v: Vec>> = Vec::new(); match serde_json::from_str::(&rawdata) { Err(e) => println!("error deserializing, {}", e), Ok(jsondata) => { if jsondata.is_array() { let contours = jsondata.as_array().unwrap(); for i in 0..contours.len() { let contourval = &contours[i]; if contourval.is_array() { let contour = contourval.as_array().unwrap(); let mut vc: Vec> = Vec::new(); for j in 0..contour.len() { let points = contour[j].as_array().unwrap(); let mut vp: Vec = Vec::new(); for k in 0..points.len() { let val = points[k].to_string(); let pval = val.parse::().unwrap(); vp.push(pval); } vc.push(vp); } v.push(vc); } } } } }; return Some(v); } fn load_json(testname: &str) -> (Vec, Vec, usize) { let fullname = format!("./tests/fixtures/{}.json", testname); let mut xdata: Vec>> = Vec::new(); match File::open(&fullname) { Err(why) => println!("failed to open file '{}': {}", fullname, why), Ok(mut f) => { //println!("testing {},", fullname); let mut strdata = String::new(); match f.read_to_string(&mut strdata) { Err(why) => println!("failed to read {}, {}", fullname, why), Ok(_numb) => { //println!("read {} bytes", numb); let rawstring = strdata.trim(); match parse_json(rawstring) { None => println!("failed to parse {}", fullname), Some(parsed_data) => { xdata = parsed_data; } }; } }; } }; return earcutr::flatten(&xdata); } fn bench_quadrilateral(bench: &mut Bencher) { bench.iter(|| { earcutr::earcut(&vec![10., 0., 0., 50., 60., 60., 70., 10.], &vec![], 2); }); } fn bench_hole(bench: &mut Bencher) { let mut v = vec![0., 0., 50., 0., 50., 50., 0., 50.]; let h = vec![10., 10., 40., 10., 40., 40., 10., 40.]; v.extend(h); bench.iter(|| { earcutr::earcut(&v, &vec![4], 2); }) } fn bench_flatten(bench: &mut Bencher) { let v = vec![ vec![vec![0., 0.], vec![1., 0.], vec![1., 1.], vec![0., 1.]], // outer ring vec![vec![1., 1.], vec![3., 1.], vec![3., 3.]], // hole ring ]; bench.iter(|| { let (_vertices, _holes, _dimensions) = earcutr::flatten(&v); }) } fn bench_indices_2d(bench: &mut Bencher) { bench.iter(|| { let _indices = earcutr::earcut( &vec![10.0, 0.0, 0.0, 50.0, 60.0, 60.0, 70.0, 10.0], &vec![], 2, ); }) } fn bench_indices_3d(bench: &mut Bencher) { bench.iter(|| { let _indices = earcutr::earcut( &vec![ 10.0, 0.0, 0.0, 0.0, 50.0, 0.0, 60.0, 60.0, 0.0, 70.0, 10.0, 0.0, ], &vec![], 3, ); }) } fn bench_empty(bench: &mut Bencher) { bench.iter(|| { let _indices = earcutr::earcut(&vec![], &vec![], 2); }) } // file based tests fn bench_building(bench: &mut Bencher) { let nm = "building"; let (data, holeidxs, dimensions) = load_json(nm); let mut triangles = Vec::new(); bench.iter(|| { triangles = earcutr::earcut(&data, &holeidxs, dimensions); }); mkoutput(nm, triangles); } fn bench_dude(bench: &mut Bencher) { let nm = "dude"; let (data, holeidxs, dimensions) = load_json(nm); let mut triangles = Vec::new(); bench.iter(|| { triangles = earcutr::earcut(&data, &holeidxs, dimensions); }); mkoutput(nm, triangles); } fn bench_water(bench: &mut Bencher) { let nm = "water"; let (data, holeidxs, dimensions) = load_json(nm); let mut triangles = Vec::new(); bench.iter(|| { triangles = earcutr::earcut(&data, &holeidxs, dimensions); }); mkoutput(nm, triangles); } fn bench_water2(bench: &mut Bencher) { let nm = "water2"; let (data, holeidxs, dimensions) = load_json(nm); let mut triangles = Vec::new(); bench.iter(|| { triangles = earcutr::earcut(&data, &holeidxs, dimensions); }); mkoutput(nm, triangles); } fn bench_water3(bench: &mut Bencher) { let nm = "water3"; let (data, holeidxs, dimensions) = load_json(nm); let mut triangles = Vec::new(); bench.iter(|| { triangles = earcutr::earcut(&data, &holeidxs, dimensions); }); mkoutput(nm, triangles); } fn bench_water3b(bench: &mut Bencher) { let nm = "water3b"; let (data, holeidxs, dimensions) = load_json(nm); let mut triangles = Vec::new(); bench.iter(|| { triangles = earcutr::earcut(&data, &holeidxs, dimensions); }); mkoutput(nm, triangles); } fn bench_water4(bench: &mut Bencher) { let nm = "water4"; let (data, holeidxs, dimensions) = load_json(nm); let mut triangles = Vec::new(); bench.iter(|| { triangles = earcutr::earcut(&data, &holeidxs, dimensions); }); mkoutput(nm, triangles); } fn bench_water_huge(bench: &mut Bencher) { let nm = "water-huge"; let (data, holeidxs, dimensions) = load_json(nm); let mut triangles = Vec::new(); //PROFILER.lock().unwrap().start("./earcutr.profile").unwrap(); bench.iter(|| { // for i in 0..99 { triangles = earcutr::earcut(&data, &holeidxs, dimensions); // } }); //PROFILER.lock().unwrap().stop().unwrap(); mkoutput(nm, triangles); } fn bench_water_huge2(bench: &mut Bencher) { let nm = "water-huge2"; let (data, holeidxs, dimensions) = load_json(nm); let mut triangles = Vec::new(); bench.iter(|| { triangles = earcutr::earcut(&data, &holeidxs, dimensions); }); mkoutput(nm, triangles); } fn bench_degenerate(bench: &mut Bencher) { let nm = "degenerate"; let (data, holeidxs, dimensions) = load_json(nm); let mut triangles = Vec::new(); bench.iter(|| { triangles = earcutr::earcut(&data, &holeidxs, dimensions); }); mkoutput(nm, triangles); } fn bench_bad_hole(bench: &mut Bencher) { let nm = "bad-hole"; let (data, holeidxs, dimensions) = load_json(nm); let mut triangles = Vec::new(); bench.iter(|| { triangles = earcutr::earcut(&data, &holeidxs, dimensions); }); mkoutput(nm, triangles); } fn bench_empty_square(bench: &mut Bencher) { let nm = "empty-square"; let (data, holeidxs, dimensions) = load_json(nm); let mut triangles = Vec::new(); bench.iter(|| { triangles = earcutr::earcut(&data, &holeidxs, dimensions); }); mkoutput(nm, triangles); } fn bench_issue16(bench: &mut Bencher) { let nm = "issue16"; let (data, holeidxs, dimensions) = load_json(nm); let mut triangles = Vec::new(); bench.iter(|| { triangles = earcutr::earcut(&data, &holeidxs, dimensions); }); mkoutput(nm, triangles); } fn bench_issue17(bench: &mut Bencher) { let nm = "issue17"; let (data, holeidxs, dimensions) = load_json(nm); let mut triangles = Vec::new(); bench.iter(|| { triangles = earcutr::earcut(&data, &holeidxs, dimensions); }); mkoutput(nm, triangles); } fn bench_steiner(bench: &mut Bencher) { let nm = "steiner"; let (data, holeidxs, dimensions) = load_json(nm); let mut triangles = Vec::new(); bench.iter(|| { triangles = earcutr::earcut(&data, &holeidxs, dimensions); }); mkoutput(nm, triangles); } fn bench_issue29(bench: &mut Bencher) { let nm = "issue29"; let (data, holeidxs, dimensions) = load_json(nm); let mut triangles = Vec::new(); bench.iter(|| { triangles = earcutr::earcut(&data, &holeidxs, dimensions); }); mkoutput(nm, triangles); } fn bench_issue34(bench: &mut Bencher) { let nm = "issue34"; let (data, holeidxs, dimensions) = load_json(nm); let mut triangles = Vec::new(); bench.iter(|| { triangles = earcutr::earcut(&data, &holeidxs, dimensions); }); mkoutput(nm, triangles); } fn bench_issue35(bench: &mut Bencher) { let nm = "issue35"; let (data, holeidxs, dimensions) = load_json(nm); let mut triangles = Vec::new(); bench.iter(|| { triangles = earcutr::earcut(&data, &holeidxs, dimensions); }); mkoutput(nm, triangles); } fn bench_self_touching(bench: &mut Bencher) { let nm = "self-touching"; let (data, holeidxs, dimensions) = load_json(nm); let mut triangles = Vec::new(); bench.iter(|| { triangles = earcutr::earcut(&data, &holeidxs, dimensions); }); mkoutput(nm, triangles); } fn bench_outside_ring(bench: &mut Bencher) { let nm = "outside-ring"; let (data, holeidxs, dimensions) = load_json(nm); let mut triangles = Vec::new(); bench.iter(|| { triangles = earcutr::earcut(&data, &holeidxs, dimensions); }); mkoutput(nm, triangles); } fn bench_simplified_us_border(bench: &mut Bencher) { let nm = "simplified-us-border"; let (data, holeidxs, dimensions) = load_json(nm); let mut triangles = Vec::new(); bench.iter(|| { triangles = earcutr::earcut(&data, &holeidxs, dimensions); }); mkoutput(nm, triangles); } fn bench_touching_holes(bench: &mut Bencher) { let nm = "touching-holes"; let (data, holeidxs, dimensions) = load_json(nm); let mut triangles = Vec::new(); bench.iter(|| { triangles = earcutr::earcut(&data, &holeidxs, dimensions); }); mkoutput(nm, triangles); } fn bench_hole_touching_outer(bench: &mut Bencher) { let nm = "hole-touching-outer"; let (data, holeidxs, dimensions) = load_json(nm); let mut triangles = Vec::new(); bench.iter(|| { triangles = earcutr::earcut(&data, &holeidxs, dimensions); }); mkoutput(nm, triangles); } fn bench_hilbert(bench: &mut Bencher) { let nm = "hilbert"; let (data, holeidxs, dimensions) = load_json(nm); let mut triangles = Vec::new(); bench.iter(|| { triangles = earcutr::earcut(&data, &holeidxs, dimensions); }); mkoutput(nm, triangles); } fn bench_issue45(bench: &mut Bencher) { let nm = "issue45"; let (data, holeidxs, dimensions) = load_json(nm); let mut triangles = Vec::new(); bench.iter(|| { triangles = earcutr::earcut(&data, &holeidxs, dimensions); }); mkoutput(nm, triangles); } fn bench_eberly_3(bench: &mut Bencher) { let nm = "eberly-3"; let (data, holeidxs, dimensions) = load_json(nm); let mut triangles = Vec::new(); bench.iter(|| { triangles = earcutr::earcut(&data, &holeidxs, dimensions); }); mkoutput(nm, triangles); } fn bench_eberly_6(bench: &mut Bencher) { let nm = "eberly-6"; let (data, holeidxs, dimensions) = load_json(nm); let mut triangles = Vec::new(); bench.iter(|| { triangles = earcutr::earcut(&data, &holeidxs, dimensions); }); mkoutput(nm, triangles); } fn bench_issue52(bench: &mut Bencher) { let nm = "issue52"; let (data, holeidxs, dimensions) = load_json(nm); let mut triangles = Vec::new(); bench.iter(|| { triangles = earcutr::earcut(&data, &holeidxs, dimensions); }); mkoutput(nm, triangles); } fn bench_shared_points(bench: &mut Bencher) { let nm = "shared-points"; let (data, holeidxs, dimensions) = load_json(nm); let mut triangles = Vec::new(); bench.iter(|| { triangles = earcutr::earcut(&data, &holeidxs, dimensions); }); mkoutput(nm, triangles); } fn bench_bad_diagonals(bench: &mut Bencher) { let nm = "bad-diagonals"; let (data, holeidxs, dimensions) = load_json(nm); let mut triangles = Vec::new(); bench.iter(|| { triangles = earcutr::earcut(&data, &holeidxs, dimensions); }); mkoutput(nm, triangles); } fn bench_issue83(bench: &mut Bencher) { let nm = "issue83"; let (data, holeidxs, dimensions) = load_json(nm); let mut triangles = Vec::new(); bench.iter(|| { triangles = earcutr::earcut(&data, &holeidxs, dimensions); }); mkoutput(nm, triangles); } benchmark_group!( benches, bench_indices_3d, bench_indices_2d, bench_empty, bench_quadrilateral, bench_hole, bench_flatten, bench_bad_diagonals, bench_bad_hole, bench_building, bench_degenerate, bench_dude, bench_eberly_3, bench_eberly_6, bench_empty_square, bench_hilbert, bench_hole_touching_outer, bench_issue16, bench_issue17, bench_issue29, bench_issue34, bench_issue35, bench_issue45, bench_issue52, bench_issue83, bench_outside_ring, bench_self_touching, bench_shared_points, bench_simplified_us_border, bench_steiner, bench_touching_holes, bench_water_huge, bench_water_huge2, bench_water, bench_water2, bench_water3, bench_water3b, bench_water4, ); benchmark_main!(benches);