FastEvent
模组属性评比

距离显示结果还剩4票~

路过的这位少侠,你觉得这款Mod怎么样,可否愿意来评一评它呢?登录并评比
更新日志
  • 暂无日志..

历史编辑记录更多
    管理组

      暂无管理组..

    编辑组

      暂无编辑组..

    开发组申请
    最近参与编辑
    活跃
    开源

    FastEvent

    0.0

    无人问津

    昨日指数: 37
    昨日平均指数: 81.252

    3589

    总浏览

    --

    资料填充率


    如何下载?
    • FastEvent

      是一个面向 Forge / NeoForge 的优化模组,优化了一个 Forge 中最基础的功能:事件系统。


      有多快

      为每一个 FastEvent 支持的 MC 版本写一个测试并不容易,特别是在各版本的事件系统都不一样的情况下。

      因此,作者只会提供一份 JMH 性能测试报告,这份报告来自他为 Cleanroom 项目撰写的一份性能优化 PR,其中的性能优化手法与 FastEvent 一样。


      注册 10000 个事件监听,发布事件 0 次:

      Benchmark                               Mode  Cnt     Score     Error  Units
      BusPerformanceTest.register10000Legacy  avgt    5  1126.498 ± 284.633  ms/op
      BusPerformanceTest.register10000Modern  avgt    5  1058.961 ± 173.586  ms/op

      大致快了 6.4%。


      注册 1000 个事件监听,发布事件 10000 次:

      Benchmark                                       Mode  Cnt     Score      Error  Units
      BusPerformanceTest.register1000test10000Legacy  avgt    5  4407.963 ± 4250.643  ms/op
      BusPerformanceTest.register1000test10000Modern  avgt    5  3550.578 ± 1991.352  ms/op

      大致快了 24%。


      来源:https://github.com/CleanroomMC/Cleanroom/pull/328#issuecomment-2801099504


      原理

      (警告:前有枯燥技术细节)原文如此

      当开发者们使用“@EventBusSubscriber”以及“@SubscribeEvent”注册事件监听时,事件系统并不能无中生有地得到事件监听对象,而是只能拿到一个记录了相关信息的“Method”对象。此时最为直接的做法就是直接使用这个对象:“method.invoke(...)”。这样的调用最终会被 JVM 重定向回原来的方法,这样就做到了让事件监听在事件被发布时受到发布的事件。


      但是“method.invoke(...)”性能上是非常缓慢的,为了让这个过程更快,Forge 的事件系统会在运行时为每个方法生成一个实现了事件监听功能的类,从而消除了性能代价高昂的反射调用。


      但生成类本身也会拖慢性能,为了进一步优化,FaseEvent 将生成类替换为了构造 lambda,从而提高了构造事件监听的速度。另一个好处是 lambda 对应的类是“隐藏”的,这意味着 JVM 不必确保外部可以访问实现事件监听的类的各种数据,因此可以更加彻底地进行优化。


      如果恰巧会一点 Java,以下的代码演示或许会更加好懂:

      class Listen {
          @SubscribeEvent
          public void onEvent(Event event) {
          }
      }
      Listen lis = new Listen();

      // 原有事件系统会为每一个事件监听生成一个类
      class IEventListener$Listen$onEvent implements IEventListener {
          private Listen instance;
          public IEventListener$Listen$onEvent(Listen instance) {
              this.instance = instance;
          }
          @Override
          public void invoke(Event event) {
              instance.onEvent(event);
          }
      }
      IEventListener handler = new IEventListener$Listen$onEvent(lis);

      // FastEvent 使用 lambda 生成事件监听
      IEventListener handler = lis::onEvent;

    短评加载中..