As a counterpoint, I used PHP5 when writing https://www.goldeneaglecoin.com/ and it was always < 50 ms on my endpoints, running on some crusty hosted celeron at the time. Adding caching and opcache doesn't invalidate the stateless approach.
Programming is about adding abstractions on top of underlying computational substrates. Ultimately our CPUs don't care if we run haskell or PHP, they just run machine instructions. I never found it too complicated to use useful abstractions in PHP.
I usually prefer inheriting a subperforming cache-free PHP site, because devising a consistent cache strategy is usually not too hard (cache static content + opcodes on deploy, determine which invalidation keys you need for the subset of dynamic content that does the bulk of the load / has latency requirement, don't cache the rest). If I have a big collection of lose php files, that's reasonably easy to do. If i have a tangled web of middlewares and ORM'd business logic, it's much harder, and I usually have to unfold it to "lose leaves".
Great comment! You clearly are well-versed in the ecosystem much more than when my PHP5 self gave up. If I needed a PHP dev for a project, I'd hire you.
> Adding caching and opcache doesn't invalidate the stateless approach.
> Programming is about adding abstractions on top of underlying computational substrates. Ultimately our CPUs don't care if we run haskell or PHP, they just run machine instructions. I never found it too complicated to use useful abstractions in PHP.
I'll push back a little on these. TL;DR: it's a trade-off.
My point with Haskell is that the entire language itself is stateless, so if per-request statelessness ("shared nothing") in PHP is a virtue, then certainly total statelessness ("purity") in Haskell is even more of a virtue. The problem is that, despite having similar performance to PHP, Haskell is hard to write.
This is illustrated with caches: if a PHP program had a line something like `if ($cache.retrieve('foo') != null) { echo "Success!<br />"; } else { echo "it's broken"; }`, then now global state matters again.
Haskell doesn't allow code of this form, but forces you to think harder about how to make it work using e.g. monads, and this can be frustrating. But if you can get Haskell to work, you can get caching nearly for free.
for sure. but it's not "hard" (of course abstraction is hard to learn and see, but not to implement, I hope you understand my meaning here. I apologize for the lack of clarity) to build something like (very rough sketch):
The caching is declarative, and the code is "stateless." This is fast enough that caching the render is pretty much not necessary, despite running on a t2.medium, and easily sustains > 100 rps. In the happy path, it reads a single value in the object cache. Only an initial hit will cause a render (using a bytecode compiled optimized template), and only the first XHR will cause an actual lookup in the server side cache (if necessary) because the browser then does the rest.
I wrote this code 12 years ago, and porting to react doesn't require any change on the server side. We just put RTK-Query in front and let it do all the rest.
As a counterpoint, I used PHP5 when writing https://www.goldeneaglecoin.com/ and it was always < 50 ms on my endpoints, running on some crusty hosted celeron at the time. Adding caching and opcache doesn't invalidate the stateless approach.
Programming is about adding abstractions on top of underlying computational substrates. Ultimately our CPUs don't care if we run haskell or PHP, they just run machine instructions. I never found it too complicated to use useful abstractions in PHP.
I usually prefer inheriting a subperforming cache-free PHP site, because devising a consistent cache strategy is usually not too hard (cache static content + opcodes on deploy, determine which invalidation keys you need for the subset of dynamic content that does the bulk of the load / has latency requirement, don't cache the rest). If I have a big collection of lose php files, that's reasonably easy to do. If i have a tangled web of middlewares and ORM'd business logic, it's much harder, and I usually have to unfold it to "lose leaves".