style: gofmt 归位(CI 之外的漂移)

This commit is contained in:
JianFeeeee
2026-10-27 12:18:27 +08:00
parent 051247e10f
commit 238f7b5c0b
5 changed files with 42 additions and 38 deletions

View File

@ -113,5 +113,3 @@ func TestFirstSemverLike(t *testing.T) {
t.Errorf("日期不应被识别为版本号,实际 %q", got) t.Errorf("日期不应被识别为版本号,实际 %q", got)
} }
} }

View File

@ -18,9 +18,9 @@ import (
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
"unicode/utf8"
"strings" "strings"
"unicode" "unicode"
"unicode/utf8"
"golang.org/x/text/unicode/norm" "golang.org/x/text/unicode/norm"
) )
@ -193,10 +193,12 @@ func stripAccents(text string) string {
// 不是 Unicode P*,但它们也是标点(HF 用的是 ASCII 码点区间)。 // 不是 Unicode P*,但它们也是标点(HF 用的是 ASCII 码点区间)。
// //
// ★ 性能改动:把「累积 rune slice + 每次 string(cur)」换成 // ★ 性能改动:把「累积 rune slice + 每次 string(cur)」换成
//
// 一趟扫描,段以**字节区间**表示,最后一次 substring。 // 一趟扫描,段以**字节区间**表示,最后一次 substring。
// pprof 实测(mid_zh)本函数占 alloc_objects 的 33.5%。 // pprof 实测(mid_zh)本函数占 alloc_objects 的 33.5%。
// //
// ★★ 但**非法 UTF-8 必须与旧实现逐值一致**:旧实现走 `[]rune(text)`, // ★★ 但**非法 UTF-8 必须与旧实现逐值一致**:旧实现走 `[]rune(text)`,
//
// 会把每个非法字节归一成 U+FFFD(`<60>`,3 字节);而纯字节切片会 // 会把每个非法字节归一成 U+FFFD(`<60>`,3 字节);而纯字节切片会
// **原样保留坏字节**。差分测试当场抓到这一分歧: // **原样保留坏字节**。差分测试当场抓到这一分歧:
// "\xbc\xef=..." → 旧 ["<22><>" ...] vs 新 ["\xbc\xef" ...] // "\xbc\xef=..." → 旧 ["<22><>" ...] vs 新 ["\xbc\xef" ...]
@ -204,6 +206,7 @@ func stripAccents(text string) string {
// 保留坏字节会让它进入本不该到达的地方(且 hash/去重会与旧行为不一致)。 // 保留坏字节会让它进入本不该到达的地方(且 hash/去重会与旧行为不一致)。
// //
// ⇒ 正确做法:**逐 rune 扫描**(utf8.DecodeRuneInString 对非法序列返回 // ⇒ 正确做法:**逐 rune 扫描**(utf8.DecodeRuneInString 对非法序列返回
//
// (RuneError, 1),与 []rune 同语义),但**不预先把整串转成 rune slice**; // (RuneError, 1),与 []rune 同语义),但**不预先把整串转成 rune slice**;
// 对非 ASCII/非法字节的段,用 strings.Builder 写回 RuneError 的 UTF-8, // 对非 ASCII/非法字节的段,用 strings.Builder 写回 RuneError 的 UTF-8,
// 从而与旧实现完全一致,同时省掉「整串 rune slice」那一块分配。 // 从而与旧实现完全一致,同时省掉「整串 rune slice」那一块分配。
@ -247,6 +250,7 @@ func splitOnPunctuation(text string) []string {
// wordpiece 贪心最长匹配;整词任一段无法匹配则该词整体退化为 [UNK]。 // wordpiece 贪心最长匹配;整词任一段无法匹配则该词整体退化为 [UNK]。
// //
// ★ 先定字节边界,再取一次 substring(而非每个候选都 string(runes[a:b])): // ★ 先定字节边界,再取一次 substring(而非每个候选都 string(runes[a:b])):
//
// pprof 实测(mid_zh)本函数占 alloc_objects 的 29.5%,是第二大分配源。 // pprof 实测(mid_zh)本函数占 alloc_objects 的 29.5%,是第二大分配源。
// 根因是内层循环**每轮候选都构造一个 string**: // 根因是内层循环**每轮候选都构造一个 string**:
// piece := string(runes[start:end]) // "##"+piece 又是第二次分配 // piece := string(runes[start:end]) // "##"+piece 又是第二次分配

View File

@ -83,6 +83,7 @@ func BenchmarkTokenizerEncode(b *testing.B) {
// BenchmarkTokenizerStages 分解流水线各段,用于定位真正的热点。 // BenchmarkTokenizerStages 分解流水线各段,用于定位真正的热点。
// //
// ★ 判据:若 wordpiece 占比远高于其它段,则「O(n²) 字符串分配」是主因; // ★ 判据:若 wordpiece 占比远高于其它段,则「O(n²) 字符串分配」是主因;
//
// 若 basicTokenize 的分配占比高,则 cleanText/tokenizeChineseChars 的 // 若 basicTokenize 的分配占比高,则 cleanText/tokenizeChineseChars 的
// strings.Builder 往返是主因。两者处方完全不同,不能凭直觉断言。 // strings.Builder 往返是主因。两者处方完全不同,不能凭直觉断言。
func BenchmarkTokenizerStages(b *testing.B) { func BenchmarkTokenizerStages(b *testing.B) {

View File

@ -221,6 +221,7 @@ func TestTokenizerDiff_Encode(t *testing.T) {
// //
// ★ 为什么必须测这个:字节层面扫描(新实现)与 rune 层面扫描(旧实现)在 // ★ 为什么必须测这个:字节层面扫描(新实现)与 rune 层面扫描(旧实现)在
// **非法 UTF-8** 上的行为最容易不同 —— // **非法 UTF-8** 上的行为最容易不同 ——
//
// · []rune(s) 把非法字节变成 U+FFFD(每个坏字节一个) // · []rune(s) 把非法字节变成 U+FFFD(每个坏字节一个)
// · utf8.DecodeRuneInString 返回 (RuneError, 1) 并前进 1 字节 // · utf8.DecodeRuneInString 返回 (RuneError, 1) 并前进 1 字节
// 两者语义应当一致,但「应当」不是证据。 // 两者语义应当一致,但「应当」不是证据。