GeWuYou a79f02c987 docs(api): 添加 Core API 参考文档与事件系统接口文档
- 新增 Core API 参考文档,涵盖架构与模块、数据模型与系统、命令与查询等核心组件
- 添加事件系统接口详细文档,包括 IEvent、IEventBus、IUnRegister 等接口说明
- 提供完整的 API 使用示例路径、最佳实践与性能建议
- 包含架构图、依赖关系图与故障排查指南
- 添加测试用例参考与扩展方法说明
- [skip ci]
2026-01-21 23:45:10 +08:00

22 KiB
Raw Blame History

性能优化

**本文引用的文件** - [GFramework.Core/coroutine/CoroutineScheduler.cs](file://GFramework.Core/coroutine/CoroutineScheduler.cs) - [GFramework.Core/coroutine/CoroutineSlot.cs](file://GFramework.Core/coroutine/CoroutineSlot.cs) - [GFramework.Core/coroutine/CoroutineHandle.cs](file://GFramework.Core/coroutine/CoroutineHandle.cs) - [GFramework.Core/coroutine/CoroutineHelper.cs](file://GFramework.Core/coroutine/CoroutineHelper.cs) - [GFramework.Core/pool/AbstractObjectPoolSystem.cs](file://GFramework.Core/pool/AbstractObjectPoolSystem.cs) - [GFramework.Core/events/EventBus.cs](file://GFramework.Core/events/EventBus.cs) - [GFramework.Core/events/EasyEvents.cs](file://GFramework.Core/events/EasyEvents.cs) - [GFramework.Core/events/EasyEvent.cs](file://GFramework.Core/events/EasyEvent.cs) - [GFramework.Core/query/AsyncQueryBus.cs](file://GFramework.Core/query/AsyncQueryBus.cs) - [GFramework.Core/command/CommandBus.cs](file://GFramework.Core/command/CommandBus.cs) - [GFramework.Core/ioc/IocContainer.cs](file://GFramework.Core/ioc/IocContainer.cs) - [GFramework.Core/architecture/Architecture.cs](file://GFramework.Core/architecture/Architecture.cs) - [GFramework.Core/system/AbstractSystem.cs](file://GFramework.Core/system/AbstractSystem.cs) - [GFramework.Core/logging/ConsoleLogger.cs](file://GFramework.Core/logging/ConsoleLogger.cs) - [GFramework.Core.Abstractions/pool/IPoolableObject.cs](file://GFramework.Core.Abstractions/pool/IPoolableObject.cs) - [GFramework.Core/pool/README.md](file://GFramework.Core/pool/README.md)

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖分析
  7. 性能考量
  8. 故障排查指南
  9. 结论
  10. 附录

简介

本文件面向GFramework的性能优化实践围绕内存管理、协程调度、事件系统、资源加载与性能监控五大主题结合代码库中的实际实现给出可落地的最佳实践与优化建议。内容兼顾工程效率与长期维护性帮助团队在保证稳定性的同时获得更佳的运行时表现。

项目结构

GFramework采用分层与模块化组织核心能力集中在Core层Godot适配位于GFramework.Godot游戏业务位于GFramework.Game。与性能优化直接相关的关键目录如下

  • coroutine协程调度与等待指令
  • pool对象池系统
  • events事件总线与事件管理
  • query/command查询/命令总线
  • ioc依赖注入容器
  • architecture/system架构生命周期与系统基类
  • logging日志基础设施
graph TB
subgraph "核心层(Core)"
A["architecture/Architecture.cs"]
B["system/AbstractSystem.cs"]
C["ioc/IocContainer.cs"]
D["coroutine/CoroutineScheduler.cs"]
E["pool/AbstractObjectPoolSystem.cs"]
F["events/EventBus.cs"]
G["query/AsyncQueryBus.cs"]
H["command/CommandBus.cs"]
end
subgraph "Godot适配(Godot)"
GD1["coroutine/GodotTimeSource.cs"]
end
A --> C
A --> D
A --> E
A --> F
A --> G
A --> H
D -.-> GD1

图表来源

章节来源

核心组件

  • 协程调度器:负责协程的创建、推进、暂停/恢复、终止与等待链管理,内置槽位数组与元数据映射,支持按标签批量终止。
  • 对象池系统提供键控对象池支持Acquire/Release/Clear与系统生命周期联动降低GC压力。
  • 事件系统:基于类型事件的注册/注销/触发,支持全局事件管理器与泛型事件自动创建。
  • 查询/命令总线:同步/异步执行查询与命令,参数校验与异常处理。
  • 依赖注入容器:线程安全注册与获取,支持冻结后禁止修改,便于运行期稳定。
  • 架构生命周期:统一组件初始化/销毁流程,阶段化通知,便于性能敏感组件的有序启动与回收。

章节来源

架构总览

下图展示与性能优化强相关的组件交互:架构负责注册与生命周期管理,容器提供线程安全的依赖解析,调度器驱动协程,事件系统承载解耦通信,对象池降低内存分配,查询/命令总线支撑数据与控制流。

graph TB
Arch["架构(Architecture)"]
Ctx["上下文(ArchitectureContext)"]
IOC["容器(IocContainer)"]
Sys["系统(AbstractSystem)"]
Pool["对象池(AbstractObjectPoolSystem)"]
Coro["协程调度器(CoroutineScheduler)"]
Ev["事件总线(EventBus)"]
Q["查询总线(AsyncQueryBus)"]
Cmd["命令总线(CommandBus)"]
Arch --> IOC
Arch --> Coro
Arch --> Ev
Arch --> Q
Arch --> Cmd
Arch --> Pool
Arch --> Sys
IOC --> Sys
Sys --> Pool
Sys --> Coro
Sys --> Ev
Sys --> Q
Sys --> Cmd

图表来源

详细组件分析

协程调度器性能优化

  • 设计要点
    • 固定容量槽位数组+元数据字典O(1)定位与状态管理。
    • 预热机制在Run时推进首个MoveNext减少首帧等待。
    • 等待指令链式推进异常捕获后主动Complete避免悬挂。
    • 支持WaitForCoroutine等待链唤醒减少轮询成本。
    • 标签索引支持按标签批量终止,便于场景切换时的资源回收。
  • 性能建议
    • 合理设置初始容量,避免频繁扩容;扩容为倍增,注意峰值协程数。
    • 使用WaitForFrames/WaitOneFrame替代轮询降低Update循环开销。
    • 为长耗时协程设置超时/取消路径,配合标签批量终止。
    • 将高频短协程合并为单次Update内的多次MoveNext减少调度抖动。
  • 关键路径
    • Run创建槽位、元数据、预热、活跃计数+1。
    • Update遍历槽位处理Waiting、MoveNext、异常处理。
    • Complete回收槽位、移除标签、唤醒等待者。
    • Expand容量翻倍注意峰值内存占用。
classDiagram
class CoroutineScheduler {
+DeltaTime : double
+ActiveCoroutineCount : int
+Run(coroutine, tag) CoroutineHandle
+Update() void
+Pause(handle) bool
+Resume(handle) bool
+Kill(handle) bool
+WaitForCoroutine(current, target) void
+KillByTag(tag) int
+Clear() int
}
class CoroutineSlot {
+Enumerator : IEnumerator
+State : CoroutineState
+Waiting : IYieldInstruction
}
class CoroutineHandle {
+IsValid : bool
+Key : byte
}
CoroutineScheduler --> CoroutineSlot : "管理"
CoroutineScheduler --> CoroutineHandle : "索引"

图表来源

章节来源

对象池系统性能优化

  • 设计要点
    • 基于字典+栈的键控池Acquire优先弹栈空则Create。
    • 与AbstractSystem生命周期集成系统销毁时统一调用OnPoolDestroy。
    • 支持Clear一次性销毁所有池内对象避免碎片化残留。
  • 性能建议
    • 明确对象池键域,避免键爆炸导致字典膨胀。
    • 限制池大小或动态调整上限,防止内存占用随时间增长。
    • 在OnAcquire/OnRelease中做最小必要重置避免昂贵操作。
    • 与协程/事件配合避免在Update中频繁创建临时对象。
  • 关键路径
    • Acquire取栈顶或Create调用OnAcquire。
    • Release调用OnRelease压栈。
    • Clear遍历所有对象调用OnPoolDestroy并清空字典。
flowchart TD
Start(["进入Acquire"]) --> CheckPool["检查池是否存在"]
CheckPool --> Exists{"池存在?"}
Exists --> |否| NewPool["创建新栈"]
Exists --> |是| Pop["弹栈取对象"]
NewPool --> Create["Create(key)"]
Pop --> HasObj{"栈非空?"}
HasObj --> |是| OnAcquire["OnAcquire()"]
HasObj --> |否| Create
Create --> OnAcquire
OnAcquire --> Return["返回对象"]

图表来源

章节来源

事件系统性能优化

  • 设计要点
    • EventBus封装EasyEvents提供Send/Register/UnRegister。
    • EasyEvents全局单例+类型字典GetOrAddEvent避免重复创建。
    • EasyEvent简单事件聚合器支持注册/注销/触发。
  • 性能建议
    • 事件粒度拆分:高频事件拆分为细粒度事件,避免一次触发大量回调。
    • 事件批处理在Update末尾集中触发一批事件减少多次触发的开销。
    • 反注册及时不再使用的回调务必UnRegister避免回调链膨胀。
    • 事件过滤:在注册侧加入谓词过滤,减少无效回调执行。
  • 关键路径
    • Send()GetOrAddEvent() -> Trigger(new T())
    • Register()GetOrAddEvent() -> Register(onEvent)
sequenceDiagram
participant S as "发送方"
participant Bus as "EventBus"
participant Events as "EasyEvents"
participant Evt as "Event<T>"
S->>Bus : Send<T>()
Bus->>Events : GetOrAddEvent<Event<T>>()
Events-->>Bus : Event<T> 实例
Bus->>Evt : Trigger(new T())
Note over Bus,Evt : 触发所有已注册回调

图表来源

章节来源

查询/命令总线性能优化

  • 设计要点
    • AsyncQueryBus/Sync CommandBus均进行参数非空校验避免空引用异常。
    • 异步路径直接返回Task减少额外包装开销。
  • 性能建议
    • 将CPU密集型任务放入后台线程或协程避免阻塞主线程。
    • 对频繁小查询进行合并或缓存结果,减少重复计算。
    • 命令幂等化设计,避免重试导致的重复开销。
  • 关键路径
    • AsyncQueryBus.SendAsync校验 -> DoAsync()
    • CommandBus.Send/SendAsync校验 -> Execute/ExecuteAsync()
sequenceDiagram
participant Caller as "调用方"
participant QBus as "AsyncQueryBus"
participant Q as "IAsyncQuery<TResult>"
Caller->>QBus : SendAsync(query)
QBus->>Q : DoAsync()
Q-->>QBus : Task<TResult>
QBus-->>Caller : Task<TResult>

图表来源

章节来源

依赖注入容器性能优化

  • 设计要点
    • ReaderWriterLockSlim读写锁读多写少场景高效。
    • Contains/Get/GetAll/Freeze等操作均考虑线程安全与一致性。
    • 冻结后禁止注册,避免运行期不稳定。
  • 性能建议
    • 尽量在初始化阶段完成注册,避免运行期频繁注册/注销。
    • 使用GetAllSorted按优先级排序后调度减少运行时比较成本。
    • 避免过度注册同一实例,减少类型索引冲突与查找成本。
  • 关键路径
    • RegisterPlurality注册具体类型与所有接口。
    • GetAll快照返回避免并发修改影响。
classDiagram
class IocContainer {
-_lock : ReaderWriterLockSlim
-_frozen : bool
-_objects : HashSet<object>
-_typeIndex : Dictionary<Type, HashSet<object>>
+RegisterPlurality(instance) void
+Get<T>() T?
+GetRequired<T>() T
+GetAll<T>() IReadOnlyList<T>
+Freeze() void
}

图表来源

章节来源

架构生命周期与系统基类

  • 设计要点
    • Architecture统一组件注册、初始化与销毁阶段化通知。
    • AbstractSystem提供系统级日志与生命周期钩子。
  • 性能建议
    • 将重资源初始化放在After*Init阶段避免阻塞Ready。
    • 系统销毁逆序执行,确保依赖释放顺序正确。
    • 通过RegisterLifecycleHook在特定阶段执行性能敏感操作。
  • 关键路径
    • InitializeInternalAsync设置LoggerFactory、初始化Environment、调用用户Init、分阶段初始化组件、冻结容器、进入Ready。
stateDiagram-v2
[*] --> 初始化
初始化 --> BeforeUtilityInit
BeforeUtilityInit --> AfterUtilityInit
AfterUtilityInit --> BeforeModelInit
BeforeModelInit --> AfterModelInit
AfterModelInit --> BeforeSystemInit
BeforeSystemInit --> AfterSystemInit
AfterSystemInit --> Ready
Ready --> 销毁
销毁 --> 已销毁

图表来源

章节来源

依赖分析

  • 组件耦合
    • Architecture依赖IOC、EventBus、AsyncQueryBus、CommandBus、CoroutineScheduler、AbstractObjectPoolSystem。
    • AbstractSystem作为系统基类被各业务系统继承统一日志与生命周期。
    • IocContainer提供线程安全的注册/获取,贯穿系统初始化与运行期。
  • 外部依赖
    • 时间源ITimeSourceGodotTimeSource为协程调度提供DeltaTime。
    • 日志接口ILogger/ILoggerFactory为性能调试与诊断提供基础。
graph LR
Arch["Architecture"] --> IOC["IocContainer"]
Arch --> Coro["CoroutineScheduler"]
Arch --> Ev["EventBus"]
Arch --> Q["AsyncQueryBus"]
Arch --> Cmd["CommandBus"]
Arch --> Pool["AbstractObjectPoolSystem"]
Coro --> Time["ITimeSource(GodotTimeSource)"]
Arch --> Log["ILogger/Factory"]

图表来源

章节来源

性能考量

  • 内存管理
    • 使用对象池减少GC压力避免频繁分配在系统销毁时统一释放。
    • 限制池大小与动态调整,防止内存持续增长。
    • 在OnAcquire/OnRelease中做轻量重置避免在Update中创建临时对象。
  • 协程调度
    • 合理设置初始容量,避免扩容;使用固定帧等待指令替代轮询。
    • 为长协程设置超时/取消路径,配合标签批量终止。
    • 将高频短协程合并,减少调度抖动。
  • 事件系统
    • 拆分高频事件,减少单次触发回调数量。
    • 在Update末尾批处理事件降低多次触发开销。
    • 注册时加入过滤谓词,注销不再使用的回调。
  • 查询/命令总线
    • 将CPU密集型任务放入后台线程或协程避免阻塞主线程。
    • 合并与缓存查询结果,减少重复计算。
  • 依赖注入
    • 初始化阶段完成注册,避免运行期频繁注册/注销。
    • 使用GetAllSorted按优先级排序后调度减少运行时比较成本。
  • 日志与监控
    • 使用ILogger输出关键路径耗时与异常便于定位瓶颈。
    • 在关键节点埋点统计,如协程活跃数、事件触发次数、对象池命中率等。

[本节为通用指导,无需列出章节来源]

故障排查指南

  • 协程相关
    • 症状协程卡住或无法结束。排查点Waiting未完成、MoveNext异常被捕获后Complete、等待链是否正确唤醒。
    • 建议:为协程设置超时/取消,使用标签批量终止。
  • 对象池相关
    • 症状内存持续增长。排查点池未限制大小、对象未正确Release、系统销毁未调用Clear。
    • 建议实现池大小上限或动态调整策略确保OnPoolDestroy被调用。
  • 事件相关
    • 症状回调过多导致卡顿。排查点事件粒度过粗、未及时UnRegister。
    • 建议:拆分事件、在合适时机注销回调。
  • 容器相关
    • 症状:运行期注册失败。排查点:容器被冻结。
    • 建议:在初始化阶段完成注册,避免运行期修改。
  • 日志相关
    • 症状:日志过多影响性能。排查点:日志级别与输出设备。
    • 建议:调整最小日志级别,必要时关闭彩色输出。

章节来源

结论

通过对象池、协程调度、事件系统与依赖注入的协同优化GFramework能够在保证架构清晰与扩展性的同时显著降低GC压力、提升调度效率与系统稳定性。建议在项目实践中遵循本文的最佳实践并结合日志与监控持续迭代逐步形成适合自身业务的性能优化体系。

[本节为总结,无需列出章节来源]

附录

  • 协程辅助方法
    • 提供WaitForSeconds/WaitForOneFrame/WaitForFrames/WaitUntil/WaitWhile与重复调用工具便于构建高性能协程流程。
  • 性能监控建议
    • 统计ActiveCoroutineCount、事件触发次数、对象池Acquire/Release命中率、容器注册实例数等指标。
    • 在关键路径埋点输出到ILogger便于定位热点与瓶颈。

章节来源