… or was it always the new Assembly?
This analysis is foreboding, because it’s exactly what programmers have always done when they switched to a higher level language. 10 years ago a programmer would be more likely to “switch to assembly” for a much-needed performance boost. Has it come to this? Are we moving to a higher plane? If you’re like me, you’ve probably become quite comfortable in your Objective-C universe, and somewhat dismissive of the scripting languages as they begin to encroach on our holy ground. But we run the risk of being like those losers who still insist on programming everything in assembly, while the higher-level code would be just as fast and easier to maintain.
Is C is the new assembly?
In a way, though, C was always the new assembly. When C was developed, one of the target goals of the C language was to make the assembly language generation straightforward: each statement would translate into a few machine language instructions. Further, C doesn’t require very much run-time language support: aside from setting up the BSS segment and a little code to translate the environment variables and run-time arguments into an array of string before invoking main(), C really requires no run-time language support at all.
C was always the new assembly.
One of the reasons why I love C++ was that, as originally conceived, C++ was basically C with classes. When I first learned C++, C++ only added two things to C: class support (and C++ class support followed the philosophy of C’s ‘keep it simple’), and operator overloading via function name aliasing. The beauty of C++ and the reason why I liked C++ was that you could write a C++ class and the method names and have an intuitive feel as to the assembly language that was being produced. This is very powerful when you’re working on a 16MHz 68020 processor and need to do things like refresh the drawing region of a screen in less than 20ms, which is the thresshold for most people’s ability to see a flicker on the screen. (And since application performance is directly related to algorithm efficiency and shortness of the instruction paths, having a feel for the instructions being generated helps you keep instruction paths short.)
Since then, of course, two things happened–as they always do. First, computers have gotten rediculously fast compared to that original 16MHz 68020 or the 8MHz 68000 or the 1.7MHz Z-80 I first learned to write software on. This has allowed us to the second thing: to create virtual machines and insanely long execution paths at key parts of the code (can you say ‘IDispatch’?) yet maintain the 20ms refresh rate on the screen. It’s the reason why we have 3GHz processors and need every ounce of that horsepower to do what we used to do on a computer that had more than three orders of magnitude less horsepower.
Secondly, and hand in hand with the first, we have seen the rise of computer languages which are less and less performance sensitive, but which are designed to make developers’ lives easier. Thus, we get langauges such as Java (which, even with modern JVMs and just in time compiling, is still a freakishly large pig compared to C), and C# and the .NET runtime library (which dispatches through IDispatch with shocking regularity) and the latest craze, Ruby, which proves the old adage that what is old is new again.
So is C the new Assembly? Yes, and it always was–it’s only that computers have become powerful enough that we can finally code in something other than assembly language.