Optimize ComponentList.GetAll by getting rid of LINQ
The combination of recursion and LINQ allocated a lot of garbage in GetAll, this would result in a heap reallocation during many GetAll calls.
Removing LINQ yielded a nice performance improvement.
Getting rid of the recursion gives another tiny performance improvement, but not big enough to justify the reduction in code readability.
I can not show results directly for ComponentList.GetAll, because the function executes too fast after the optimization and is no longer captured by the sample profiler.
But here are the improvements for PhysiscsWorld.OnIntersection, which makes heavy use of ComponentList.GetAll internally via InvokeListeners<T>().
Before:
Function Name: Sandbox.PhysicsWorld.OnIntersection
Number of Functions: 2907
Total time: 9s 406ms 99µs
Maximum: 11ms 86µs
Top Quartile: 3ms 848µs
Average: 3ms 235µs
Median: 3ms 176µs
Bottom Quartile: 2ms 684µs
Minimum: 20µs
After:
Function Name: Sandbox.PhysicsWorld.OnIntersection
Number of Functions: 2779
Total time: 3s 661ms 358µs
Maximum: 6ms 971µs
Top Quartile: 1ms 552µs
Average: 1ms 317µs
Median: 1ms 220µs
Bottom Quartile: 975µs
Minimum: 19µs
Related to sbox-deathmatch/issues/104