Is it because these were all written in managed, garbage-collected languages rather than native code?
No. Slow code will perform poorly regardless. Sure, a particular language may introduce certain classes of problems while solving others. But good programmers are quite capable of finding workarounds given enough time.
Is it the individual programmers who wrote the software for these devices?
Partly. In many cases it is quite likely at least a contributing factor. This is an unfortunate side-effect of an industry where good programmers are in high demand and short supply. Also the gulfs between various levels of technical ability can be quite large. So it stands to reason that sometimes the programmers tasked to implement certain software could be congratulated just for getting it to work (sort of).
In all of these cases the app developers knew exactly what hardware platform they were targeting and what its capabilities were; did they not take it into account?
Partly. For a start, the exact hardware platform is probably not known, as that is often negotiated with various manufacturers in parallel during software development. In fact, there can even be small (but not necessarily insignificant) changes to underlying hardware after initial release. However, I would agree that the general capabilities will be known.
Part of the problem is that software probably isn't developed on the hardware, it's done in emulators. This makes it difficult to account for true device performance even if the emulators are 100% accurate - which they aren't.
Of course this doesn't really justify insufficient testing on the appropriate prototype hardware before release. That blame probably lies outside of dev/qa control.
Is it the guy who goes around repeating "optimization is the root of all evil," did he lead them astray?
No. I'm pretty certain they don't listen to him anyway; otherwise he wouldn't be misquoted so often (that's supposed to be "premature optimisation ..."). :-D
It's more likely that too many programmers take one of 2 extremes with regards optimisation.
- Either they either ignore it completely.
- Or they obsess themselves with minutiae that has nothing to do with the actual performance requirements. The net effect being that budget runs out and the code is too obfuscated to optimise the real performance problems safely.
Was it a mentality of "oh it's just an additional 100ms" each time until all those milliseconds add up to minutes?
Possibly. Obviously if Sleep(100)
has been used as the equivalent of tissue paper used to slow the bleeding of a severed limb - then problems are to be expected. However, I suspect the problem is more subtle than that.
The thing is modern computing hardware (including embedded devices) is much faster than people give them credit for. Most people, even "experienced" programmers fail to appreciate just how fast computers are. 100ms is a long time - a very long time. And as it so happens, this "very long time" cuts 2 ways:
- The first is that programmers worry unnecessarily about the things that a computer does extremely quickly. (It so happens that it was just such a concern "incrementing a value 300 times per second" that led me here in the first place.)
- The second is that they sometimes fail to show due concern when things do take a very long time (on the computing timescale). So:
- if they ignore the effects of latency when communicating over a network or with a storage device;
- if they ignore the impact of a thread blocked and waiting for another thread;
- if they forget that because computers work so quickly it is very capable of repeating a task far more often than it should, without the developer being aware of a problem
- ... if any combination of such oversights occur, a routine will unexpectedly run very slowly (on the computing timescale). A few repeats and it will even be noticeable by humans - but may be tricky to pin down because hundreds of interconnected things are all running quickly by themselves.
Is it my fault, for having bought these products in the first place?
Yes definitely. Well, not you personally but consumers in general. Products are sold (and bought) by feature checklists. Too few consumers are demanding better performance.
To illustrate my point: The last time I wanted to buy a cell-phone, the store couldn't even offer a demo model to play with in-store. All they had were plastic shells with stickers to show what the screen would look like. You can't even get a feel for the weight like that - let alone performance or usability. My point is that if enough people objected to that business model, and voted with their wallets to voice their objection, we would be one small step in the right direction.
But they don't, so we aren't; and every year new cell-phones run slower on faster hardware.
(The questions not asked.)
- Are marketing people to blame? Partly. They need release dates. And when said date looms, the choice between "get it working" and "make it faster" is a no-brainer.
- Are sales people to blame? Partly. They want more features in the checklist. They hype up feature lists and ignore performance. They (sometimes) make unrealistic promises.
- Are managers to blame? Partly. Inexperienced managers might make many mistakes, but even very experienced managers may (quite rightly) sacrifice time to resolve performance issues in favour of others concerns.
- Are specifications to blame? Partly. If something is left out of specification, it's that much easier to "forget" about it later. And if it's not specifically stated, what's the target? (Although I do personally believe that if a team takes pride in its work, they would worry about performance regardless.)
- Is education to blame? Maybe. Education will probably always be on the back-foot. I certainly disapprove of "education" that rapidly churns out beginners with a superficial understanding software development. However, education that is backed up with theory, and instills a culture of learning can't be bad.
- Are upgrades to blame? Partly. New software, old hardware really is tempting fate. Even before version X is released, X + 1 is in planning. The new software is compatible, but is the old hardware fast enough? Was it tested? A particular performance fix may be rolled into the new software - encouraging an ill-advised software upgrade.
Basically, I believe there are many contributing factors. So, unfortunately there's no silver bullet to fix it. But that doesn't mean it's doom and gloom. There are ways to contribute to improving things.
So, at what point did things go wrong for these products?
IMHO we can't really identify any single point. There are many contributing factors that evolved over time.
- Bean counters: cost cutting, market timing. But then again would we have made the advances we have achieved without the pressure?
- High demand and low supply of skilled people in the industry. Not just programmers, but also managers, testers, and even sales-people. Lack of skills & experience leads to mistakes. But then again it also leads to learning.
- Bleeding-edge technology. Until a technology matures, it will regularly bite in unexpected ways. But then again it often provided a number of advantages in the first place.
- Compounded complication. Over time, the industry has evolved: adding more tools, technologies, layers, techniques, abstractions, hardware, languages, variation, options. This makes it somewhat impossible to have a "full" understanding of modern systems. However, we are also capable of doing a lot more in a far shorter time as a result.
What can we as programmers do to avoid inflicting this pain on our own customers?
I have a few suggestions (both technical and non-technical) which may help:
- In sofar as it's possible - use your own product. There's nothing like first hand experience to reveal things that are awkward, slow or inconvenient. However you will need to consciously avoid bypassing deficiencies due to "insider knowledge". E.g. If you have no problems synching contacts because you do it with a backdoor Python script - you're not using "the product". Which brings up the next point...
- Listen to your users (preferably first hand, but at least second hand via support). I know programmers (generally) prefer to stay hidden away and avoid human interaction; but that doesn't help you discover the problems other people experience when using your product. E.g. You might not notice that the menu options are slow, because you know all the shortcuts and use those exclusively. Even if the manual fully documents all shortcuts, some people will still prefer the menus - despite being insufferably slow.
- Strive to improve your technique skills and knowledge on a continuous basis. Develop the skill to critically analyse everything you learn. Reassess your knowledge regularly. In some cases, be prepared to forget what you thought you knew. Which brings up...
- Some technologies / techniques can be very tricky leading to subtle misunderstandings and incorrect implementations. Others through the evolution of common knowledge or available tools may fall in or out of favour (e.g. Singletons). Some topics are so tricky that they breed a bunch of "hocus-pocus pundits" that propagate a huge body of misinformation. A particular bugbear of mine is the misinformation surrounding multi-threading. A good multi-threaded implementation can significantly improve user experience. Unfortunately a lot of misinformed approaches to multi-threading will significantly reduce performance, increase erratic bugs, increase dead-lock risks, complicate debugging etc. So remember: just because an "expert" said it, doesn't make it true.
- Take ownership. (No seriously, I'm not playing boardroom bingo.) Negotiate with managers, product owners, sales people for performance features taking precedence over some checklist items. Demand better specifications. Not childishly, but by asking questions that get people thinking about performance.
- Be a discerning consumer. Pick the phone that has less features but is faster. (Not faster CPU, faster UI.) Then brag about it! The more consumers start demanding performance, the more bean counters will start budgeting for it.