成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

用 Windsurf 從0實現(xiàn)高性能JSON解析器

發(fā)布于 2025-5-13 00:45
瀏覽
0收藏

為了探索和改進 AI 工具在編程方面的體驗,同時也想驗證一些 AI 的邊界,于是又想到了嘗試從 0 實現(xiàn)高性能JSON解析器,說干就干。開始以為比較簡單,不會超過半天就能實現(xiàn),但是經(jīng)過各種提示詞優(yōu)化,最終花了兩天時間...

1. 選用工具

現(xiàn)在有各種 AI Copilot,比較常用的 Cursor,Windsurf,Trae 等,不過我現(xiàn)在用的比較順手的是:Windsurf。除了編程工具,然后就是模型,目前代碼領(lǐng)域比較強的:

  • Claude 3.7 Sonnet 和 Claude 3.7 Sonnet Thinking
  • GPT-4.1
  • o4-mini-high
  • Gemini 2.5 Pro

我在 Windsurf 上,使用 Claude 3.7 Sonnet 和 GPT-4.1 互相切換,簡單問題 GPT-4.1 能快速解決,復雜的問題可以嘗試 Claude 3.7 Sonnet 和 Thinking 分析,不過在使用過程中發(fā)現(xiàn) Gemini 2.5 Pro 在分析性能上很強大,但是上下文不太夠(可能是 Windsurf 上下文導致 prompt 太多了),對于代碼超過 200 行的效果不是很好。

2. Prompt

如果使用輔助編程工具,其實 Prompt 不是特別重要,對于開發(fā)者最重要的是如何把需求描述清楚。

比如本項目最開始的 Prompt 是:

用 golang 實現(xiàn)一個類似標準庫 "encoding/json" 的 JSON 解析器,可以參考 github 的 cJSON

通過如上 Prompt,將會獲得比較粗的代碼實現(xiàn),這個時候不應該基于是實現(xiàn)其他的功能,而是開始讓 AI 幫你生成測試用例:

基于 @lexer.go 生成測試用例,其中測試用例需要覆蓋如下 token 的支持:
EOFToken                           // 文件結(jié)束標記
NumberToken                        // 數(shù)字標記,例如:123, 45.67
StringToken                        // 字符串標記,例如:"hello"
NullToken                          // null值標記
TrueToken                          // true布爾值標記
FalseToken                         // false布爾值標記
CommaToken                         // 逗號標記 ','
ColonToken                         // 冒號標記 ':'
LeftBraceToken                     // 左大括號標記 '{'
RightBraceToken                    // 右大括號標記 '}'
LeftBracketToken                   // 左方括號標記 '['
RightBracketToken                  // 右方括號標記 ']'

為什么生成測試用例很重要?(1)驗證代碼的功能性問題,當你的代碼覆蓋率做的足夠高,生成的代碼就更安全。(2)通過測試用例可以更好的提示 AI 生成代碼,類似觸發(fā) CoT(Chain of Thought)。(3)測試用例可以更好的幫助開發(fā)者理解獨立的模塊。

生成測試用例后,可能會遇到各種測試用例不通過的情況,Prompt 其實就將報錯信息輸入給 AI 即可:

@parser_test.go#L291-729 @types.go @parser.go 執(zhí)行測試用例出現(xiàn)棧溢出的錯誤:runtime: goroutine stack exceeds 1000000000-byte limit
runtime: sp=0x14020260340 stack=[0x14020260000, 0x14040260000]
fatal error: stack overflow

runtime stack:
runtime.throw({0x10308321f?, 0xa2284a1184611846?})
 /opt/homebrew/Cellar/go/1.24.1/libexec/src/runtime/panic.go:1101 +0x38 fp=0x16d4ced90 sp=0x16d4ced60 pc=0x102f9fff8
runtime.newstack()
 /opt/homebrew/Cellar/go/1.24.1/libexec/src/runtime/stack.go:1107 +0x45c fp=0x16d4ceed0 sp=0x16d4ced90 pc=0x102f8682c
runtime.morestack()
 /opt/homebrew/Cellar/go/1.24.1/libexec/src/runtime/asm_arm64.s:342 +0x70 fp=0x16d4ceed0 sp=0x16d4ceed0 pc=0x102fa57f0
