use cache to store char-to-column mapping
This is faster by O(n) to O(n²) compared to the previous algorithm that would re-compute the column for each call.
This commit is contained in:
@@ -45,7 +45,10 @@ class HighlightSelection(Highlight):
|
|||||||
|
|
||||||
start_column = line.char_to_column(start_char)
|
start_column = line.char_to_column(start_char)
|
||||||
end_column = line.char_to_column(end_char)
|
end_column = line.char_to_column(end_char)
|
||||||
length_in_columns = end_column - start_column
|
if end_column >= 0:
|
||||||
|
length_in_columns = end_column - start_column
|
||||||
|
else:
|
||||||
|
length_in_columns = 4096
|
||||||
|
|
||||||
return [HighlightedRange(start_column, length_in_columns, brush=QBrush(QColor(156, 215, 255, 192)),
|
return [HighlightedRange(start_column, length_in_columns, brush=QBrush(QColor(156, 215, 255, 192)),
|
||||||
pen=Qt.PenStyle.NoPen)]
|
pen=Qt.PenStyle.NoPen)]
|
||||||
|
|||||||
17
line.py
17
line.py
@@ -1,3 +1,5 @@
|
|||||||
|
from typing import Dict
|
||||||
|
|
||||||
import constants
|
import constants
|
||||||
|
|
||||||
|
|
||||||
@@ -6,6 +8,7 @@ class Line:
|
|||||||
self._byte_offset = byte_offset
|
self._byte_offset = byte_offset
|
||||||
self._byte_end = byte_end
|
self._byte_end = byte_end
|
||||||
self._line = line
|
self._line = line
|
||||||
|
self._char_to_column_cache = self._cache_char_to_column()
|
||||||
|
|
||||||
def byte_offset(self) -> int:
|
def byte_offset(self) -> int:
|
||||||
return self._byte_offset
|
return self._byte_offset
|
||||||
@@ -63,17 +66,25 @@ class Line:
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
# todo this method is slow
|
|
||||||
def char_to_column(self, char_in_line: int) -> int:
|
def char_to_column(self, char_in_line: int) -> int:
|
||||||
|
if not char_in_line in self._char_to_column_cache:
|
||||||
|
# print("%d in %s" % (char_in_line, self._char_to_column_cache))
|
||||||
|
return -1
|
||||||
|
return self._char_to_column_cache[char_in_line]
|
||||||
|
|
||||||
|
def _cache_char_to_column(self) -> Dict[int, int]:
|
||||||
|
char_to_column_cache = {}
|
||||||
result = 0
|
result = 0
|
||||||
i = 0
|
i = 0
|
||||||
while i < char_in_line:
|
char_to_column_cache[0] = 0
|
||||||
|
while i < len(self._line):
|
||||||
if i < len(self._line) and self._line[i] == "\t":
|
if i < len(self._line) and self._line[i] == "\t":
|
||||||
result = result + constants.tab_width - result % constants.tab_width
|
result = result + constants.tab_width - result % constants.tab_width
|
||||||
else:
|
else:
|
||||||
result = result + 1
|
result = result + 1
|
||||||
i = i + 1
|
i = i + 1
|
||||||
return result
|
char_to_column_cache[i] = result
|
||||||
|
return char_to_column_cache
|
||||||
|
|
||||||
def includes_byte(self, byte: int) -> bool:
|
def includes_byte(self, byte: int) -> bool:
|
||||||
return self._byte_offset <= byte <= self._byte_end
|
return self._byte_offset <= byte <= self._byte_end
|
||||||
|
|||||||
Reference in New Issue
Block a user