From ad9da96336d4b39825d465b586e0f601897b3640 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Sat, 29 Dec 2018 17:08:49 -0800 Subject: [PATCH] Build objects in parallel! --- Cargo.lock | 1 + utils/tile-svg/Cargo.toml | 1 + utils/tile-svg/src/main.rs | 23 ++++++++++++++++++++--- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a02d6ea3..fdec8c66 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1492,6 +1492,7 @@ dependencies = [ "quick-xml 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)", "quickcheck 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "svgtypes 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/utils/tile-svg/Cargo.toml b/utils/tile-svg/Cargo.toml index e8a899ed..111a8242 100644 --- a/utils/tile-svg/Cargo.toml +++ b/utils/tile-svg/Cargo.toml @@ -14,6 +14,7 @@ jemallocator = "0.1" lyon_geom = "0.12" lyon_path = "0.12" quick-xml = "0.12" +rayon = "1.0" svgtypes = "0.2" [dependencies.pathfinder_path_utils] diff --git a/utils/tile-svg/src/main.rs b/utils/tile-svg/src/main.rs index 55598acc..afb5d0e3 100644 --- a/utils/tile-svg/src/main.rs +++ b/utils/tile-svg/src/main.rs @@ -28,6 +28,7 @@ use lyon_path::iterator::PathIter; use pathfinder_path_utils::stroke::{StrokeStyle, StrokeToFillIter}; use quick_xml::Reader; use quick_xml::events::{BytesStart, Event}; +use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator}; use std::cmp::Ordering; use std::fmt::{self, Debug, Formatter}; use std::fs::File; @@ -57,6 +58,9 @@ fn main() { .value_name("COUNT") .takes_value(true) .help("Run a benchmark with COUNT runs")) + .arg(Arg::with_name("sequential").short("s") + .long("sequential") + .help("Use only one thread")) .arg(Arg::with_name("INPUT").help("Path to the SVG file to render") .required(true) .index(1)) @@ -68,6 +72,7 @@ fn main() { Some(runs) => runs.parse().unwrap(), None => 1, }; + let sequential = matches.is_present("sequential"); let input_path = PathBuf::from(matches.value_of("INPUT").unwrap()); let output_path = matches.value_of("OUTPUT").map(PathBuf::from); @@ -77,7 +82,12 @@ fn main() { let start_time = Instant::now(); let mut built_scene = BuiltScene::new(&scene.view_box, scene.objects.len() as u32); for _ in 0..runs { - built_scene = BuiltScene::from_objects(&scene.view_box, &scene.build_objects()); + let built_objects = if sequential { + scene.build_objects_sequentially() + } else { + scene.build_objects_in_parallel() + }; + built_scene = BuiltScene::from_objects(&scene.view_box, &built_objects); } let elapsed_time = Instant::now() - start_time; @@ -311,8 +321,7 @@ impl Scene { &self.styles[style.0 as usize] } - fn build_objects(&self) -> Vec { - // TODO(pcwalton): Parallelize! + fn build_objects_sequentially(&self) -> Vec { self.objects.iter().enumerate().map(|(object_index, object)| { let mut tiler = Tiler::new(&object.outline, object_index as u32, &self.view_box); tiler.generate_tiles(); @@ -320,6 +329,14 @@ impl Scene { }).collect() } + fn build_objects_in_parallel(&self) -> Vec { + self.objects.par_iter().enumerate().map(|(object_index, object)| { + let mut tiler = Tiler::new(&object.outline, object_index as u32, &self.view_box); + tiler.generate_tiles(); + tiler.built_object + }).collect() + } + fn push_svg_path(&mut self, value: &str, style: StyleId, name: String) { if self.get_style(style).stroke_color.is_some() { let computed_style = self.get_style(style);