...

需要注意: 測試用例一定要縮小范圍,并且測試用例最好按照 ??標記 #%d 類型錯誤: 期望 %v, 得到 %v???(參考如下代碼),讓 AI 更好的理解問題出在哪里(??期望 -> 得到??)。

比如本項目的測試用例都會將錯誤信息,原始信息等都打印出來:

for _, tt := range tests {
    testCase := tt // 避免閉包問題
    t.Run(testCase.name, func(t *testing.T) {
        lexer := NewLexer(testCase.input)
        for i, expected := range testCase.expected {
            got := lexer.NextToken()
            if got.Type != expected.Type {
                t.Errorf("標記 #%d 類型錯誤: 期望 %v, 得到 %v", i, expected.Type, got.Type)
            }
            if got.Value != expected.Value {
                t.Errorf("標記 #%d 值錯誤: 期望 %q, 得到 %q", i, expected.Value, got.Value)
            }
            if got.Pos != expected.Pos {
                t.Errorf("標記 #%d 位置錯誤: 期望 %d, 得到 %d", i, expected.Pos, got.Pos)
            }
        }
    })
}

3. 限制文件大小

從實踐經(jīng)驗來看,隨著功能的疊加,AI 生成的代碼在單個文件會越來越長,但是這樣會遇到一些問題(上下文限制,模型思考慢,問題分析不準確),因此需要定期將單個文件按照功能拆分多個文件,建議單個文件不超過 200 行(測試用例倒是不需要,由于測試用例是單一功能的),在 ??sjson?? 的代碼行數(shù)基本上都少于 200 行:

用 Windsurf 從0實現(xiàn)高性能JSON解析器-AI.x社區(qū)

4. 提供方向性的指引

提出一個問題 讓 AI 解決,可能方案有很多,比如 JSON 解析可以用方案:

  • 遞歸下降方法,邊解析邊賦值(流式解析)
  • 分階段解析(詞法+語法分析)

但是 AI 一開始并不一定能給出最優(yōu)的方案,比如本項目開始提供分階段解析方案,但是參考其他的開源項目,都是用流式解析,該方案對于 JSON 解析器比較合適(因為沒有需要動態(tài)計算的過程,所以掃一遍就可以處理,性能要比分段解析好),當然也要考慮業(yè)務(wù)場景,比如要實現(xiàn)動態(tài)腳本或者 ??expr?? 功能,分階段解析更合適,所以在實現(xiàn)之前可以先了解當前領(lǐng)域的知識并分析方案的優(yōu)劣勢(其實整個分析的過程也可以喂給 AI 來做判斷并糾正),然后讓 AI 按照提示的方向?qū)崿F(xiàn)。

不過值得注意的是,當提出用 JIT 等方案優(yōu)化,AI 會提示方案不合理(實現(xiàn)的確不合理,JIT 需要增加各種適配代碼)。

5. 充分的測試

??sjson??? 需要對比其他庫的功能是否完整,依賴 AI 通常不一定能給全所有的測試用例,所以需要找到測試套件,這里我參考開源項目 ??https://github.com/nst/JSONTestSuite???,修改 ??run_tests.py??:

programs = {
   "JavaScript":
       {
           "url":"",
           "commands":["node", os.path.join(PARSERS_DIR, "test_json.js")]
       },
   "Python 2.7.10":
       {
           "url":"",
           "commands":["python", os.path.join(PARSERS_DIR, "test_json.py")]
       },
    "sjson":
       {
           "url":"",
           "commands":["/Volumes/my/github/mylib/go/sjson/tests/example", "-a"]
       },
    "stdjson":
       {
           "url":"",
           "commands":["/Volumes/my/github/mylib/go/sjson/tests/example", "-b"]
       },
    "jsoniterator":
       {
           "url":"",
           "commands":["/Volumes/my/github/mylib/go/sjson/tests/example", "-c"]
       },
}

可以跑通 ??300+??? 個測試用例,其中與標準庫 ??encoding/json??? 和 ??Jsoniter?? 的對比如下:

用 Windsurf 從0實現(xiàn)高性能JSON解析器-AI.x社區(qū)

