FastEvent avatar

FastEvent [1.21.1] [1.20.1] [1.19.2]

Проект закрыт

Коротко говоря, подход к оптимизации по-прежнему применим, но Forge/NeoForge не позволяют модифицировать EventBus.

В отличие от классов самого Minecraft или Forge, EventBus загружается не как часть игры, а как "библиотека", что делает невозможным его изменение через Mixin или Transformer.

В версии 1.2.0, в попытке дальнейшего повышения производительности, были использованы нестандартные методы для изменения класса ASMEventHandler, которые, к сожалению, перестали работать в версиях 1.18.2+. Эти выпуски теперь заархивированы и, вероятно, не будут обновляться.

FastEvent

является модом-оптимизацией для Forge/Neoforge, улучшающим одну из фундаментальных систем в Forge: систему событий (Event system).

Насколько быстро

Создать тестовый сценарий для каждой поддерживаемой версии Minecraft сложно, особенно учитывая различия в системе событий между версиями. Поэтому ниже представлен отчет JMH-бенчмарка из PR, сделанного для проекта Cleanroom, где использовался тот же подход к оптимизации, что и в FastEvent:

Регистрация 10 000 слушателей событий, отправка события 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% быстрее.

Регистрация 1 000 слушателей событий, отправка события 10 000 раз:

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% быстрее.

Оригинальный PR

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

Как это работает

(Внимание, далее следуют технические детали)

Когда разработчики используют @EventBusSubscriber и/или @SubscribeEvent для подписки обработчиков событий, EventBus не может получить доступ к обработчику напрямую — ему доступен только объект Method. Наиболее прямой подход — использование этого объекта напрямую: method.invoke(...). Этот вызов в конечном итоге перенаправляется JVM обратно в исходный метод, позволяя обработчику события получить его после подписки.

Однако такой вызов (method.invoke(...)) крайне медленный. Для ускорения EventBus во время выполнения генерирует классы-обработчики событий для каждого найденного метода, устраняя дорогостоящий вызов на основе отражения (reflection).

Но генерация классов также приводит к замедлению. Для дальнейшего ускорения FastEvent заменяет генерацию классов созданием лямбда-выражений, ускоряя построение обработчиков событий. Дополнительное преимущество заключается в том, что лямбда-выражения являются "скрытыми", позволяя JVM выполнять более агрессивную оптимизацию.

Если вы знакомы с Java, следующие примеры кода могут быть более наглядными:

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

// EventBus сгенерирует новый класс для каждого обработчика события
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 использует лямбда-выражение для создания обработчика события
IEventListener handler = lis::onEvent;

Скачать FastEvent

 
Тип Скачать Версия Загрузчик Обновлено Размер
ReleaseFastEvent-1.16.5-1.2.0.jar1.16.5Forge18 июня 202534,9 КБ
ReleaseFastEvent-1.21.1-forge-1.1.1.jar1.21.1Forge19 мая 202531,8 КБ
AlphaNeoForge version not doing anything, do not use1.21.1NeoForge19 мая 202532,4 КБ
ReleaseFastEvent-1.16.5-1.1.1.jar1.16.5Forge14 мая 202532,7 КБ
ReleaseFastEvent-1.18.2-1.1.1.jar1.18.2Forge14 мая 202532,8 КБ
ReleaseFastEvent-1.19.2-1.1.1.jar1.19.2Forge14 мая 202532 КБ
ReleaseFastEvent-1.20.1-1.1.1.jar1.20.1Forge14 мая 202532 КБ
ReleaseFastEvent-1.16.5-1.1.0.jar1.16.5Forge25 апреля 202532,7 КБ
ReleaseFastEvent-1.18.2-1.1.0.jar1.18.2Forge25 апреля 202532,7 КБ
ReleaseFastEvent-1.19.2-1.1.0.jar1.19.2Forge25 апреля 202532 КБ
Пожалуйста авторизуйтесь, чтобы оставить свой комментарий.