Optimize rendering by using Ropey::byte_slice
This avoids costly conversions via byte_to_char (which are then reversed back into bytes internally in Ropey). Reduces time spent in slice/byte_to_char from ~24% to ~5%.
This commit is contained in:
parent
c6bd105484
commit
59f05088b9
10
Cargo.lock
generated
10
Cargo.lock
generated
@ -862,10 +862,10 @@ checksum = "8c31b5c4033f8fdde8700e4657be2c497e7288f01515be52168c631e2e4d4086"
|
||||
[[package]]
|
||||
name = "ropey"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6b9aa65bcd9f308d37c7158b4a1afaaa32b8450213e20c9b98e7d5b3cc2fec3"
|
||||
source = "git+https://github.com/cessen/ropey#38531e083f8cf5c5b1aeb328361895fb5a9b867c"
|
||||
dependencies = [
|
||||
"smallvec",
|
||||
"str_indices",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1031,6 +1031,12 @@ version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d44a3643b4ff9caf57abcee9c2c621d6c03d9135e0d8b589bd9afb5992cb176a"
|
||||
|
||||
[[package]]
|
||||
name = "str_indices"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "283baa48c486e4c5e27b4d92c435db9eaceac236a74dab5e3293570e2c3fa4aa"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.88"
|
||||
|
@ -15,7 +15,8 @@ include = ["src/**/*", "README.md"]
|
||||
[dependencies]
|
||||
helix-loader = { version = "0.6", path = "../helix-loader" }
|
||||
|
||||
ropey = "1.3"
|
||||
# ropey = "1.3"
|
||||
ropey = { git = "https://github.com/cessen/ropey" }
|
||||
smallvec = "1.8"
|
||||
smartstring = "1.0.0"
|
||||
unicode-segmentation = "1.9"
|
||||
|
@ -333,10 +333,7 @@ fn next(&mut self) -> Option<RopeSlice<'a>> {
|
||||
}
|
||||
|
||||
if a < self.cur_chunk_start {
|
||||
let a_char = self.text.byte_to_char(a);
|
||||
let b_char = self.text.byte_to_char(b);
|
||||
|
||||
Some(self.text.slice(a_char..b_char))
|
||||
Some(self.text.byte_slice(a..b))
|
||||
} else {
|
||||
let a2 = a - self.cur_chunk_start;
|
||||
let b2 = b - self.cur_chunk_start;
|
||||
|
@ -576,9 +576,7 @@ pub struct Syntax {
|
||||
}
|
||||
|
||||
fn byte_range_to_str(range: std::ops::Range<usize>, source: RopeSlice) -> Cow<str> {
|
||||
let start_char = source.byte_to_char(range.start);
|
||||
let end_char = source.byte_to_char(range.end);
|
||||
Cow::from(source.slice(start_char..end_char))
|
||||
Cow::from(source.byte_slice(range))
|
||||
}
|
||||
|
||||
impl Syntax {
|
||||
@ -1197,9 +1195,7 @@ impl<'a> TextProvider<'a> for RopeProvider<'a> {
|
||||
type I = ChunksBytes<'a>;
|
||||
|
||||
fn text(&mut self, node: Node) -> Self::I {
|
||||
let start_char = self.0.byte_to_char(node.start_byte());
|
||||
let end_char = self.0.byte_to_char(node.end_byte());
|
||||
let fragment = self.0.slice(start_char..end_char);
|
||||
let fragment = self.0.byte_slice(node.start_byte()..node.end_byte());
|
||||
ChunksBytes {
|
||||
chunks: fragment.chunks(),
|
||||
}
|
||||
|
@ -183,6 +183,7 @@ pub fn doc_syntax_highlights<'doc>(
|
||||
.highlight_iter(text.slice(..), Some(range), None)
|
||||
.map(|event| event.unwrap())
|
||||
.map(move |event| match event {
|
||||
// TODO: use byte slices directly
|
||||
// convert byte offsets to char offset
|
||||
HighlightEvent::Source { start, end } => {
|
||||
let start =
|
||||
@ -317,6 +318,8 @@ pub fn render_text_highlights<H: Iterator<Item = HighlightEvent>>(
|
||||
theme: &Theme,
|
||||
highlights: H,
|
||||
) {
|
||||
// It's slightly more efficient to produce a full RopeSlice from the Rope, then slice that a bunch
|
||||
// of times than it is to always call Rope::slice/get_slice (it will internally always hit RSEnum::Light).
|
||||
let text = doc.text().slice(..);
|
||||
|
||||
let mut spans = Vec::new();
|
||||
@ -327,10 +330,6 @@ pub fn render_text_highlights<H: Iterator<Item = HighlightEvent>>(
|
||||
|
||||
let text_style = theme.get("ui.text");
|
||||
|
||||
// It's slightly more efficient to produce a full RopeSlice from the Rope, then slice that a bunch
|
||||
// of times than it is to always call Rope::slice/get_slice (it will internally always hit RSEnum::Light).
|
||||
let text = text.slice(..);
|
||||
|
||||
'outer: for event in highlights {
|
||||
match event {
|
||||
HighlightEvent::HighlightStart(span) => {
|
||||
|
Loading…
Reference in New Issue
Block a user