mirror of
https://github.com/zed-industries/zed.git
synced 2026-06-01 03:14:56 +07:00
gpui: Small perf optimizations (#40767)
Some random findings based on profiling Release Notes: - N/A *or* Added/Fixed/Improved ...
This commit is contained in:
parent
4f0a44896a
commit
738e248109
6 changed files with 78 additions and 88 deletions
|
|
@ -34,15 +34,14 @@ where
|
|||
|
||||
pub fn insert(&mut self, new_bounds: Bounds<U>) -> u32 {
|
||||
// If the tree is empty, make the root the new leaf.
|
||||
if self.root.is_none() {
|
||||
let Some(mut index) = self.root else {
|
||||
let new_node = self.push_leaf(new_bounds, 1);
|
||||
self.root = Some(new_node);
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
// Search for the best place to add the new leaf based on heuristics.
|
||||
let mut max_intersecting_ordering = 0;
|
||||
let mut index = self.root.unwrap();
|
||||
while let Node::Internal {
|
||||
left,
|
||||
right,
|
||||
|
|
|
|||
|
|
@ -572,18 +572,14 @@ impl DispatchTree {
|
|||
focus_path
|
||||
}
|
||||
|
||||
pub fn view_path(&self, view_id: EntityId) -> SmallVec<[EntityId; 8]> {
|
||||
let mut view_path: SmallVec<[EntityId; 8]> = SmallVec::new();
|
||||
pub fn view_path_reversed(&self, view_id: EntityId) -> impl Iterator<Item = EntityId> {
|
||||
let mut current_node_id = self.view_node_ids.get(&view_id).copied();
|
||||
while let Some(node_id) = current_node_id {
|
||||
let node = self.node(node_id);
|
||||
if let Some(view_id) = node.view_id {
|
||||
view_path.push(view_id);
|
||||
}
|
||||
current_node_id = node.parent;
|
||||
}
|
||||
view_path.reverse(); // Reverse the path so it goes from the root to the view node.
|
||||
view_path
|
||||
|
||||
std::iter::successors(
|
||||
current_node_id.map(|node_id| self.node(node_id)),
|
||||
|node_id| Some(self.node(node_id.parent?)),
|
||||
)
|
||||
.filter_map(|node| node.view_id)
|
||||
}
|
||||
|
||||
pub fn node(&self, node_id: DispatchNodeId) -> &DispatchNode {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ use crate::{
|
|||
point, size,
|
||||
};
|
||||
use collections::{FxHashMap, FxHashSet};
|
||||
use smallvec::SmallVec;
|
||||
use stacksafe::{StackSafe, stacksafe};
|
||||
use std::{fmt::Debug, ops::Range};
|
||||
use taffy::{
|
||||
|
|
@ -31,6 +30,7 @@ pub struct TaffyLayoutEngine {
|
|||
taffy: TaffyTree<NodeContext>,
|
||||
absolute_layout_bounds: FxHashMap<LayoutId, Bounds<Pixels>>,
|
||||
computed_layouts: FxHashSet<LayoutId>,
|
||||
layout_bounds_scratch_space: Vec<LayoutId>,
|
||||
}
|
||||
|
||||
const EXPECT_MESSAGE: &str = "we should avoid taffy layout errors by construction if possible";
|
||||
|
|
@ -43,6 +43,7 @@ impl TaffyLayoutEngine {
|
|||
taffy,
|
||||
absolute_layout_bounds: FxHashMap::default(),
|
||||
computed_layouts: FxHashSet::default(),
|
||||
layout_bounds_scratch_space: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -168,7 +169,7 @@ impl TaffyLayoutEngine {
|
|||
//
|
||||
|
||||
if !self.computed_layouts.insert(id) {
|
||||
let mut stack = SmallVec::<[LayoutId; 64]>::new();
|
||||
let mut stack = &mut self.layout_bounds_scratch_space;
|
||||
stack.push(id);
|
||||
while let Some(id) = stack.pop() {
|
||||
self.absolute_layout_bounds.remove(&id);
|
||||
|
|
@ -177,7 +178,7 @@ impl TaffyLayoutEngine {
|
|||
.children(id.into())
|
||||
.expect(EXPECT_MESSAGE)
|
||||
.into_iter()
|
||||
.map(Into::into),
|
||||
.map(LayoutId::from),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1316,9 +1316,7 @@ impl Window {
|
|||
for view_id in self
|
||||
.rendered_frame
|
||||
.dispatch_tree
|
||||
.view_path(view_id)
|
||||
.into_iter()
|
||||
.rev()
|
||||
.view_path_reversed(view_id)
|
||||
{
|
||||
if !self.dirty_views.insert(view_id) {
|
||||
break;
|
||||
|
|
@ -2277,19 +2275,14 @@ impl Window {
|
|||
}
|
||||
|
||||
self.next_frame.deferred_draws.extend(
|
||||
self.rendered_frame.deferred_draws
|
||||
[range.start.deferred_draws_index..range.end.deferred_draws_index]
|
||||
.iter()
|
||||
.map(|deferred_draw| DeferredDraw {
|
||||
current_view: deferred_draw.current_view,
|
||||
parent_node: reused_subtree.refresh_node_id(deferred_draw.parent_node),
|
||||
element_id_stack: deferred_draw.element_id_stack.clone(),
|
||||
text_style_stack: deferred_draw.text_style_stack.clone(),
|
||||
priority: deferred_draw.priority,
|
||||
element: None,
|
||||
absolute_offset: deferred_draw.absolute_offset,
|
||||
prepaint_range: deferred_draw.prepaint_range.clone(),
|
||||
paint_range: deferred_draw.paint_range.clone(),
|
||||
self.rendered_frame
|
||||
.deferred_draws
|
||||
.drain(range.start.deferred_draws_index..range.end.deferred_draws_index)
|
||||
.map(|mut deferred_draw| {
|
||||
deferred_draw.parent_node =
|
||||
reused_subtree.refresh_node_id(deferred_draw.parent_node);
|
||||
deferred_draw.element = None;
|
||||
deferred_draw
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
|
@ -4902,7 +4895,7 @@ pub enum ElementId {
|
|||
/// A code location.
|
||||
CodeLocation(core::panic::Location<'static>),
|
||||
/// A labeled child of an element.
|
||||
NamedChild(Box<ElementId>, SharedString),
|
||||
NamedChild(Arc<ElementId>, SharedString),
|
||||
}
|
||||
|
||||
impl ElementId {
|
||||
|
|
@ -5016,7 +5009,7 @@ impl From<(&'static str, u32)> for ElementId {
|
|||
|
||||
impl<T: Into<SharedString>> From<(ElementId, T)> for ElementId {
|
||||
fn from((id, name): (ElementId, T)) -> Self {
|
||||
ElementId::NamedChild(Box::new(id), name.into())
|
||||
ElementId::NamedChild(Arc::new(id), name.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ impl ProjectEnvironment {
|
|||
.get("PATH")
|
||||
.map(|path| path.as_str())
|
||||
.unwrap_or_default();
|
||||
log::info!(
|
||||
log::debug!(
|
||||
"using project environment variables shell launched in {:?}. PATH={:?}",
|
||||
abs_path,
|
||||
path
|
||||
|
|
|
|||
|
|
@ -389,11 +389,12 @@ impl Rope {
|
|||
if offset >= self.summary().len_utf16 {
|
||||
return self.summary().len;
|
||||
}
|
||||
let mut cursor = self.chunks.cursor::<Dimensions<OffsetUtf16, usize>>(());
|
||||
cursor.seek(&offset, Bias::Left);
|
||||
let overshoot = offset - cursor.start().0;
|
||||
cursor.start().1
|
||||
+ cursor.item().map_or(Default::default(), |chunk| {
|
||||
let (start, _, item) =
|
||||
self.chunks
|
||||
.find::<Dimensions<OffsetUtf16, usize>, _>((), &offset, Bias::Left);
|
||||
let overshoot = offset - start.0;
|
||||
start.1
|
||||
+ item.map_or(Default::default(), |chunk| {
|
||||
chunk.as_slice().offset_utf16_to_offset(overshoot)
|
||||
})
|
||||
}
|
||||
|
|
@ -402,11 +403,12 @@ impl Rope {
|
|||
if offset >= self.summary().len {
|
||||
return self.summary().lines;
|
||||
}
|
||||
let mut cursor = self.chunks.cursor::<Dimensions<usize, Point>>(());
|
||||
cursor.seek(&offset, Bias::Left);
|
||||
let overshoot = offset - cursor.start().0;
|
||||
cursor.start().1
|
||||
+ cursor.item().map_or(Point::zero(), |chunk| {
|
||||
let (start, _, item) =
|
||||
self.chunks
|
||||
.find::<Dimensions<usize, Point>, _>((), &offset, Bias::Left);
|
||||
let overshoot = offset - start.0;
|
||||
start.1
|
||||
+ item.map_or(Point::zero(), |chunk| {
|
||||
chunk.as_slice().offset_to_point(overshoot)
|
||||
})
|
||||
}
|
||||
|
|
@ -415,11 +417,12 @@ impl Rope {
|
|||
if offset >= self.summary().len {
|
||||
return self.summary().lines_utf16();
|
||||
}
|
||||
let mut cursor = self.chunks.cursor::<Dimensions<usize, PointUtf16>>(());
|
||||
cursor.seek(&offset, Bias::Left);
|
||||
let overshoot = offset - cursor.start().0;
|
||||
cursor.start().1
|
||||
+ cursor.item().map_or(PointUtf16::zero(), |chunk| {
|
||||
let (start, _, item) =
|
||||
self.chunks
|
||||
.find::<Dimensions<usize, PointUtf16>, _>((), &offset, Bias::Left);
|
||||
let overshoot = offset - start.0;
|
||||
start.1
|
||||
+ item.map_or(PointUtf16::zero(), |chunk| {
|
||||
chunk.as_slice().offset_to_point_utf16(overshoot)
|
||||
})
|
||||
}
|
||||
|
|
@ -428,11 +431,12 @@ impl Rope {
|
|||
if point >= self.summary().lines {
|
||||
return self.summary().lines_utf16();
|
||||
}
|
||||
let mut cursor = self.chunks.cursor::<Dimensions<Point, PointUtf16>>(());
|
||||
cursor.seek(&point, Bias::Left);
|
||||
let overshoot = point - cursor.start().0;
|
||||
cursor.start().1
|
||||
+ cursor.item().map_or(PointUtf16::zero(), |chunk| {
|
||||
let (start, _, item) =
|
||||
self.chunks
|
||||
.find::<Dimensions<Point, PointUtf16>, _>((), &point, Bias::Left);
|
||||
let overshoot = point - start.0;
|
||||
start.1
|
||||
+ item.map_or(PointUtf16::zero(), |chunk| {
|
||||
chunk.as_slice().point_to_point_utf16(overshoot)
|
||||
})
|
||||
}
|
||||
|
|
@ -441,13 +445,11 @@ impl Rope {
|
|||
if point >= self.summary().lines {
|
||||
return self.summary().len;
|
||||
}
|
||||
let mut cursor = self.chunks.cursor::<Dimensions<Point, usize>>(());
|
||||
cursor.seek(&point, Bias::Left);
|
||||
let overshoot = point - cursor.start().0;
|
||||
cursor.start().1
|
||||
+ cursor
|
||||
.item()
|
||||
.map_or(0, |chunk| chunk.as_slice().point_to_offset(overshoot))
|
||||
let (start, _, item) =
|
||||
self.chunks
|
||||
.find::<Dimensions<Point, usize>, _>((), &point, Bias::Left);
|
||||
let overshoot = point - start.0;
|
||||
start.1 + item.map_or(0, |chunk| chunk.as_slice().point_to_offset(overshoot))
|
||||
}
|
||||
|
||||
pub fn point_utf16_to_offset(&self, point: PointUtf16) -> usize {
|
||||
|
|
@ -462,11 +464,12 @@ impl Rope {
|
|||
if point >= self.summary().lines_utf16() {
|
||||
return self.summary().len;
|
||||
}
|
||||
let mut cursor = self.chunks.cursor::<Dimensions<PointUtf16, usize>>(());
|
||||
cursor.seek(&point, Bias::Left);
|
||||
let overshoot = point - cursor.start().0;
|
||||
cursor.start().1
|
||||
+ cursor.item().map_or(0, |chunk| {
|
||||
let (start, _, item) =
|
||||
self.chunks
|
||||
.find::<Dimensions<PointUtf16, usize>, _>((), &point, Bias::Left);
|
||||
let overshoot = point - start.0;
|
||||
start.1
|
||||
+ item.map_or(0, |chunk| {
|
||||
chunk.as_slice().point_utf16_to_offset(overshoot, clip)
|
||||
})
|
||||
}
|
||||
|
|
@ -475,11 +478,12 @@ impl Rope {
|
|||
if point.0 >= self.summary().lines_utf16() {
|
||||
return self.summary().lines;
|
||||
}
|
||||
let mut cursor = self.chunks.cursor::<Dimensions<PointUtf16, Point>>(());
|
||||
cursor.seek(&point.0, Bias::Left);
|
||||
let overshoot = Unclipped(point.0 - cursor.start().0);
|
||||
cursor.start().1
|
||||
+ cursor.item().map_or(Point::zero(), |chunk| {
|
||||
let (start, _, item) =
|
||||
self.chunks
|
||||
.find::<Dimensions<PointUtf16, Point>, _>((), &point.0, Bias::Left);
|
||||
let overshoot = Unclipped(point.0 - start.0);
|
||||
start.1
|
||||
+ item.map_or(Point::zero(), |chunk| {
|
||||
chunk.as_slice().unclipped_point_utf16_to_point(overshoot)
|
||||
})
|
||||
}
|
||||
|
|
@ -492,33 +496,30 @@ impl Rope {
|
|||
}
|
||||
|
||||
pub fn clip_offset_utf16(&self, offset: OffsetUtf16, bias: Bias) -> OffsetUtf16 {
|
||||
let mut cursor = self.chunks.cursor::<OffsetUtf16>(());
|
||||
cursor.seek(&offset, Bias::Right);
|
||||
if let Some(chunk) = cursor.item() {
|
||||
let overshoot = offset - cursor.start();
|
||||
*cursor.start() + chunk.as_slice().clip_offset_utf16(overshoot, bias)
|
||||
let (start, _, item) = self.chunks.find::<OffsetUtf16, _>((), &offset, Bias::Right);
|
||||
if let Some(chunk) = item {
|
||||
let overshoot = offset - start;
|
||||
start + chunk.as_slice().clip_offset_utf16(overshoot, bias)
|
||||
} else {
|
||||
self.summary().len_utf16
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clip_point(&self, point: Point, bias: Bias) -> Point {
|
||||
let mut cursor = self.chunks.cursor::<Point>(());
|
||||
cursor.seek(&point, Bias::Right);
|
||||
if let Some(chunk) = cursor.item() {
|
||||
let overshoot = point - cursor.start();
|
||||
*cursor.start() + chunk.as_slice().clip_point(overshoot, bias)
|
||||
let (start, _, item) = self.chunks.find::<Point, _>((), &point, Bias::Right);
|
||||
if let Some(chunk) = item {
|
||||
let overshoot = point - start;
|
||||
start + chunk.as_slice().clip_point(overshoot, bias)
|
||||
} else {
|
||||
self.summary().lines
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clip_point_utf16(&self, point: Unclipped<PointUtf16>, bias: Bias) -> PointUtf16 {
|
||||
let mut cursor = self.chunks.cursor::<PointUtf16>(());
|
||||
cursor.seek(&point.0, Bias::Right);
|
||||
if let Some(chunk) = cursor.item() {
|
||||
let overshoot = Unclipped(point.0 - cursor.start());
|
||||
*cursor.start() + chunk.as_slice().clip_point_utf16(overshoot, bias)
|
||||
let (start, _, item) = self.chunks.find::<PointUtf16, _>((), &point.0, Bias::Right);
|
||||
if let Some(chunk) = item {
|
||||
let overshoot = Unclipped(point.0 - start);
|
||||
start + chunk.as_slice().clip_point_utf16(overshoot, bias)
|
||||
} else {
|
||||
self.summary().lines_utf16()
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue