summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBlaž Hrastnik2022-01-17 07:28:56 +0000
committerBlaž Hrastnik2022-03-17 00:29:47 +0000
commit59f05088b9628086b35631338e49ae8f061dcba2 (patch)
treeb8e87e318e2194a9473aca0ce799a4e32bffa33a
parentc6bd105484fbaf35812dddc41b8fb32cb054fc54 (diff)
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%.
-rw-r--r--Cargo.lock10
-rw-r--r--helix-core/Cargo.toml3
-rw-r--r--helix-core/src/graphemes.rs5
-rw-r--r--helix-core/src/syntax.rs8
-rw-r--r--helix-term/src/ui/editor.rs7
5 files changed, 16 insertions, 17 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 80645e1e..060f93e8 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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]]
@@ -1032,6 +1032,12 @@ 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"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/helix-core/Cargo.toml b/helix-core/Cargo.toml
index 8152da57..3e5aabaa 100644
--- a/helix-core/Cargo.toml
+++ b/helix-core/Cargo.toml
@@ -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"
diff --git a/helix-core/src/graphemes.rs b/helix-core/src/graphemes.rs
index aa898684..c0c61775 100644
--- a/helix-core/src/graphemes.rs
+++ b/helix-core/src/graphemes.rs
@@ -333,10 +333,7 @@ impl<'a> Iterator for RopeGraphemes<'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;
diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs
index 3fc91efc..f76683b9 100644
--- a/helix-core/src/syntax.rs
+++ b/helix-core/src/syntax.rs
@@ -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(),
}
diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs
index 31a9bfc8..2b9de5d6 100644
--- a/helix-term/src/ui/editor.rs
+++ b/helix-term/src/ui/editor.rs
@@ -183,6 +183,7 @@ impl EditorView {
.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 @@ impl EditorView {
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 @@ impl EditorView {
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) => {