用 Windsurf 從0實現(xiàn)高性能JSON解析器-AI.x社區(qū)

6. 性能優(yōu)化

通過 AI 生成 ??Benchmark?? 函數(shù),然后進行性能的測試:

BenchmarkComplexJSON/Original-14          13598248       5525 ns/op     9993 B/op      178 allocs/op
BenchmarkComplexJSON/Optimized-14         12703338       5804 ns/op    10645 B/op      179 allocs/op
BenchmarkComplexJSON/Standard-14          17148706       4125 ns/op     5136 B/op      107 allocs/op

以上是第一輪的性能測試,比標準庫性能差了 60%,然后可以將當前性能測試數(shù)據(jù)當成 Prompt 輸入:

@sjson_marshal.go 性能測試如下:
BenchmarkComplexJSON/Original-14          13598248       5525 ns/op     9993 B/op      178 allocs/op
BenchmarkComplexJSON/Optimized-14         12703338       5804 ns/op    10645 B/op      179 allocs/op
BenchmarkComplexJSON/Standard-14          17148706       4125 ns/op     5136 B/op      107 allocs/op

基于當前性能對比進行性能優(yōu)化,比如增加緩存,減少 decode 次數(shù),減少 fmt.Sprintf 改為 byte[] 和 append 或者 strings.Builder,目標是減少內(nèi)存分配和數(shù)據(jù)拷貝次數(shù)。

...  ...

然后經(jīng)過一系列漫長的優(yōu)化,最后性能對比標準庫:

BenchmarkUnmarshalCompareMedium/SjsonUnmarshal-14           2203020       5576 ns/op     5923 B/op      115 allocs/op
BenchmarkUnmarshalCompareMedium/StdUnmarshal-14             1484354       8036 ns/op      504 B/op       11 allocs/op
BenchmarkUnmarshalCompareMedium/JsoniterUnmarshal-14        5908438       1986 ns/op      352 B/op       38 allocs/op

性能已經(jīng)比 ??encoding/json??? 標準庫提升 ??80%???,雖然比 ??Jsoniter??? 性能差(Jsoniter開啟了 ConfigFastest),但是可以嘗試引入 ??reflect2??? 等方案來提升性能,從 ??flamegraph?? 看需要對反射和拷貝的方向進行優(yōu)化:

用 Windsurf 從0實現(xiàn)高性能JSON解析器-AI.x社區(qū)

7. 后續(xù)

(1)代碼已經(jīng)開源:https://github.com/linkxzhou/mylib/tree/master/go/sjson(2)繼續(xù)性能優(yōu)化,嘗試探索讓 AI 如何對項目進行性能優(yōu)化和構(gòu)建 ??go pprof MCP Server??

本文轉(zhuǎn)載自???周末程序猿??,作者:周末程序猿

收藏
回復
舉報
回復
相關(guān)推薦
主站蜘蛛池模板: 欧美日韩在线精品 | 国产综合久久 | 性高湖久久久久久久久3小时 | caoporn国产精品免费公开 | 91精品久久久久久久久99蜜臂 | 国产精品久久久久久影院8一贰佰 | 91亚洲国产成人久久精品网站 | 天天久久 | 久久精品国产99国产 | 一级毛片高清 | 美女黄网站视频免费 | 日本中文字幕日韩精品免费 | 国产午夜精品一区二区 | 色视频在线观看 | 日韩在线一区二区 | 欧美涩| 免费小视频在线观看 | 国产精品久久九九 | 国产毛片久久久久久久久春天 | 综合亚洲视频 | 国产成人精品午夜 | 成人久久久久 | 亚洲国产精品成人 | 国产精品免费看 | www国产亚洲精品久久网站 | 91麻豆精品国产91久久久久久久久 | v亚洲| 中文字字幕一区二区三区四区五区 | 久久久久国产精品 | 亚洲av一级毛片 | 精品国产一区二区三区日日嗨 | 久久精品免费 | 日韩欧美中文字幕在线视频 | 亚洲免费观看视频网站 | www国产成人 | 日韩精品一区二区三区四区 | 欧美成年网站 | 日本一区二区在线视频 | 狠狠干夜夜草 | 亚洲欧洲一区二区 | 精品国产欧美在线 |