-
Notifications
You must be signed in to change notification settings - Fork 114
Hotspot optimization technical details
Adrian Papari edited this page May 31, 2016
·
2 revisions
While the JVM is fast at invoking methods, it is somewhat more expensive for the JVM to call megamorphic methods like EntityProcessingSystem#process(Entity)
. This is compounded by the fact that it's invoked once per entity per system. By performing an extra compile-time/post-compile step you can decrease Artemis overhead by 25-35%. Full benchmarks can be found at junkdog/entity-system-benchmarks.
Normally, when invoking World#process
, an EntityProcessingSystem
is invoked as follows:
-
EntitySystem#process
: method is declared final so only one implementation - cheap for the JVM to call -
EntitySystem#process
makes a call to abstract method#processEntities
: since this one has several implementations, method invocation is much slower (10-20x is often cited, but regardless, it's much slower) - though it doesn't really matter since it's only called once per system and tick. -
EntityProcessingSystem#processEntities
- the most common parent for concrete entity systems - declaresprotected abstract void process(Entity e);
; asEntityProcessingSystem#process(Entity)
is likely to be one of the most frequently executed methods AND has multiple implementations (one for each concrete entity processing system), the higher method invocation cost builds up - In summary:
-
EntitySystem#process
: monomorphic -
EntityProcessingSystem#processEntities
: megamorphic -
EntityProcessingSystem#process(Entity)
: megamorphic and invoked once per entity per system, every tick.
Ideally, we'd like to get rid of the expensive call to EntityProcessingSystem#process(Entity)
,
- Scans all classes, looking for those directly extending EntityProcessingSystem
- Replaces super class:
s/EntityProcessingSystem/EntitySystem
- Injects processEntities, copied from EntityProcessingSystem. Method is already megamorphic, so it doesn't affect performance noticeably if we add a few more.
- Rewrite
#process(Entity)
as a private method (override behavior with@PreserveProcessVisiblity
)- Since
#process(Entity)
is only declared abstract inEntityProcessingSystem
, we are no longer invoking a polymorphic method; ie, the method is now monomorphic.
- Since
- Overview
- Concepts
- Getting Started
- Using
- More guides
- Plugins
- Game Gallery
- Tools and Frameworks
- API reference