perf(vast): 回滚 _PosInfo 增量行查找(Python while 慢于 C bisect)

新 cProfile(232s)显示 _PosInfo tottime 1.74s→2.84s:增量 while 顺延的 Python 循环开销大于 _bisect(C 级 O(log n)),且 _Make 先 start 后 end 两次调用跨行时退化。回滚为 bisect + 保留 isascii 快速路径(避免 encode 分配)。
This commit is contained in:
TermiNexus committed 2026-08-17 19:46:14 +08:00
1 parent 08e7b8d0c0
commit 2dbf348329
1 file changed
+6 -17
+6 -17
View File
@@ -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: