import b from "benny" import { EventHub } from "../index" import { RawEvents } from "../lib/RawEvents" import mitt from "mitt" import EventEmitter from "eventemitter3" import tinyEmitter from "tiny-emitter" /** * Benchmark 内容 * - emit 单监听器 (single listener) * - emit 多监听器 (10 listeners) * - add + remove listener * - once 注册 + emit * * 说明: * - 每个测试在外部先完成必要的 setup(注册监听器等), * benny 的每一次执行会触发一次被测操作(例如一次 emit 或一次 add+remove)。 * - 使用简单的计数器以防止 JS 引擎做不必要的优化。 */ const ITER = 1 // benny 本身会重复运行,这里每次操作执行一次真实动作 // 实例化各个实现 const eventHub = new EventHub() const eventHub2 = new EventHub() const rawEvents = new RawEvents() const mitt_emitter = mitt() const eventemitter3 = new EventEmitter() const tiny_emitter = new tinyEmitter.TinyEmitter() // 全局计数器,避免被优化 let c_ehub = 0 let c_raw = 0 let c_mitt = 0 let c_ev3 = 0 let c_tiny = 0 // 单监听器注册(用于 single-emit 测试) eventHub.on("test", (d: any) => { c_ehub += d || 1 }) eventHub2.on("test", (d: any) => { /* 用于 noTypePath 测试 */ c_ehub += d || 1 }) rawEvents.on("test", (d: any) => { c_raw += d || 1 }) mitt_emitter.on("test", (d: any) => { c_mitt += d || 1 }) eventemitter3.on("test", (d: any) => { c_ev3 += d || 1 }) tiny_emitter.on("test", (d: any) => { c_tiny += d || 1 }) // 为 10 listeners 的测试准备监听器并注册(每个实现注册 10 个 listener) const makeHandlers = (ctrRefName: string, targetCounter: { val: number }) => { const handlers: Function[] = [] for (let i = 0; i < 10; i++) { const fn = ((idx: number) => (v?: any) => { targetCounter.val += (v || 1) })(i) handlers.push(fn) } return handlers } const c_ehub_10 = { val: 0 } const c_raw_10 = { val: 0 } const c_mitt_10 = { val: 0 } const c_ev3_10 = { val: 0 } const c_tiny_10 = { val: 0 } const handlers_ehub = makeHandlers("ehub", c_ehub_10) const handlers_raw = makeHandlers("raw", c_raw_10) const handlers_mitt = makeHandlers("mitt", c_mitt_10) const handlers_ev3 = makeHandlers("ev3", c_ev3_10) const handlers_tiny = makeHandlers("tiny", c_tiny_10) for (const h of handlers_ehub) eventHub.on("ten", h as any) for (const h of handlers_raw) rawEvents.on("ten", h as any) for (const h of handlers_mitt) mitt_emitter.on("ten", h as any) for (const h of handlers_ev3) eventemitter3.on("ten", h as any) for (const h of handlers_tiny) tiny_emitter.on("ten", h as any) // 现在构造 benny suite,比较多种操作 b.suite( "[AI] Event libs — emit / 10-list / add+remove / once", // Emit - single listener b.add("EventHub — emit (single)", () => { return () => { eventHub.emit("test", 1) } }), b.add("EventHub — emit (noTypePath)", () => { return () => { eventHub2.emit("test", 1, { noTypePath: true }) } }), b.add("RawEvents — emit (single)", () => { return () => { rawEvents.emit("test", 1) } }), b.add("mitt — emit (single)", () => { return () => { mitt_emitter.emit("test", 1) } }), b.add("eventemitter3 — emit (single)", () => { return () => { eventemitter3.emit("test", 1) } }), b.add("tiny-emitter — emit (single)", () => { return () => { tiny_emitter.emit("test", 1) } }), // Emit - with 10 listeners b.add("EventHub — emit (10 listeners)", () => { return () => { eventHub.emit("ten", 1) } }), b.add("RawEvents — emit (10 listeners)", () => { return () => { rawEvents.emit("ten", 1) } }), b.add("mitt — emit (10 listeners)", () => { return () => { mitt_emitter.emit("ten", 1) } }), b.add("eventemitter3 — emit (10 listeners)", () => { return () => { eventemitter3.emit("ten", 1) } }), b.add("tiny-emitter — emit (10 listeners)", () => { return () => { tiny_emitter.emit("ten", 1) } }), // add + remove listener (measure on/off) b.add("EventHub — add + remove", () => { return () => { const fn = () => { c_ehub++ } eventHub.on("adremo", fn, { noCloser: true }) // 使用 noCloser 避免自动返回 closer eventHub.off("adremo", fn) } }), b.add("RawEvents — add + remove", () => { return () => { const fn = () => { c_raw++ } rawEvents.on("adremo", fn) rawEvents.off("adremo", fn) } }), b.add("mitt — add + remove", () => { return () => { const fn = () => { c_mitt++ } mitt_emitter.on("adremo", fn) mitt_emitter.off("adremo", fn) } }), b.add("eventemitter3 — add + remove", () => { return () => { const fn = () => { c_ev3++ } eventemitter3.on("adremo", fn) // eventemitter3 对应的方法为 removeListener 或 off(根据版本),优先尝试 off(),否则 removeListener() if ((eventemitter3 as any).off) (eventemitter3 as any).off("adremo", fn) else eventemitter3.removeListener("adremo", fn) } }), b.add("tiny-emitter — add + remove", () => { return () => { const fn = () => { c_tiny++ } tiny_emitter.on("adremo", fn) tiny_emitter.off("adremo", fn) } }), // once behavior b.add("EventHub — once", () => { return () => { let called = 0 const fn = () => { called++ } // EventHub 没有直接 once,使用返回的 closer 或手动 off eventHub.on("once-test", fn) eventHub.emit("once-test", 1) eventHub.off("once-test", fn) } }), b.add("RawEvents — once", () => { return () => { rawEvents.once("once-test", (d: any) => { c_raw++ }) rawEvents.emit("once-test", 1) } }), b.add("mitt — once (simulate)", () => { return () => { const fn = (d: any) => { c_mitt++ ; mitt_emitter.off("once-test", fn) } mitt_emitter.on("once-test", fn) mitt_emitter.emit("once-test", 1) } }), b.add("eventemitter3 — once", () => { return () => { eventemitter3.once("once-test", () => { c_ev3++ }) eventemitter3.emit("once-test", 1) } }), b.add("tiny-emitter — once (simulate)", () => { return () => { const fn = (d: any) => { c_tiny++ ; tiny_emitter.off("once-test", fn) } tiny_emitter.on("once-test", fn) tiny_emitter.emit("once-test", 1) } }), // benny hooks b.cycle(), b.complete() )