Summary of the benchmarks:
ConfigAbstractFactory runs at around the same speed as any other factory that pulls at least one dependency from the container.
ReflectionBasedAbstractFactory adds 2-3μs to service creation for a service that pulls at least one dependency from the container; this is essentially the cost of using reflection on the constructor.
ConfigAbstractFactory runs essentially the same speed whether used as an abstract factory or mapped as a factory; these speeds will, of course, change based on how many abstract factories are in use.
ReflectionBasedAbstractFactory consistently runs 0.5μs faster when mapped as a factory, regardless of number of dependencies.
The takeaways are:
ReflectionBasedAbstractFactory is more convenient (less configuration required), but comes at a performance cost.
ConfigAbstractFactory is faster, but comes with more configuration; it also has the benefit that you can specify alternate services (e.g., mapping config sub-arrays to a configuration abstract factory).
A factory that does not do reflection, and does not need to first pull the config service in order to determine dependencies is still the fastest solution.
My take is that an application will evolve over time:
The developer can use the
ReflectionBasedAbstractFactory as a catch-all to begin application development.
They can then generate configuration for the
ConfigAbstractFactory for a performance boost, to specify alternate dependencies, or to disambiguate dependencies.
Finally, when ready to go to production, they can generate actual factory classes, and map them into configuration.