perf(输入法): 降低查词与候选内存开销并放大等尺寸26键

这个提交包含在:
sydxky 于 2026-11-14 20:39:54 +08:00 提交
1 父节点 100757f684
当前提交 7cd1ab906c
33 个文件已更改
+513 -126

没有与搜索条件相匹配的文件

@@ -48,6 +48,19 @@ def from94(value):
number = number * 94 + ord(ch) - 33
return number
def presence(names,alphabet,lengths,prefix):
masks=[]
for length in lengths:
mask=bytearray((len(alphabet)**length+7)//8)
for name in names:
code=name[len(prefix):] if name.startswith(prefix) else ''
if len(code)!=length or any(ch not in alphabet for ch in code):continue
index=0
for ch in code:index=index*len(alphabet)+alphabet.index(ch)
mask[index//8]|=1<<(index%8)
masks.append(mask.hex())
return masks
def convert(source, target):
target.parent.mkdir(parents=True, exist_ok=True)
assert target.resolve().is_relative_to((APP/'src/assets').resolve())
@@ -124,6 +137,15 @@ def _convert(source, target):
predictive_largest_shard_bytes=max((target/(name+'.json')).stat().st_size for name in [*association_shards,*completion_shards]),
source_files={name:hashlib.sha256(data).hexdigest() for name,data in sorted(files.items())})
if frequency_path.exists():report['t9_frequency_source']={'project':'jieba 0.42.1','license':'MIT','sha256':hashlib.sha256(frequency_path.read_bytes()).hexdigest()}
# Runtime needs only presence bits, not thousands of filenames and audit data.
runtime={'version':1,'short':presence(shards,'23456789',range(1,4),'s'),
'long':presence([name for name in shards if re.fullmatch('[2-9]{4}',name)],'23456789',[4],''),
'dualShort':presence(shards,'0123456789abcd',range(1,3),'ds'),
'dualLong':presence([name for name in shards if re.fullmatch('d[0-9a-d]{3}',name)],'0123456789abcd',[3],'d'),
'associations':presence(association_shards,'0123456789abcdef',[2],'a'),
'completions':presence(completion_shards,'0123456789abcdef',[2],'c')}
output=target/'runtime.json';data=(json.dumps(runtime,separators=(',',':'))+'\n').encode('utf-8')
if not output.exists() or output.read_bytes()!=data:output.write_bytes(data)
output=target/'meta.json';data=(json.dumps(report, ensure_ascii=False, indent=2)+'\n').encode('utf-8')
if not output.exists() or output.read_bytes()!=data:output.write_bytes(data)
print(json.dumps({**{k:v for k,v in report.items() if k not in ['source_files','shards']},'shards':len(shards)}, ensure_ascii=False))