Not exactly; although for services a Container is probably optimized enough. So this might not be the best example. I usually do
return$this->service??=Container::get(...);
to initialize the service, when I am 100% sure the container will return the service.
The "problem" this helper solves is that ?? is the same as isset(), and that will return false for uninitialzed aswel as null. But null is a valid value to initialize a parameter.
So when the value is initalized with null the isset() or ?? check will still trigger the Container::get(...) on subsequent request, while this is_initialized() helper will not. Hope that makes sense.
Isn't using reflection here somewhat adding extra load on the server unnecessarily? Normal execution, stop, check reflection, go on. Sure might be easier for developer but at the cost of runtime? The more your program does the more CPU cycles it consumes. At some point just throwing hardware at it won't be enough. And doing something like this kinda feels like that trap to me.
You're right, performance is something we absolutely have to keep in mind. So I'm glad you point this out.
The Reflection API is actually pretty fast. Of course it adds some extra load, but only on execution time, and even then the differences are minuscule. I ran a phpbench test over 4 situations:
multiple calls on the same instance with isset()
multiple calls on new instances with isset() (every call is a new instance)
multiple calls on the same instance with is_initialized()
multiple calls on new instances with is_initialized() (every call is a new instance)
I ran the test with 10.000 calls, and repeated them 100 times. These are the results:
subject
revs
its
mem_peak
mode
rstdev
benchIsset
10000
100
656.328kb
0.087μs
±6.93%
benchIssetNew
10000
100
656.328kb
0.172μs
±5.01%
benchReflection
10000
100
656.328kb
0.334μs
±4.14%
benchReflectionNew
10000
100
656.344kb
0.433μs
±3.72%
The memory consumption is exactly the same for every situation, except situation 4. But that is not really helpfull with memoization. Even then, the extra memory is negligible.
isset() is definitely faster, but only marginal. You would probably not notice this in your request.
Still, I would only suggest you use this method if you have a memoization situation where the value of your (typed) parameter could also be null. Otherwise, definitely use isset() or ??(=).
Not exactly; although for services a
Container
is probably optimized enough. So this might not be the best example. I usually doto initialize the service, when I am 100% sure the container will return the service.
The "problem" this helper solves is that
??
is the same asisset()
, and that will returnfalse
for uninitialzed aswel asnull
. Butnull
is a valid value to initialize a parameter.So when the value is initalized with
null
theisset()
or??
check will still trigger theContainer::get(...)
on subsequent request, while thisis_initialized()
helper will not. Hope that makes sense.Isn't using reflection here somewhat adding extra load on the server unnecessarily? Normal execution, stop, check reflection, go on. Sure might be easier for developer but at the cost of runtime? The more your program does the more CPU cycles it consumes. At some point just throwing hardware at it won't be enough. And doing something like this kinda feels like that trap to me.
Not the most liked opinion unfortunately :(
Cool solution tho.
You're right, performance is something we absolutely have to keep in mind. So I'm glad you point this out.
The Reflection API is actually pretty fast. Of course it adds some extra load, but only on execution time, and even then the differences are minuscule. I ran a
phpbench
test over 4 situations:isset()
isset()
(every call is a new instance)is_initialized()
is_initialized()
(every call is a new instance)I ran the test with 10.000 calls, and repeated them 100 times. These are the results:
The memory consumption is exactly the same for every situation, except situation 4. But that is not really helpfull with memoization. Even then, the extra memory is negligible.
isset()
is definitely faster, but only marginal. You would probably not notice this in your request.Still, I would only suggest you use this method if you have a memoization situation where the value of your (typed) parameter could also be
null
. Otherwise, definitely useisset()
or??(=)
.This benchmark thing is super super interesting! Thank you!!