зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1648703 - Use a custom vector growth pattern in PrimitiveList. r=gw
This greatly reduces the number of vector reallocations happening while building primitive lists. On the difficult cases like youtube front page the reduction is a bit more than 50%, and more in other pages I tested. More importantly it dramatically reduces the amount of the most expensive of these reallocations which are when the vector is starting to get large. Differential Revision: https://phabricator.services.mozilla.com/D81725
This commit is contained in:
Родитель
957d144600
Коммит
36d0b0407a
|
@ -4397,7 +4397,31 @@ impl PrimitiveList {
|
|||
.intersection(&prim_rect)
|
||||
.unwrap_or_else(LayoutRect::zero);
|
||||
|
||||
let instance_index = self.prim_instances.len();
|
||||
|
||||
// Primitive lengths aren't evenly distributed among primitive lists:
|
||||
// We often have a large amount of single primitive lists, a
|
||||
// few below 20~30 primitives, and even fewer lists (maybe a couple)
|
||||
// in the multiple hundreds with nothing in between.
|
||||
// We can see in profiles that reallocating vectors while pushing
|
||||
// primitives is taking a large amount of the total scene build time,
|
||||
// so we take advantage of what we know about the length distributions
|
||||
// to go for an adapted vector growth pattern that avoids over-allocating
|
||||
// for the many small allocations while avoiding a lot of reallocation by
|
||||
// quickly converging to the common sizes.
|
||||
// Rust's default vector growth strategy (when pushing elements one by one)
|
||||
// is to double the capacity every time.
|
||||
let prims_len = self.prim_instances.len();
|
||||
if prims_len == self.prim_instances.capacity() {
|
||||
let next_alloc = match prims_len {
|
||||
1 ..= 31 => 32 - prims_len,
|
||||
32 ..= 256 => 512 - prims_len,
|
||||
_ => prims_len * 2,
|
||||
};
|
||||
|
||||
self.prim_instances.reserve(next_alloc);
|
||||
}
|
||||
|
||||
let instance_index = prims_len;
|
||||
self.prim_instances.push(prim_instance);
|
||||
|
||||
if let Some(cluster) = self.clusters.last_mut() {
|
||||
|
@ -4407,6 +4431,18 @@ impl PrimitiveList {
|
|||
}
|
||||
}
|
||||
|
||||
// Same idea with clusters, using a different distribution.
|
||||
let clusters_len = self.clusters.len();
|
||||
if clusters_len == self.clusters.capacity() {
|
||||
let next_alloc = match clusters_len {
|
||||
1 ..= 15 => 16 - clusters_len,
|
||||
16 ..= 127 => 128 - clusters_len,
|
||||
_ => clusters_len * 2,
|
||||
};
|
||||
|
||||
self.clusters.reserve(next_alloc);
|
||||
}
|
||||
|
||||
let mut cluster = PrimitiveCluster::new(
|
||||
spatial_node_index,
|
||||
flags,
|
||||
|
|
Загрузка…
Ссылка в новой задаче