As proposed in the past in #13577.
Replace TraitContainer.All() that uses the custom AllEnumerator with
TraitContainer.ApplyToAllX() that takes an action as argument.
The AllEnumerator.Current function show up in profiling reports since it is
used each tick multiple times for multiple traits. The function is 'heavy'
because it creates TraitPair<T>'s temporary objects for each actor
trait combination.
In the past about 20k ITick trait pairs were present during an average
multi player game.
Using an Apply function that takes an action avoid the need to create
these temporary objects.
To be able to still use 'DoTimed' somewhat efficiently the measurement
was moved to inside the trait container method.
Results in a 25% performance improvement in accessing all traits of
a certain type.
Apply function could be used for other TraitContainer functions as well
for further improvements.
Test result for calling on a dummy trait on 20k actors a 1000 times:
1315 ms traitcontainer.AllEnumerator (current)
989 ms traitcontainer.Apply (this commit)
Use the binary search invariant of the lists to find the actor quickly and remove the range of entries from the list in a single operation to avoid redundant copying otherwise caused by removing entries one by one.
- Made private methods static where possible (runtime can elide checking the object for null).
- Declared attribute classes as sealed (allows reflection on attributes to complete faster).
- Moved some static cctor's into field initializers (static cctor's are slower than static field initializers).
- Made classes static if they contained only static methods (can't create instances of useless objects).
- Use inferable Exts.Lazy and not new Lazy<T>().
- Added required STAThread attribute to CrashDialog.
- Removed unused parameters in private methods.
- Added Serializable attribute to exceptions.
- Added parameter name in calls to ArgumentNullException.
- Use of as operator instead of is + cast.
- Changed (x as Foo).Bar anti-pattern into ((Foo)x).Bar. Results in sensible cast exceptions on error rather than null dereferences.
- Removed unused method in NullShader.