« Stealing Focus | Home | Veropedia and Information Ethics »
Understanding Performance Trade-offs
By Jacob Cohen | August 30, 2007
I think most programmers these days are fairly aware of the performance trade-offs of using an interpreted or bytecode-based language like Perl or Java, compared to a compiled language such as C or C++.
There is also little doubt that we now have more computing power available on the desktop than ever before. The performance losses that used to argue against using languages like Python, Ruby, C#, Perl, or Java, are now virtually impossible to notice to the end user.
Jeff Atwood writes, in an article about the pitfalls of C++:
C++ is fast but unforgiving. It was an appropriate solution for an era of limited computing resources. But we’ve long since left that behind; we live in an era of abundance. We have more computer power than we possibly know what to do with on the desktop. Even the naive solutions for most computing problems are “fast enough” these days. Computers get faster every day, but programmers’ brains, sadly, do not. It’d be a waste not to trade some of that abundant raw power to make things easier on us. It’s time to evolve up the one trillion dollar programming pyramid.
I think that this is a dangerous mindset. While a naive solution may be “fast enough” for one problem, it can quickly become “far too slow” for another. Algorithms and data structures must still be chosen wisely, even in this era of abundant computing power. As I’ve discussed before, there are often simple ways to achieve vast improvements in the performance of an algorithm that allow it to scale far beyond the naive solution.
The naive solution to a problem is certainly attractive in terms of the ease of implementation. However, we need to be careful not to be overconfident in our abundance of computing power. We certainly have enough spare power in today’s desktop machines to make light of the performance differences between C++ and Python for a standard user application. However, no amount of computing power can make up for an algorithm that scales poorly with the size of the problem to which it is applied.
Topics: General |

August 30th, 2007 at 1:27 pm
I think you are both right, and one answer is frameworks like scipy, that carefully allow you to try more algorithms due to the development speed of Python/IPython and yet get execution speed through the use of specialized libraries pre-written in compiled languages; and has the further option of allowing you to quickly code in a compiled language and use the result as if it were native Python - but at compiled execution speed.
- Paddy.
- Paddy.
October 14th, 2007 at 5:32 am
Game developers used to think .NET was a plaything and not anything to be taken seriously for game development. This has started to change as some are learning that .NET, once compiled, runs at native speeds. I was shocked to hear this, too, as I always thought C and C++ were faster.
October 19th, 2007 at 10:30 am
From a standpoint of optimizing computer efficiency, you are entirely correct. From a standpoint of optimizing computer effectiveness at being able to address problems and solve them, I can’t say I agree with you.
The primary constraints that prevent information technology from addressing any specific problem space are not that there is enough computing power, but that there is not enough expertise in both the problem domain and the IT domain to solve it. While maximizing the efficiency (and internal effectiveness or coherency) of IT is an important process, it is one that will never end.
A better economic solution would be to improve the ability of non IT experts to apply IT to their problems. This can only be done by expanding the flexibility and decreasing the complexity of the domain expert interface into IT.
In other words… scripting languages.
If I have a thousand C++ experts that dont, won’t or can’t understand my problem, then they are all useless to me. Give me one guy who understands my problem and who can solve it in some horrific language (VB comes to mind…) and I’m going to go with him.
October 22nd, 2007 at 12:10 pm
It’s funny.. as programmers, we’re always after the perfect solution — the most elegant, most efficient and clever solution to any one problem. We try to apply this to programming languages, and we wind up with nothing but arguments.
In reality, I think that it is virtually impossible to glob all the possible problem domains into one and devise a best solution. It’s a bit like asking what the best kind of paint and paintbrushes are overall: A house painter will tell you one thing, a model airplane builder will tell you another, and a watercolor artist will tell you a third.
I do agree with you that naivety is a dangerous pitfall in many ways when it comes to software. What works on a small scale may be horrible on a large scale. Scalability is similar to portability in this regard — naive programmers just don’t think beyond their immediate needs. Now, if you couple this with greater and greater abstraction away from machine code, your programmers become less and less capable of solving capacity problems through optimization.
Lastly, let’s not get ahead of ourselves on computing power being overabundant just yet. I write realtime systems within the financial industry, and I can tell you that I need more speed!!!!
October 23rd, 2007 at 12:08 pm
My point is that we have enough computing power to make up for the difference between an O(N*3) and an O(N*2.4) algorithm, but this doesn’t generalize into the statement that computers are powerful enough to make quick work of naive solutions.
It still amazes me how many people can’t name any sorting algorithms except “bubble sort”. If this is an indicator on the state of the industry, I don’t think we’re ready to accept naive solutions and rely on computing power to make it fast. An n-squared algorithm on a million records still takes a long time.
His (Jeff’s) point is that it doesn’t make sense to waste our (programmer’s) time trying to optimize these things, but I’d rather spend 5 minutes selecting a scalable algorithm rather than waiting for 5 years for the computing horsepower to make my solution fast.
October 29th, 2007 at 12:50 pm
Things change. Programs written in c/c++ etc are unable to dynamically adapt themselves to new operating environments. VM based languages like c# and java are able to optimize code based on the memory/cpu layout of the system they are running on, and optimize accordingly.
When you write in C, you have to code for a target platform, which is not really a realistic paradigm in modern software engineering.
Besides, as fun as it is to tweak algorithms with crazy pointer math and all sorts of bitwise operations and inline logic statements, it really isn’t needed, and to be honest, it really isn’t safe.
A large majority of security vulnerabilities in modern code are not there because they were coded by morons. They were often put there by people trying to show off, and using cool features and tweaks that they did not fully understand.
October 29th, 2007 at 2:40 pm
It should also be noted that “scalability” isn’t always, a good thing. Rather, necessary. Like clipon mentioned above, every problem has a different solution.
My main point here, is that if someone were to take the engine behind a large software project (World of Warcraft or Quake comes to mind) and tried to program say, Pong, or a financial planner, the results would more than likely be horrendous let alone optimal.
Large programs like the ones previously mentioned need the low-level (even though c/++ aren’t really low-level languages) power of the languages they’re written in, where as your basically financial planner doesn’t need that primal “oomph” to get the job done.
My rebuttal for “programming language wars” has always been, every task has an appropriate too. One more contrast for effect, bear with me; Writing a web-page in C would be ridiculous, and conversely, writing an operating system in HTML (I know its not a programming language, ok, how about JavaScript) would be equally ridiculous.
One more thought. pierce mentioned “Programs written in c/c++ etc are unable to dynamically adapt themselves to new operating environments”. I think there is a fundamental difference between a compiled program and one that is run through a Virtual Machine. That difference is in their very definitions. If I compiled hello world on a Windows Machine, and took the binary and placed it on a Unix box, I can guarantee that it wouldn’t run. A VM language on the other hand, is build precisely to combat this constraint. “Write once, run everywhere”.
In conclusion. Every task has an appropriate tool. Choose
wiselylogically.October 30th, 2007 at 8:05 am
Well, in response to the comment that “Programs written in C/C++ are unable to dynamically adapt themselves to new operating environments.”
I think you’d have to examine the specific benefit of such optimizations before making a judgment call on that.
If you use a N-cubed algorithm written in Java or another bytecode language, and have it as optimized as possible, and taking advantage of the latest platform tweaks and optimizations, and compare it against a linear-in-N algorithm written in any language, the linear algorithm will still have a more favorable performance curve.
My point was that the selection of a naive algorithm isn’t always going to be “fast enough”, regardless of the technologies used. In some cases, it will be fine. The types of performance differences I’m talking about are not the difference between what people see as a “slow” language compared to C, I’m talking about the difference between categories of algorithms that scale quite differently.