They have a multi-core, multi-gigahertz processor, gigabytes of ROM/Flash, more gigabytes of RAM, and they still can't write a responsive program. Poor coding is largely to blame, although inadequate compilers and/or wrong choice of language/methodology used can have a bearing as well. I can, and did, write far more responsive software on the crude 4 and 8 bit processors of the day years back - never mind the 16 and 32 bitters I graduated to later.
I think the hardware is as much to blame, though indirectly - not that it causes the latency obviously, but that it lets the coder get lazy. As hardware tech improves, the old hardware that does the job just fine gets discontinued to free up production space for the next new thing, and the device manufacturer has to upgrade when the old stuff did the job just fine. Then some brilliant PM gets the idea "we've got all this hardware headroom, lets add some features that no one is asking for", without realizing that most of that headroom is already accounted for to cover up lazy coding.
Even the controllers I use are way too much beef for what a lot of my contemporaries do with them. I don't even know what the clock speed is, but I know it's 32 bit and the power supply for the entire device is 30W which includes an integrated 132x64 monochrome LCD display, (6) 0-10V or 4-20mA sensors and (24) relays. The most complex program I've ever written executes in about 60ms - a similarly complex program I wrote 2 years ago took twice that, so I guess I'm getting better. The longest operations I usually have to deal with are data exports, which are user initiated, and I just spread the operation over several program cycles so no single lag in response is observable. There are a couple of things that I have to execute in one cycle but they only have to be performed once or twice a minute so that's what I do.
Exhibit A - a "four pipe" heat pump. Each module has two refrigerant-water heat exchangers and a refrigerant-air coil. It can absorb heat from the ambient air to heat water, it can cool water and reject the heat to ambient air, or it can cool water and reject the heat to the other water simultaneously, during which it can prioritize temperature precision for either the heated or the chilled water (I say water but it's really a water-glycol solution). It also has to defrost the air coil when it's running the water-heating mode. There is a version that only has the hot-side heat exchanger so it doesn't have water cooling, and there is a high temp version that completely reconfigures the refrigerant side, so there's 7 operating modes and 4 different configurations. Compressors, fans, expansion valves are "infinitely" variable based on various temperatures and pressures which are different between different modes. And then there's a supervisory device that determines which mode each module should operate in to achieve the desired overall fluid temperatures, while achieving equal usage across up to 100 modules. And there's probably not half a dozen IF statements in the whole thing.
HVAC programmers come in two flavors - there's the ones like me that learned some computer programming growing up (my "numerical methods for engineering computation" prof always got a kick out of my printed out QuickBASIC programs breaking up the monotony of grading click-and-dragged Excel formulas - and I also had some courses on Java and VB .NET later on) and then fell into HVAC. The second flavor of HVAC programmer is the guy that started out as a tech and convinced himself that coding is easy because he saw somebody using Function Block Diagrams - which I view as a crutch that allows hacks to continue far longer in the field than they have any business doing. It works ok for building management but when you start using it as a manufacturer and try to make anything configurable or scalable it just turns into spaghetti in no time that's impossible to troubleshoot. The example I used could never be achieved in FBD and that's why FBD programmers are a dime a dozen and text programmers can write their own check.
Here's a very simple function that just monitors the connection between the controller and a cellular modem, and cycles power on the modem if that connection appears to be dead.
FBD:
Text: