[librsvg: 4/5] PathBuilder: use a SmallVec while the path commands are being accumulated
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 4/5] PathBuilder: use a SmallVec while the path commands are being accumulated
- Date: Wed, 25 Mar 2020 00:46:06 +0000 (UTC)
commit ee63041d012406a9b05204ef604eb5411a8cf7ae
Author: Federico Mena Quintero <federico gnome org>
Date: Tue Mar 24 16:52:20 2020 -0600
PathBuilder: use a SmallVec while the path commands are being accumulated
From the last commit, we had this for the big SVG file in #574:
--------------------------------------------------------------------------------
n time(i) total(B) useful-heap(B) extra-heap(B) stacks(B)
--------------------------------------------------------------------------------
30 22,796,106,012 1,553,581,072 1,329,943,324 223,637,748 0
^^^^^^^^^^^
That extra-heap is a lot of allocator metadata or waste space,
possibly from heap fragmentation due to all the realloc() shenanigans
from using into_boxed_slice() on the starting Vec<PathCommand>.
This commit makes PathBuilder use a SmallVec:
pub struct PathBuilder {
path_commands: SmallVec<[PathCommand; 32]>,
}
That is, it will keep up to 32 PathCommand directly inside itself, and
only spill to a heap allocation if more elements come in.
We still into_boxed_slice() for the final Path. Hopefully this makes
realloc() find heap blocks that are more closely packed. Indeed:
--------------------------------------------------------------------------------
n time(i) total(B) useful-heap(B) extra-heap(B) stacks(B)
--------------------------------------------------------------------------------
33 24,139,598,653 1,416,831,176 1,329,943,212 86,887,964 0
^^^^^^^^^^
That's a lot of less waste space. Note also how the total bytes
shrinks from 1,553,581,072 to 1,416,831,176.
Cargo.lock | 1 +
rsvg_internals/Cargo.toml | 1 +
rsvg_internals/src/path_builder.rs | 10 +++++++---
3 files changed, 9 insertions(+), 3 deletions(-)
---
diff --git a/Cargo.lock b/Cargo.lock
index a7ad5290..f1dd3655 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1366,6 +1366,7 @@ dependencies = [
"rctree 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"selectors 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
diff --git a/rsvg_internals/Cargo.toml b/rsvg_internals/Cargo.toml
index 0dc8beef..6943e443 100644
--- a/rsvg_internals/Cargo.toml
+++ b/rsvg_internals/Cargo.toml
@@ -35,6 +35,7 @@ rayon = "1"
rctree = "0.3.3"
regex = "1"
selectors = "0.22.0"
+smallvec = "1.2.0"
url = "2"
xml-rs = "0.8.0"
diff --git a/rsvg_internals/src/path_builder.rs b/rsvg_internals/src/path_builder.rs
index 7da68d3a..b5738ffb 100644
--- a/rsvg_internals/src/path_builder.rs
+++ b/rsvg_internals/src/path_builder.rs
@@ -1,5 +1,7 @@
//! Representation of Bézier paths.
+use smallvec::SmallVec;
+
use std::f64;
use std::f64::consts::*;
@@ -294,9 +296,9 @@ impl PathCommand {
///
/// When you are finished constructing a path builder, turn it into
/// a `Path` with `into_path`.
-#[derive(Clone, Default)]
+#[derive(Clone)]
pub struct PathBuilder {
- path_commands: Vec<PathCommand>,
+ path_commands: SmallVec<[PathCommand; 32]>,
}
/// An immutable path
@@ -308,7 +310,9 @@ pub struct Path {
impl PathBuilder {
pub fn new() -> PathBuilder {
- PathBuilder::default()
+ PathBuilder {
+ path_commands: SmallVec::new(),
+ }
}
pub fn into_path(self) -> Path {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]