diff --git a/lib/vast/Tokenizer.py b/lib/vast/Tokenizer.py index 15b10db..ace5e9d 100644 --- a/lib/vast/Tokenizer.py +++ b/lib/vast/Tokenizer.py @@ -131,9 +131,6 @@ class Tokenizer: self.Comments: list[Token] = [] # 行起始字符索引表(索引 0 对应第 1 行),用于行列换算 self._LineStarts: list[int] = [0] - # _PosInfo 增量缓存:token 顺序创建时 pos 单调递增,免 bisect - self._LastLineIdx: int = 0 - self._LastPos: int = -1 # ------------------------------------------------------------------ # 位置换算 @@ -141,22 +138,14 @@ class Tokenizer: def _PosInfo(self, pos: int) -> tuple[int, int]: """将字符索引换算为 (1-based 行号, UTF-8 字节列偏移)。 - 优化(cProfile 热点:~300 万次调用):token 顺序创建时 pos 单调 - 递增,用上次行索引增量顺延替代 bisect(O(log n)→摊销 O(1)); - 列偏移对 ASCII 行用 len() 直接量取,避免每次 encode 分配字节串。 + 优化(cProfile 热点:~300 万次调用):列偏移对 ASCII 行用 len() + 直接量取,避免每次 encode 分配字节串。行查找保持 bisect(C 级 + _bisect,O(log n))——增量 while 顺延实测反而更慢(Python 循环 + 开销 > C bisect,且 _Make 先 start 后 end 两次调用跨行时退化)。 """ - ls: list[int] = self._LineStarts - if pos >= self._LastPos and self._LastLineIdx + 1 < len(ls): - idx: int = self._LastLineIdx - nls: int = len(ls) - while idx + 1 < nls and ls[idx + 1] <= pos: - idx += 1 - else: - idx = bisect.bisect_right(ls, pos) - 1 - self._LastLineIdx = idx - self._LastPos = pos + idx: int = bisect.bisect_right(self._LineStarts, pos) - 1 line: int = idx + 1 - seg: str = self.Source[ls[idx]:pos] + seg: str = self.Source[self._LineStarts[idx]:pos] if seg.isascii(): col_bytes: int = len(seg) else: