Open Chris3606 opened 1 year ago
Adding some performance tests that back this up:
The version of ComponentCollection in beta5 uses a custom iterator for GetAll
. The following benchmarks that implementation:
Method | TypesOfComponents | ComponentsPerType | Mean | Error | StdDev |
---|---|---|---|---|---|
GetAllMockA | 1 | 2 | 40.04 ns | 0.808 ns | 0.930 ns |
GetAllMockAViaInterface | 1 | 2 | 92.37 ns | 0.324 ns | 0.270 ns |
GetAllIMock | 1 | 2 | 41.74 ns | 0.423 ns | 0.375 ns |
GetAllIMockViaInterface | 1 | 2 | 99.77 ns | 1.441 ns | 1.203 ns |
GetAll2MockA | 1 | 2 | 57.40 ns | 1.104 ns | 1.133 ns |
GetAll2MockAViaInterface | 1 | 2 | 67.15 ns | 0.460 ns | 0.384 ns |
GetAll2IMock | 1 | 2 | 63.50 ns | 1.108 ns | 1.037 ns |
GetAll2IMockViaInterface | 1 | 2 | 77.80 ns | 0.367 ns | 0.286 ns |
GetAllMockA | 1 | 10 | 62.71 ns | 0.242 ns | 0.202 ns |
GetAllMockAViaInterface | 1 | 10 | 204.15 ns | 0.646 ns | 0.539 ns |
GetAllIMock | 1 | 10 | 87.27 ns | 0.512 ns | 0.427 ns |
GetAllIMockViaInterface | 1 | 10 | 241.40 ns | 0.895 ns | 0.747 ns |
GetAll2MockA | 1 | 10 | 140.73 ns | 0.703 ns | 0.623 ns |
GetAll2MockAViaInterface | 1 | 10 | 150.34 ns | 1.819 ns | 1.702 ns |
GetAll2IMock | 1 | 10 | 174.75 ns | 0.571 ns | 0.506 ns |
GetAll2IMockViaInterface | 1 | 10 | 193.57 ns | 0.297 ns | 0.232 ns |
GetAllMockA | 2 | 2 | 37.46 ns | 0.181 ns | 0.160 ns |
GetAllMockAViaInterface | 2 | 2 | 91.72 ns | 1.025 ns | 0.959 ns |
GetAllIMock | 2 | 2 | 59.91 ns | 0.999 ns | 0.934 ns |
GetAllIMockViaInterface | 2 | 2 | 137.84 ns | 0.317 ns | 0.248 ns |
GetAll2MockA | 2 | 2 | 56.13 ns | 0.259 ns | 0.229 ns |
GetAll2MockAViaInterface | 2 | 2 | 67.87 ns | 0.703 ns | 0.587 ns |
GetAll2IMock | 2 | 2 | 93.69 ns | 0.846 ns | 0.750 ns |
GetAllMockA | 2 | 10 | 58.19 ns | 0.157 ns | 0.123 ns |
GetAllMockAViaInterface | 2 | 10 | 202.02 ns | 0.342 ns | 0.286 ns |
GetAllIMock | 2 | 10 | 167.17 ns | 0.422 ns | 0.374 ns |
GetAllIMockViaInterface | 2 | 10 | 426.41 ns | 2.096 ns | 1.750 ns |
GetAll2MockA | 2 | 10 | 141.43 ns | 1.630 ns | 1.525 ns |
GetAll2MockAViaInterface | 2 | 10 | 147.20 ns | 1.177 ns | 1.043 ns |
GetAll2IMock | 2 | 10 | 313.42 ns | 3.609 ns | 3.199 ns |
GetAll2IMockViaInterface | 2 | 10 | 339.23 ns | 1.494 ns | 1.324 ns |
"GetAll" represents the current, custom enumerator version, both called via a concrete variable of type ComponentCollection
, and on that same instance but via an interface. The GetAll2
implementation is an alternate implementation which uses yield return
, rather than a custom enumerator, which keeps the interface version closer time-wise, but is slower overall. In both cases, however, the interface is slower.
Currently, the component system in GoRogue has
IComponentCollection
, which is really just an interface used for an implementation of a collection of components. It also providesComponentCollection
, which is a concrete implementation of that interface.However, it may be worth considering removing
IComponentCollection
and simply providingComponentCollection
instead. I'm not aware of very many use cases where a custom implementation ofIComponentCollection
is the correct answer to a problem, sinceComponentCollection
is quite efficient and versatile. Futhermore, ifComponentCollection.GetAll<T>
uses a custom enumerator (which is coming in a PR soon), accessingGetAll
through an interface reference is actually significantly slower, since it requires boxing.If there is a compelling use case for
IComponentCollection
, I will happily leave it; but I simply haven't seen a use case that I can recall where it solved a problem; and if it solves a non-existent problem and also costs performance, it would make sense to remove it.