Entitas
Entitas copied to clipboard
Generated code is suboptimal on IL2CPP target
Hi,
After updating to latest version we've noticed a considerable slowdown in Adding/Replacing components, after some investigation it turned out that Jenny started to generate code that contains typeof() which isn't really fast (in no AOT environment it is at least JIT'ed away, in IL2CPP it is slow every time it is called) before update generated code looked like this:
public partial class GameEntity {
public Level level { get { return (Level)GetComponent(GameComponentsLookup.Level); } }
public bool hasLevel { get { return HasComponent(GameComponentsLookup.Level); } }
public void AddLevel(string newName) {
var index = GameComponentsLookup.Level;
var component = CreateComponent<Level>(index);
component.name = newName;
AddComponent(index, component);
}
public void ReplaceLevel(string newName) {
var index = GameComponentsLookup.Level;
var component = CreateComponent<Level>(index);
component.name = newName;
ReplaceComponent(index, component);
}
public void RemoveLevel() {
RemoveComponent(GameComponentsLookup.Level);
}
}
and after it became:
public partial class GameEntity {
public Level level { get { return (Level)GetComponent(GameComponentsLookup.Level); } }
public bool hasLevel { get { return HasComponent(GameComponentsLookup.Level); } }
public void AddLevel(string newName) {
var index = GameComponentsLookup.Level;
var component = (Level)CreateComponent(index, typeof(Level));
component.name = newName;
AddComponent(index, component);
}
public void ReplaceLevel(string newName) {
var index = GameComponentsLookup.Level;
var component = (Level)CreateComponent(index, typeof(Level));
component.name = newName;
ReplaceComponent(index, component);
}
public void RemoveLevel() {
RemoveComponent(GameComponentsLookup.Level);
}
}
The latter isn't fast (Type_GetTypeFromHandle is what typeof becomes) All those GetTypeFromHandle amounted to 6% of all cpu time for my app and it is quite a lot.
This change is related to #780, but it does no quite the same thing as reporter suggested. I tried both reverting to old generated code and to follow the #780 author suggestion and in both cases the performance improved significantly.
Just thinking. Slowness of generic CreateComponent<T>
might come from usage of Activator.CreateInstance<T>();
it can safely be changed to new T()
.
Manual inlining without Activator
as suggested in improvement looks good too
Just thinking. Slowness of generic
CreateComponent<T>
might come from usage ofActivator.CreateInstance<T>();
it can safely be changed tonew T()
.
Actually, new T()
in generic method turns into Activator.CreateInstance<T>()
after compilation