Files
HomeAgent/docs/zh/experiments/plugin-arch/02-feasibility/exp4.go
dev 304cad0648 docs(plugin-arch): 归档插件架构迁移评估 + plan 第11节整改计划
- docs/zh/架构迁移评估.md: C ABI→子进程+共享内存完整迁移论证(1621行)
- docs/zh/experiments/: 18项可复跑可行性实验(架构评估的所有数字来源)
- plan.md §11: 11.1~11.9 插件架构缺陷修复清单(唯一权威编号)
- main 保持干净,本批次为 update 特性分支的整改起点
2026-08-31 11:45:52 +08:00

72 lines
1.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//go:build ignore
package main
import (
"fmt"
"os"
"sync/atomic"
"time"
"golang.org/x/sys/unix"
)
type ring struct {
writeSeq atomic.Uint64
cap uint64
slots []uint64
}
func main() {
fmt.Println("=== 实验 4事件环 post-and-forget vs 同步 Publish慢消费者场景===")
const tokens = 5000
// --- A. 现状:同步 Publish消费者慢 ---
slowHandler := func() { time.Sleep(20 * time.Microsecond) }
t0 := time.Now()
for i := 0; i < tokens; i++ { slowHandler() }
syncDur := time.Since(t0)
fmt.Printf("A 同步 Publish (慢消费者 20µs): %d token 耗时 %v → 均摊 %.1f µs/token\n",
tokens, syncDur, float64(syncDur.Microseconds())/tokens)
// --- B. 新方案:写环 + eventfd post不等消费者 ---
r := &ring{cap: 1024, slots: make([]uint64, 1024)}
efd, _ := unix.Eventfd(0, unix.EFD_NONBLOCK)
f := os.NewFile(uintptr(efd), "e")
var dropped atomic.Uint64
// 慢消费者 goroutine
done := make(chan struct{})
go func() {
buf := make([]byte, 8)
var readSeq uint64
for {
if _, err := f.Read(buf); err != nil { return }
w := r.writeSeq.Load()
if w-readSeq > r.cap {
dropped.Add(w - readSeq - r.cap)
readSeq = w - r.cap
}
for readSeq < w { readSeq++ }
time.Sleep(20 * time.Microsecond) // 慢
select { case <-done: return; default: }
}
}()
t0 = time.Now()
one := []byte{1,0,0,0,0,0,0,0}
for i := 0; i < tokens; i++ {
s := r.writeSeq.Add(1)
r.slots[s%r.cap] = s // 写数据
f.Write(one) // post不等
}
asyncDur := time.Since(t0)
close(done)
fmt.Printf("B 环+eventfd post: %d token 耗时 %v → 均摊 %.2f µs/token\n",
tokens, asyncDur, float64(asyncDur.Microseconds())/tokens)
fmt.Printf("\n加速比 %.1fx 丢弃事件 %d消费者跟不上已计数\n",
float64(syncDur)/float64(asyncDur), dropped.Load())
if asyncDur < syncDur/5 {
fmt.Println("✅ post-and-forget 使流式发布与消费者速度解耦")
}
}