High-level Languages and Speed
nitsudima writes to tell us Informit's David Chisnall takes a look at the 'myth' of high-level languages versus speed and why it might not be entirely accurate. From the article: "When C was created, it was very fast because it was almost trivial to turn C code into equivalent machine code. But this was only a short-term benefit; in the 30 years since C was created, processors have changed a lot. The task of mapping C code to a modern microprocessor has gradually become increasingly difficult. Since a lot of legacy C code is still around, however, a huge amount of research effort (and money) has been applied to the problem, so we still can get good performance from the language."
God, what has been happening? Can't OSTG afford a test server for Taco to mess around with?
Well, we ran our own tests. We took a sizable chunk of supposedly well-written time-critical code that the gang had produced in what was later to become Microsoft C [2] and rewrote the same modules in Logitech Modula-2. The upshot was that the M2 code was measurably faster, smaller, and on examination better optimized. Apparently the C compiler was handicapped by essentially having to figure out what the programmer meant with a long string of low-level expressions.
Extrapolations to today are left to the reader.
[1] I used to comment that C is not a high-level language, which would induce elevated blood pressure in C programmers. After working them up, I'd bet beer money on it -- and then trot out K&R, which contains the exact quote, "C is not a high-level language."
[2] MS originally relabled another company's C complier under license (I forget their name; they were an early object lesson.)
Lacking <sarcasm> tags,
So we "still can get good performance" from C? The implication is that C will somehow become overcome by some unnamed high-elvel language soon. That is just wishful thinking. The article is not very substantial, and where it tries to substantiate, it misses the mark badly. The claim that C cannot handle SIMD instructions well is not true. You can use them directly from C, or the C compiler can use them through autovectorization, as in gcc 4.1. The claim that C cannot inline functions from another source file is also wrong. This is a limitation in gcc, but other compilers can do it, and IIRC the intel compiler can. It is certainly not "impossible".
I remember back in the days of the Atari ST and Amiga, C was considered to be a high-level language. People would complain about the poor performance of games written in C (to ease the porting from Amiga to ST and vice versa) over 'proper' Assembly coded games.
Now I hear most people referring to C and C++ as "low level" languages, compared to Java and PHP and visual basic and so on. Funny how that works out.
I like Assembler. There's something about interacting intimately with your target hardware. It's a shame that it's no longer feasible with today's variety of hardware.
Argh.
Not really much "meat" here. The proof is in the pudding as they say - but there's no benchmarks here. Just some minor talk about how things should compare.
I don't agree with the basic premise of the article at all - but I've also written equivalent programs in C and more modern languages and compared the performance.
This is not true. What they mean, I think, is "the task of mapping C code to efficient machine code has gradually become increasingly difficult".
The AACS key is NOT 0xF606EEFD628B1CA427BEA93A9CA9773F
The speed of code written in computer language is based on the number of CPU cycles required to carry it out. That means that the speed of any higher-level language is related to the efficiency of code executed by the interpreter or produced by the compiler. Most compilers and interpreters these days are pretty darn good at optimizing, making the drawback of using a higher-level language less and less important.
If you don't believe me, I suggest you look at some of the assembly code output of gcc. I'm no assembly guru, but I don't think I would have done as well writing assembly by hand.
I am officially gone from
What I think the author may have been trying to get at with the SIMD part is that our machines are becoming multiprocessor based. And not multi-CPU based but my machine right now has a CPU, GPU & probably some microprocessors for the chipset. I think that you missed his point in that processors and machines have changed a lot. Thirty years ago, things were different and C was optimized to be the fastest. It probably still is the fastest but that doesn't necessarily mean that new languages are slow--in fact, they themselves may be optimized to take advantage of multi-processors better than classic C can. Again, that's not saying someone can't add to the gcc for that particular set up but you can't ignore what the author is saying.
Isnt the JIT for java written in C though.
ahah now we know why my java program is so slow. damn C slowing it down.
Escher was the first MC and Giger invented the HR department.
Is this a surprise?
;-) Unfortunatly...
C is designed for classic Von-Neumann architecture machines using a stack based methodology and an attempt to give programmers all the rope they could want.
This is a good thing for solving one set of problems.
It also showed it can be adapted and built on to solve further more advanced problems.
This is also a good thing.
I would question however if in these days with ever increasing usage of multiprocessors, MMUs, Register heavy CPUs, massive on chip caches, huge latency to access memory etc if the concepts embodied within C are still the best methodology?
I guess what I'm saying is i wonder if there is an equivalent medium level language* around that better suits todays reality.
Let me as a possibly poor example take the cell processor as an example here:
The kind of tools I'd like to see for this (were a cell style processor to be used in my next desktop) would be:
1) Access to the low level assembler.
2) An extemsion to the C language (possibly a library) which would mean I could run all my existing code as is on this multi processor machine, but I could then profile the code to make better use of new processor architectures in the interim until I migrate my code/programmers over to new methodology.
3) High level languages like python, Perl etc running in some mode - for tools like this I normally don't care about performance if I'm using thse tools - and wioth any luck, clever compilers/interprators will do some of the multi core management for me
Although a new high level language which allows instruction/task level parallelism would be cool!
4) A new medium level language (along the lines of occam) which would allow me to have a comparable level of control and automation over this multi processor register and cache heavy system.
to me, 1 is implicitly required for any design, 3 comes for free once you have 2, and 4 is a way to progress forwards and gain productivity.
That leaves 2 as a stop gap measure.
That is all you programs compiled using #2 would make very inefficient use of such a processor,, but would maintain compatability for the time being until we can move on to more appropriate things.
Will we ever leave C behind? Well we never left Fortran behind really, it's still there. I don't see any more reason to keep C for modern desktop processors than there was to keep training most programmers in fortran.
But will we ever move GNU off of C?
I won't be throwing out my C LRM yet
* By my definition:
High level language - Hide all/as many as possible of the details of the machine from the programmer
Low Level language - expose the programmer to as many of the machine details as possible
Medium level - make some parts of the machine automated (e.g for loops) make some exposed to the programmer (e.g. memory managment)
Yes this is a sliding scale, so arguments as to where a langauge lies are always open to debate
"The weirdest thing about a mind, is that every answer that you find, is the basis of a brand new cliche" -
Sure, CPU:s look quite a bit different now than they did 20+ years ago. On the other hand, CPU designs do heavily take into account what features are being used by the application code expected to be run on them, and one constant you can still depend on is that most of that application code is going to be machine-generated by a C compiler.
For instance, 20 years ago there was nothing strange about having an actual quicksort machine instruction (VAXen had it). One expectation was still, at the time, that a lot of code would be generated directly by humans, so instructions and instruction designs catering to that use-case were developed. But by around then, most code was machine generated by a compiler, and since the compiler had little high-level semantics to work with, the high-level instructions - and most low-level one's too - went unused; this was one impetus for the development of RISC machines, by the way.
So, as long as a lot of coding is done in C and C++ (and especially in the embedded space, where you have most rapid CPU development, almost all coding is), designs will never stray far away from the requirements of that language. Better compilers have allowed designers to stray further, but stray too far and you get penalized in the market.
Trust the Computer. The Computer is your friend.
The more abstract a language is, the better a compiler can understand what you are doing. If you write out twenty instructions to do something in a low-level language, it's a lot of work to figure out that what matters isn't that the instructions get executed, but the end result. If you write out one instruction in a high-level language that does the same thing, the compiler can decide how best to get that result without trying to figure out if it's okay to throw away the code you've written. Optimisation is easier and safer.
Furthermore, the bottleneck is often in the programmer's brain rather than the code. If programmers could write code ten times faster, that executes a tenth as quickly, that would actually be a beneficial trade-off for many (most?) organisations. High-level languages help with programmer productivity. I know that it's considered a mark of programmer ability to write the most efficient code possible, but it's a mark of software engineer ability to get the programming done faster while still meeting performance constraints.
Bogtha Bogtha Bogtha
The first mistake: Confusing "compile" performance with execution performance. The job of maping C/C++ code to machine code is trivial.
.NET will make software worse.
I've been programming professionally for over 20 years, and for those 20 years, the argument is that computers are now fast enough to allow high level languages and we don't need those dirty nasty assemblers and low level languages.
What was true 20 years ago is still true today, well written code in a low level language tailored to how the computer actually works will always be faster than a higher level environment.
The problem with computer science today is that the professors are "preaching" a hypothetical computer with no limitations. Suggesting that "real" limitations of computers are somehow unimportant.
If computer science isn't about computers, what is it about? I haate that students coming out of universities, when asked about registers and how would they write a multiply routine if they only had shifts and adds, ask "why do I need to know this?"
Software sucks today because software engineers don't understand computers, and that's why languages and environments like Java and
Take Quake II for instance; as quoted from the article 'the managed version initially ran faster than the native version' - which would suggest higher-level languages are certainly capable of comparing to that of their lower-level siblings.
Also, take into account the added developer time gained from factors like memory-management being, well, managed, and ever-falling processor & memory prices, and the logical conclusion is usually "write at a higher-level".
There are of course more considerations than these when deciding on a development platform, but essentially, I think there'd have to be very good reasons for writing green-field projects too close to the machine.
throw new NoSignatureException();
People who are good at C will insist that they can code something as quickly as anyone else can code the same thing in a higher level language. Well, maybe. I got my own awakening when I watched two students struggling to write something in C that they could have written in ten lines of Basic (it was a while ago).
In the embedded world, programming DSPs is a wonderful example. We used to write assembly code for the parts that had to be fast because we could get tighter code than a compiler could produce. Now the tools are so good that even good programmers are better off letting the tools do the work.
So, is there any point writing in a low level language, even where speed matters? I don't think. In any event, it will take longer to write the code. It just doesn't seem like a winning proposition.
Here's a print view of the article so that you don't have to keep moving through the pages. Despite that annoyance, it was a good article. I wish there had been more concrete examples though.
Who said Freedom was Fair?
The criteria for a high-level language are: 1) you aren't allowed to do direct memory register manipulations (i.e. cant run of the end of an array into other areas), and 2) you are interpreted. Either of these can qualify a language as high-level. C has direct memory register manipulation and it is not interpreted, therefore it cannot be a high-level language.
stuff |
OK, this is nitpicking but there are some exceptions - I remember that TASM would convert automatically long conditional jumps to the opposite conditional jump + an unconditional long jump since there was no long conditional jump instruction.
This paragraph is complete crap. If you're using a Dictionary API in a so called "low-level language", it's as possible for the API to do the same optimization as it is for the runtime he talks about; and you're still letting "someone else do the optimization".
That's surely true. But the opposite is also true - when you use an immense amount of too complex semantics, they can be translated into a pile of inefficient code. Sure, this can improve in the future, but right now it's a problem of very high level constructs.
Not exactly true I think. Yes, the approach on that page is not standard C, but on section 4 he also talks about some high level performance improvements which are still being experimented on, so...
The AACS key is NOT 0xF606EEFD628B1CA427BEA93A9CA9773F
Interesting article... the main point seems to be that compilers have grown better at producing the most efficient machine code for particular processor. Perhaps there's a market out there for processors that are optimised for specific languages (like C, given that there still is a lot of C code out there)?
Deal with reality - the world as it is - rather than ideality - the world as you would like it to be.
"I've been programming professionally for over 20 years, and for those 20 years, the argument is that computers are now fast enough to allow high level languages and we don't need those dirty nasty assemblers and low level languages."
.NET will make software worse."
The "appeal to an expert" fallacy?
"What was true 20 years ago is still true today, well written code in a low level language tailored to how the computer actually works will always be faster than a higher level environment."
It also means that portability becomes ever harder, as well as adaptability to new hardware.
"If computer science isn't about computers, what is it about? I haate that students coming out of universities, when asked about registers and how would they write a multiply routine if they only had shifts and adds, ask "why do I need to know this?""
It's about algorithms. Computers just happen to be the most convienent means for trying them..
"The problem with computer science today is that the professors are "preaching" a hypothetical computer with no limitations. Suggesting that "real" limitations of computers are somehow unimportant."
With the trend towards VM's and virtualization, that "hypothetical" computer comes ever closer.
"Software sucks today because software engineers don't understand computers, and that's why languages and environments like Java and
Now who's handwaving?
I didn't see anything mentioning that many high-level languages are written in C. And I don't consider languages like FORTRAN to be high-level. FORTRAN is a language that was designed specifically for numeric computation and scientific computing. For that purpose, it is easy for the compiler to optimize the machine code better than a C compiler could ever manage. The FORTRAN compiler was probably written in C, but FORTRAN has language constructs that are more well-suited to numeric computation.
Most truly high-level languages, like LISP (which was mentioned directly in TFA), are interpreted, and the interpreters are almost always written in C. It is impossible for an interpreted language written in C (or even a compiled one that is converted to C) to go faster than C. It is always possible for a C programmer to write inefficient code, but that same programmer is likely to write inefficient code in a high-level language as well.
I'm not saying high-level languages aren't great. They are great for many things, but the argument that C is harder to optimize because the processors have gotten more complex is ludicrous. It's the machine code that's harder to optimize (if you've tried to write assembly code since MMX came out, you know what I mean), and that affects ALL languages.
The author comes up with a bunch of half-ass arguments of why higher level languages aren't necessarily slower and can be faster given certain condition. Before we abandon all our C programs, where is the proof that this is true? I mean, there are things that you just can't do with C that higher level languages fundamentally can't do, e.g. write a garbage collector.
I might give you 1 but 2 is complete crap. There are plenty of high level languages that are not interpreted. I don't think anyone will call Ada anything but high level.
The main reason C is "faster" than high level languages is because C doesn't cover bad programmers' butts with elaborate type checking, ref counting and garbage collection. Take a properly designed C app with graceful error handling and secure inputs, and you will take a performance hit. Let's face it, most of the code we write in C involves error handling and idiot-proofing, things that most high-level languages have built-in functionality for these boring, repetitive slabs of code we all hate writing.
I see no reason why a high-level application couldn't be compiled as skillfully as a feature-equivalent low-level application. It's just a matter of breaking down the code into manageable building blocks.
-Billco, Fnarg.com
GCC supports inline functions and most other aspects of C99.
an ill wind that blows no good
C is portable, fast, very complex and since 35+ years the leading standard for professional OS and APP development.
.NET??? ...amusing.
C is so successful that C++ had to be invented to get more people into OO style C programming. C++ was designed as an syntax aid for people who lacked the skill writing OO in C by disciplined use of structs and func pointers.
C is obviously too complex for the average CS student who crouch from one alternative to the next.
Java?
I found low-level languages work better with speed. I get too confused with a higher-level one when I use it. :(
Every serious hacker should have a play with assember, or even machine code. There is real magic in starting up a uP or uC on a board you built yourself, and making it flash a few LEDs under the control of your hand assembled program. I found a whole new depth of understanding when I built a 68hc11 based board (not to mention memorizing a whole bunch of op-codes). Of course, I'd never want to write a 'serious' piece of code in assembly, and it still amazes me that anyone ever did!
No, what they say is "the proof of the pudding is in the eating." (Just pointing it out because most people get it wrong.)
"[Regarding the 'cloud,'] ownership was what made America different than Russia." -- Woz
http://shootout.alioth.debian.org/
You'll notice that C does pretty well. Note also however that several other high level languages come in pretty close in terms of performance (of course they usually win on program length). In particular 3 modern functional languages (Clean, OCaml and Haskell) come in just behind gcc and well before your jited or bytecode languages.
So yes, high level languages that compile to native machine code are fully competitive with C and that's not even considering important things like programmer time, safty, maintanability etc.
I'm currently working on a new String and IO library for Haskell and we're getting idiomatic one line programs that are within a few % of equivalent C programs. This is nice because typically you have to uglify your high level code to become more competitive with C performance.
Back in the 80's and early 90's I was doing a lot of programming using Modula-2 as well. (To be honest, I still miss the language to this day... I wish I knew why it never took off the way it seemed it should've). One interesting feature the compiler/IDE system I was using at the time (TopSpeed's) had was this concept that all their language compilers (M2, C, C++, etc) all compiled into an intermediate binary form, and their final compiler did very heavy optimizations on that "byte code".
It always tended to crank out really bizarre code, but usually at least as good as I could've hand-optimized directly in assembly.
I wonder what ever happened to them...
Thread on OCaml-beginners newsgroup here.
Rich.
libguestfs - tools for accessing and modifying virtual machine disk images
The fact that C code is not as close to assembely code as it once was isn't the relevant issue. The question is whether C code is still closer to the assembely than high level languages are. This is undoubtedly true. If you don't believe this try adding constructs to ruby or lisp to let you do low level OS programming and see how difficult it would be.
I'm a big fan of high level languages and I believe eventually it will be the very distance from assembely that high level languages provide that will make them faster by allowing compilers/interpreters to do more optimization. However, it is just silly to pretend that C is not still far closer to the way a modern processor works than high level languages are.
If nothing else just look at how C uses pointers and arrays and compare this to the more flexible way references and arrays work in higher level languages.
If you liked this thought maybe you would find my blog nice too:
Whoa! This article seems to be making up history out of whole cloth. I'm not even sure where to begin. It's just totally out to lunch.
:= A + 1) puts it closer, not to PDP-11 architecture, but to contemporary machine architecture in general.
C was not a reaction to LISP. I can't even imagine why anyone would say this. LISP's if/then/else was an influence on ALGOL and later languages.
C might have been a reaction to Pascal, which in turn was a reaction to ALGOL.
LISP was not "the archetypal high-level language." The very names CAR and CDR mean "contents of address register" and "contents of decrement register," direct references to hardware registers on the IBM 704. When the names of fundamental languages constructs are those of specific registers in a specific processor, that is not a "high-level language" at all. Later efforts to build machines with machine architectures optimized for implementation of LISP further show that LISP was not considered "a high-level language."
C was not specifically patterned on the PDP-11. Rather, both of them were based on common practice and understanding of what was in the air at the time. C was a direct successor to, and reasonably similar to BCPL, on Honeywell 635 and 645, the IBM 360, the TX-2, the CDC 6400, the Univac 1108, the PDP-9, the KDF 9 and the Atlas 2.
C makes an interesting comparison with Pascal; you can see that C is, in many ways, a computer language rather than a mathematical language. For example, the inclusion of specific constructs for increment and decrement (as opposed to just writing A
"How to Do Nothing," kids activities, back in print!
... bullshit. These are purely artificial limitation you've put on high-level languages yourself. There are no clearly defined rules that divide low-level languages from high-level languages like that - it's just plain silly. The terms high- and low-level language are inherently relative and depend heavily on the context. To name an example, say we are talking about the field of Machine Architecture. In this field C is clearly a high-level language, since it's on top of assembly level, which is on top of the OS level, which is on top of the absolute machine code level, which is on top of the micro-code level, which again is on top of the actual hardware level. Actually you can continue futher down through the abstraction levels even further, but then you'd be leaving the field of Computer Science.
Now if we're speaking in the field of programming languages actually used today, you could surely argue that C is one of the lower-level languages out there, and hence call it a low-level langauge. Personally, I prefer to always look at it from the Machine Architecture viewpoint, but I guess it's a matter of preference.
I believe the phrase the faster your program will compile means "the faster the compiler will translate your program into machine-executable code." Apparently the author means "the compiler will generate faster code." He then makes the same mistake again, equivocating between the process of compilation and the quality of the compiled output.
If you can't manage to write a clear sentence defining what topic you're exploring...what else might you be getting wrong?
Badly researched to the point of being irresponsible.
1. Unsupported implication that 'C' was created in response to PDP-11 assembly language.
2. Using vector attached processors as evidence of HLL obsolescense. First, the Altivec/MMC unit is not the entire processor, it doesn't even do most of the work, it's an *attached* unit. There is still a main MPU to do the spaghetti code. Second, they are easily used by HLL's via optimized LIBRARIES, that's the beauty and breakthrough of 'C' that has become a model for HLL's.
3. JIT examples fail to include the runtime of the JIT compiler itself. The program may speed up by 10%, but running the JIT before the program will blow that time out of the water.
4. Article totally ignores the "RISC revolution" of the 80's where processors were actually designed based on HLL's, designed specifically to speed them up, acting in consort with the compilers & linkers. This concept is now old hat. Maybe the author wasn't born yet.
Need I continue??
C# is more strongly typed than Java.... :D
What are these high perfomance applications that really need the sheer speed provided by a Java JTI? Is speed really an issue these days? Most of the time, if things are working too slow, people are just going to throw some more hardware at it.
I thought this was the exact reason that Gentoo Linux exists.
A stage 1 install will do the following:
1) Compile glibc from source using architecture specific optimizations
2) Compile gcc using the previously compiled optimized glibc and optimize gcc for the architecture
3) Compile everything else using said architecture specific optimized tools
4) ???
5) Profit!
And before all the trolls come in and say how long it takes to compile things, the Gentoo Handbook has several tricks like compiling from RAM, etc... to speed up compile times. I normally don't waste my time with Stage 1 because there are plenty of Stage 3 tarballs I can grab for whatever architecture I may be using at the time.
Back to the point, if your glibc is compiling your code using the MMX registers for memcpy(), memset(), etc... it completely invalidates the point in the article about how those extra registers go unused. Additionally the point he makes about data structures, while valid, is a non-issue given that most serious programmers have taken a Data Structures and Algorithms course where you learn that O(n Log n) is less than O(n^2), and will choose to use trees and hash tables where appropriate.
[sarcasm]Nevermind, he's dead on, no one ever implements a spanning tree in C code[/sarcasm]
I see your point about the vectorization of library code, but point me to a high level language which does not suffer from that flaw given your assertion of closed source libraries. That is true across the board regardless of the language used.
I thought it might be helpful for a current student to let you know what it is we learn today at my college. I'm a senior Software Engineering major, not a comp sci major. Comp Sci is another department and has a totaly different focus. They focus on super efficent algorithms, we focus on developing large software projects.
My software engineering program has been very Java intensive. My software engineering class, object oriented class, and software testing class were all java based. We dabbled in C# a bit as well.
However, I also had an assembly class, a programming languages class where we learned perl and scheme(this language sucks) and about five algorithms classes in C++. I also had an embedded systems class in both C and assembly(learned assembly MCU code, then did C).
I feel like this is all pretty well rounded; I've learned a bunch of languages and am not really specialized in one. I'd say I am best at Java right now, but I can also write C++ code just fine.
I've never been told a computer has any kind of crazy limitless performance. In embedded systems, I learned about performance. Making a little PIC microcontroller calculate arctan was fun(took literally 30 seconds without a smart solution). I also learned that there is a trade off between several things such as performance, development time, readability, and portability.
We are taught to see languages as tools, you look at your problem and pull a tool out of the tool box that you think fit the problem best. You have to weigh whats important for the project and chose based off of that.
The final thing I'd like to point out is that one huge issue with software today is it is bug ridden. How easy something is a test makes a big difference in my opinion. Assembly and C will pretty much always be harder to test than languages like Java and C#.
I don't think the universities are the problem, at least not in my experience.
My pet peeve with the article is "(...) at which point, you would be better off simply selecting a high-level language and letting someone else do the optimization."
Translation: "I'm not able to do something like that, so you can't either because I'm smarter than you, so let's just keep advanced features out of the programming language altogether."
If language designers argued that way, we wouldn't have Loki.
Other than that, the article raises a few good points in that there are _some_ ways in which high-level languages can be better optimized than low-level ones. Hand-optimized loops nowadays can easily get in the way of the (better) optimizations the compiler would perform.
Yet another apples to oranges comparison of language features and performance numbers. When are we going to start to see reporters getting up close and personal with real tests and numbers which attempt to compare task based operations on optimally tweaked code from various languages. I've had just about enough of someone saying that poorly written code in this language was slower than optimally written code in this other.
Maybe I didn't express myself well, but... yes, it's possible but normally it's not viable. Optimization (global optimization especially) is a repetitive, mechanical, task... which is best and fastest made by a computer than by a human being. Yes, I can think of clever ways for tweaking every part of a 1,000,000 LOC C (10M - 100M LOC asm) system, BUT I would take 100 years to do that! And an optimizing compiler in a fast machine will do a job 99% as good as I would in one hour -- two tops.
It's better to be the foot on the boot than the face on the pavement. ~~ tkx Kadin2048
A long time ago, until the idea of the stored program came along, computers were programmed with patch leads, so programs were little more than knitting patterns. The instruction sets of early stored program computers were developed around the hardware and were typically pretty chaotic. Then computers came along with consistent instructions sets that were specifically designed to assist compiler-writers (eg the VAX), but they no longer mapped terribly efficiently to hardware operations (as I recall, a single VAX instruction could cause over 50 page faults before completing!), so the "machine code" was a kind of intermediate language which was then interpreted by the instruction unit of the particular piece of hardware the program ran on. We're now kind of going back to the hardware-led instruction set (out-of-order execution, vector instructions, etc) simply because the balance of performance in the various parts of the computer (execution unit, memory, etc) has shifted again.
.net virtual machine languages).
The purpose of human-oriented programming languages (and I guess C just about qualifies...) is partly to make it easier to express the problem (and perhaps this is where we stop talking about C) and partly to provide a level of abstraction so that you don't have to rewrite the program for every piece of hardware. You can, of course, get the same effective abstraction from an intermediate language (such as the Java or
But notice the number of abstractions we may have - high level language is compiled to an intermediate language that is then compiled to a CPU instruction set that is then interpreted by microcode. And don't forget the abstractions taking place in the CPU hardware - the addresses are virtualised, memory is cached, instructions are re-ordered.
If you could control every aspect of the placement of your data, the use of the address-translation caches, the individual gates of the CPU, then your program would no doubt be very efficient. It would also run on only one piece of hardware.
There's always going to be a loss of potential performance if you don't code down to the gate level, but there are compensating benefits in productivity and the longevity of the solution, providing you choose a level of abstraction that is a natural fit for the problem you are trying to solve. If you try to use C to write a program for which it isn't particularly well suited (and that's a long list), then it's unlikely the compiler or anything else can help you!
From:
Subject: The truth about 'C++' revealed
Date: Tuesday, December 31, 2002 5:20 AM
On the 1st of January, 1998, Bjarne Stroustrup gave an interview to the IEEE's 'Computer' magazine.
Naturally, the editors thought he would be giving a retrospective view of seven years of object-oriented design, using the language he created.
By the end of the interview, the interviewer got more than he had bargained for and, subsequently, the editor decided to suppress its contents, 'for the good of the industry' but, as with many of these things, there was a leak.
Here is a complete transcript of what was was said, unedited, and unrehearsed, so it isn't as neat as planned interviews.
You will find it interesting...
__________________________________________________ ________________
Interviewer: Well, it's been a few years since you changed the world of software design, how does it feel, looking back?
Stroustrup: Actually, I was thinking about those days, just before you arrived. Do you remember? Everyone was writing 'C' and, the trouble was, they were pretty damn good at it. Universities got pretty good at teaching it, too. They were turning out competent - I stress the word 'competent' - graduates at a phenomenal rate. That's what caused the problem.
Interviewer: problem?
Stroustrup: Yes, problem. Remember when everyone wrote Cobol?
Interviewer: Of course, I did too
Stroustrup: Well, in the beginning, these guys were like demi-gods. Their salaries were high, and they were treated like royalty.
Interviewer: Those were the days, eh?
Stroustrup: Right. So what happened? IBM got sick of it, and invested millions in training programmers, till they were a dime a dozen.
Interviewer: That's why I got out. Salaries dropped within a year, to the point where being a journalist actually paid better.
Stroustrup: Exactly. Well, the same happened with 'C' programmers.
Interviewer: I see, but what's the point?
Stroustrup: Well, one day, when I was sitting in my office, I thought of this little scheme, which would redress the balance a little. I thought 'I wonder what would happen, if there were a language so complicated, so difficult to learn, that nobody would ever be able to swamp the market with programmers? Actually, I got some of the ideas from X10, you know, X windows. That was such a bitch of a graphics system, that it only just ran on those Sun 3/60 things. They had all the ingredients for what I wanted. A really ridiculously complex syntax, obscure functions, and pseudo-OO structure. Even now, nobody writes raw X-windows code. Motif is the only way to go if you want to retain your sanity.
[NJW Comment: That explains everything. Most of my thesis work was in raw X-windows. :)]
Interviewer: You're kidding...?
Stroustrup: Not a bit of it. In fact, there was another problem. Unix was written in 'C', which meant that any 'C' programmer could very easily become a systems programmer. Remember what a mainframe systems programmer used to earn?
Interviewer: You bet I do, that's what I used to do.
Stroustrup: OK, so this new language had to divorce itself from Unix, by hiding all the system calls that bound the two together so nicely. This would enable guys who only knew about DOS to earn a decent living too.
Interviewer: I don't believe you said that...
Stroustrup: Well, it's been long enough, now, and I believe most people have figured out for themselves that C++ is a waste of time but, I must say, it's taken them a lot longer than I thought it would.
Interviewer: So how exactly did you do it?
Stroustrup: It was only supposed to be a joke, I never thought people would take the book seriously.
as much as development process.
CPU power is available and cheap but time to market is critical. Most of the time, you don't need to do the fastest program ever, but to do a program that works reasonably well and that you can debug easily (some may say it is the same requirement).
C may not be the best tool for any given task but it is a pretty decent swiss army knife that most people know how to use reasonably well.
Disclaimer: I'm not in web devmnt but in embedded real time on DSP. With 8 dedicated ALU (2 mul, 2 add/sub, 2 logic and 2 load/store) running at the same time on the chip, there is still not many good alternatives to C (let the compiler optim and pray) and ASM (massive headhache).
To make judgements on a language based such trivialities is ludicrous. For all we know car and cdr where retained for sentimental reasons. Lisp is far more influenced by the abstract lambda calculus than by specific machine instructions. Lisp is a high level language by any sane definition.
Again you focus on the trivial. No sane person would judge Pascal by increment/decrement idioms. Focusing on Pascal's type system, parameter passing, lexically scoped functions and procedures would be more useful.
an ill wind that blows no good
Let's see what Tommy Boy has to say about this statement:
Tommy: Hey, I'll tell you what. You can take a good look at a butcher's ass by sticking your head up there. But, wouldn't you rather to take his word for it?
Mr. Brady: [confused] What? I'm failing to make the connection here son.
Tommy: No, I mean, you can get a good look at a T-bone by sticking your head up a butcher's ass, but then..no. It's gotta be your bull.
When I have a kid, I want to put him in one of those strollers for twins and then run around the mall looking frantic.
Patrick Doyle
I mod down every jackass who puts his moderation policy in his sig. Oh, wait a sec....
Computer science is no more about computers than astronomy is about telescopes" -- Edsger Dijkstra quotes (Dutch computer Scientist. Turing Award in 1972. 1930-2002)
I see this quote everywhere, and just because it's by some semi-famous academic, nodody questions it and takes it for granted. The quote is utter rubish.
With astronomy you have stars, which aren't man made and thus only scarcely understood and the tools we use to look at them, teleskopes, which are man-made. We understand them.
Computers and Computer Science are both things that are entirely man-made. There is no natural phenomenon that we call 'computer' and a science that studies this natural phenomenon called "computer science". It's all one thing. The quote is rubbish and contains no usefull information whatsoever. On the contrary: the conclusion it draws in abolutely false.
We suffer more in our imagination than in reality. - Seneca
the author is only a couple of years out of college and he is already well on his way to be becoming a professional troll. I see a bright future for him...
need a free COBOL editor for Windows?
People will always argue over 3 things:
1) whether assembly is faster than C
2) whether interpreted languages are faster than C/C++
The real question here is - which type of language does well for your application?
Ultimately C will be faster if a good programmer, who understands the language and the application. However, will he be more productive? I'd never write a third person shooter in python, perl, or java. However, what I might do is add a 3d engine to a python statistics modeling program that's already written in one of those languages. Most people would agree, writing a web interface in C is just insane if you have anything particularly useful you want to write. However, I'll probably write a multi-process webserver in C, just because it makes sense for speed (I know python has a built-in webserver, but there are features it doesn't have. You may be able to write it in python, but will all those features that apache have be fast?).
The bottom line is:
- Define the application you want to build.
- Define your requirements (responsiveness, rhobustness [security,reliability,etc], extendability, deadlines).
- Do a little research with a few languages (just experimentation). Write prototype interfaces in the language, do a little benchmarking, just play with it.
- Make a decision on a language based on what you've found and what's required.
As more high level languages appear (functional languages look very promising), see what those languages have over what's already out there. If it has an applicability to what you're doing, use it.
I'm tired of seeing everyone beat a dead horse. Yes, I know the two arguments:
- X is faster
- Y is just as fast as X, but can do it in less lines of code.
X & Y are different, there's no ignoring it. There's more dimensions to languages than speed and time to market, don't ignore them.
Sorry, I have to laugh at this one (at your expense)
>> "I don't think the universities are the problem, at least not in my experience."
Do you *have* any experience?
>> "The final thing I'd like to point out is that one huge issue with software today is it is bug ridden. How easy something is a test makes a big difference in my opinion. Assembly and C will pretty much always be harder to test than languages like Java and C#."
What makes you think that Assembly and C are harder to test? Have you ever used a debugger? I step through code, I can even see the assembler being executed. There are FAR better tools for debugging "real" compiled code than there are interpreted code. If the program is hung, I can stop a program excatly where it is and see my stack and my actual code path. I can even send it a SIG_INT and break into the debugger. With a core dump I can do a post-mortum on a crash.
C became popular because of Unix. Since you could get the source code for Unix most big universities used Unix in there OS courses. And since it was written in c you where going to learn C if took Computer Science. Textbooks started to assume you knew c. Magazines started to assume you knew c. People wrote free small c compilers and then came GCC, so now you could have a good free c compiler for just about any system. But before GCC all the buzz was about Smalltalk. Smalltalk was the future. OOP was going to replace structured programing. The problem was very few people has a computer that could run Smalltalk. So C++ was born.
A final blow to Modula-2 was simply Borland didn't create a Modula-2 compiler. For many years when you said Pascal you reall meant Turbo or Borland Pascal. Borland was the Pascal company and they add objects to pascal and eventual created Delphi.
I am sure Topspeed has closed up shop. There just isn't much room for compiler makers anymore. You have the free software at the bottom end and the Microsoft Monster at the top. Only a few niche players are left. Ada seems to be a place where a good compiler company can still make a few dollars.
See my blog http://ilovecookes.blogspot.com/ for light hearted technical information.
Coding large apps in assembly is usually way beyond the point of diminishing returns in terms of performance.
Patrick Doyle
I mod down every jackass who puts his moderation policy in his sig. Oh, wait a sec....
I can't speak to other industries, but in the aerospace segment of the embedded market the trend is clear. Future development will be model-driven.
But it's rather long. I posted the detailed reasons in my blog.
In a nutshell:
- Intel has put lots of optimizations into the actual CPU. The author did not account for those.
- Future proof - C is a simple language, for which it is simple to write complex optimizers.
Shachar
Amazingly far back (try the 80s) a professor friend of mine had a marvelous example of compiler-generated code where the compiler had done such an amazing job of optimising register use that you had to trace through more than 20 pages of assembler output with colored markers to trace from where the register was loaded to where it was used.
No way I would ever have the huevos to code that way in assembler. On a RISC machine or (Heaven help us) the Itanic it gets lots worse.
Lacking <sarcasm> tags,
You beat me to it. What you just said, innernerd, was that you consider yourself a jack-of-all-imperative-languages and that you hate things that don't look like Algol. That's like saying that you're a linguist because you can speak American, British, and Australian English (but never really tried Spanish, Russian, or Japanese).
It's too bad, really, because there's a lot of fun and profit to be had in the non-imperative realm. I hope you can see that some day.
Dewey, what part of this looks like authorities should be involved?
I had the sneaking suspicion from the first page of this article that Java was going to be trotted out.
I think possibly the most boring tech article genre ever is "Person who likes Java writing yet another essay about how great Java is." To be quite honest, I'm not interested. I agree, high-level languages are great. That's actually a lot of why I don't like Java-the-language. Sure, it's got a garbage collector, but its syntax and semantics are those of C. C syntax is like the QWERTY of programming languages - it may not have been explicitly designed to slow you down when it was first created, but bugger if that isn't the main thing it's good for nowadays.
I'm also rather tired of the Java-isn't-really-slower thing. Folks make the argument, they trot out all sorts of benchmarks that are great at proving that Java is wonderful for running benchmarks. At least this article admitted what everyone already knows from experience - that Java bytecode running on the virutal machine produces apps that are slower and eat more memory than equivalent apps that run native. GCJ evades that problem, but otherwise, why should I care about it? If I'm compiling to native code rather than to the JVM, I'm suddenly presented with the option of using a whole host of other programming languages that blow Java out of the water in the ease-of-programming department.
You may have the time to lovingly hand-code an initialization routine, making sure at each line to check the scoreboard for the multiple execution engines on each stage of the CPU's pipeline so as to avoid congestion stalls. I'm sure that you can crank out as many as ten lines a day that way.
Similarly, Bob Pease also lovingly calculates the equations for analog circuits, eschewing the use of simulators.
The rest of us are content to let that massive bookkeeping chore to computers, because hand-calculating the intersymbol interference in a multi-gigabit signaling environment (with adaptive decision-feedback equalization) in the face of multiple parametric variables would take until the next millennium.
The same goes for scoreboarding multiple-issue deep-pipeline processors with branch prediction. You just do not want to go there by hand, but compilers do it easily.
Lacking <sarcasm> tags,
I was not talking about industry experience, I was talking about univesity experience. I figured this would be helpful, as it has been many years since many people on \. went to a university. It's easy to talk about what is supposedly being taught, but unless you are currently in a university how can you know? The simple fact is the supposed univeristy experience the parent talks about is not realistic, at least nto for me. I am not saying I am some software expert or even know all that much, I am just giving the observations of a student. I can't say I will learn everything I need to know, but I think it will be pretty close. A big problem today is that computer majors are gettign really hard to squeeze into 4 year programs. As far as the testing remark, I have used the Visual Studio debugger to trace through C, C++, assembly. It wasn't all that bad. However, in my Software Tetsing class we actually created testing tools in Java and C#, it was pretty cool I actually made my own java debugger quite easily. Java has some cool features that actually let you talk to the virtual machine. This can be very helpful. We made one tool that let you see how many times every line of code was executed, that way you could make sure you covered them all in test cases. Maybe C and assembly have this, I don't know.
I program mostly with java and python, and php for web sites. I'll probably agree(though I can't actually verify it myself) that C/C++ programs will run faster. However...I can accomplish alot more in a much shorter amount of time, and do so much safer in java. Java's object serialization, I/O, and networking for example make so many projects much faster and easier. Sure, they don't run as fast as a native program, but that's not the point. There are tradeoffs to any language/platform one chooses.
My problem? I was perfectly gruntled, until some numbnuts came by and dissed me.
No, what they SAY is "The proof is in the pudding" --
From google:
Results 1 - 10 of about 326,000 for "the proof is in the pudding". (0.47 seconds)
Results 1 - 10 of about 118,000 for "the proof of the pudding is in the eating" [definition]. (0.30 seconds)
They're not right, of course, but then, sadly, you're not either, since what people say has changed. It's changed to something nonsensical, which people quote without understanding, which is annoying, like "I could care less!":
Results 1 - 10 of about 2,180,000 for "I could care less". (0.28 seconds)
Results 1 - 10 of about 776,000 for "I couldn't care less". (0.22 seconds)
But "the proof is in the pudding" kind of rolls off the tongue better... like a pudding which tastes nasty and you are therefore gently, but suavely, spitting out.
I coded the same CPU-intensive program in both Fortran and C on a DEC microvax back in 1988 - the Fortran program was about twice as fast. I tried every trick that I could think of to get the C code to improve - in the end it was still a little slower than the Fortran code (2%-10% slower), and the speed optimization had reduced the code to an unsupportable mess.
Here is the reason I hate scheme. Compare these two lines and tell me which makes you're head hurt really bad. Java, C++, C#, C: (3+4) *5 -6 /2 +3
Scheme:
(+ (/ (* (+ 3 4) 5 ) 2) 3)
I thought the functional thing was cool, I just think they went a bit too far.
Most truly high-level languages, like LISP (which was mentioned directly in TFA), are interpreted, ...
... and the interpreters are almost always written in C. It is impossible for an interpreted language written in C (or even a compiled one that is converted to C) to go faster than C.
Programming languages are not "interpreted". A language IMPLEMENTATION may be based on an interpreter. Every major implementation of Common Lisp today has a complier, and most of them don't even have an interpreter any more - everything, including command-line/evaluator input, is compiled on-the-fly before being executed.
Again, this is a property of implementations, not of languages. The highest-performance Common Lisp implementations have scaffolding written in C and assembly, but they do not use a C compiler when they compile Lisp code. They often use non-C ABI conventions for argument passing and stack handling, to make their style of function calling faster.
I don't mean to be harsh, but the "Lisp is slow because it's interpreted" meme is about twenty years out of date. It tends to be spread primarliy by college professors whose last exposure to Lisp was pre-1980, and it really grates on those of us who know better.
To a Lisp hacker, XML is S-expressions in drag.
The article later points out that the native version was running slower due to not using optimization options correctly. And later the native version was running 15% faster than the managed version
Copyright infringement is "piracy" in the same way DRM is "consumer rape"
I agree entirely, and I'm glad I'm not the first person to have thought so. Rather than shifting low level around to encompass C, why not make a mid-level classification and shove C in there? After all, it helps a bit to know about the architecture you're compiling to when writing C, but it's not necessary like assembly.
:(){
yodav("That is why you fail.");
I like C, and I tend to write imperative Python. But for what I do, that's very appropriate.
But if you are referring to a dialect of Lisp as a language that "sucks", you need more in your brain before you open your mouth.
-- Erich
Slashdot reader since 1997
...then come back and tell me if you still believe this after reading the result.
I recently came across code that essentially did this to test for a power of two and then multiply by it:
if (var == 1 || var == 2 || var == 4) {
switch (var) {
case 1: var2 = var2; break
case 2: var2 = var2 + var2; break;
case 4: var2 = var2 << 2 break;
default:
}
Given the sheer number of assembly instructions (+jump table) needed for the above, I don't think anyone could make the case that this is more efficient than if (var == 1 || var == 2 || var == 3) var2 <<= var
(and no, the effects on the flags register were not being used.)
Just because it is technically possible to have compilers that optimize well doesn't mean our compilers actually do so. Now granted this was probably made by a lame MS compiler, but it shows that faith in compilers may be misplaced, and most certainly should not be transferred from one compiler to another.
(Aside... sometimes I think some people who code compilers have absolutely no idea of the price of code/data cache/bus bandwidth.)
Someone had to do it.
Huh? I would argue that commercially successful (as in boxes sold to Fortune 500 companies and used in production) operating systems have been written in three languages:
* Assembly
* C
* Lisp
Are there any commercially successful OSs written in C++ yet?
(revealing my ignorance and posting flamebait, all in one)
To a Lisp hacker, XML is S-expressions in drag.
of finding a good Algol compiler these days one is forced to use FORTRAN 77 for speed.
I want to say "all the OS X kernel" but I'm not sure that's true.
Clear, Dark Skies
I've probably written more assembly than most slashdot readers, and most of what you say is true:
It used to be the case that I could always increase the speed of some random C/Fortran/Pascal code by rewriting it in asm, parts of that speedup came from realizing better ways to map the current problem to the actual cpu hardware available.
However, I also discovered that much of the time it was possible to take the experience gained from the asm code, and use that to rewrite the original C code in such a way as to help the compiler generate near-optimal code. I.e. if I can get within 10-25% of 'speed_of_light' using portable C, I'll do so nearly every time.
There are some important situations where asm still wins, and that is when you have cpu hardware/opcodes available that the compiler cannot easily take advantage of. I.e. back in the days of the PentiumMMX 300 MHz cpu it became possible to do full MPEG2/DVD decoding in sw, but only by writing an awful lot of hand-optimized MMX code. Zoran SoftDVD was the first on the market, I was asked to help with some optimizations, but Mike Schmid (spelling?) had really done 99+% of the job.
Another important application for fast code is in crypto: If you want to transparently encrypt anything stored on your hard drive and/or going over a network wire, then you want the encryption/decryption process to be fast enough that you really doesn't notice any slowdown. This was one of the reasons for specifying a 200 MHz PentiumPro as the target machine for the Advanced Encryption Standard: If you could handle 100 Mbit Ethernet full duplex (i.e. 10 MB/s in both directions) on a 1996 model cpu, then you could easily do the same on any modern system.
When we (I and 3 other guys) rewrote one of the AES contenders (DFC, not the winner!) in pure asm, we managed to speed it up by a factor of 3, which moved it from being one of the 3-4 slowest to one of the fastest algorithms among the 15 alternatives.
Today, with fp SIMD instructions and a reasonably orthogonal/complete instruction set (i.e. SSE3 on x86), it is relatively easy to write code in such a way that an autovectorizer can do a good job, but for more complicated code things quickly become much harder.
Terje
"almost all programming can be viewed as an exercise in caching"
It's possible to say everything siad in this article -- vaugely, as it is said in this article -- and be right, and yet still dance around the reality.
Take a look yourself on http://shootout.alioth.debian.org/
C's faster than Java. It will probably always generally be so, unless you're trying to run C code on a hardware Java box.
This article says Java, for example, CAN be faster. But it doesn't say "C is almost always faster than Java or Fortran, usually faster than ADA, and C can be mangled (in the form of D Digital Mars, for instance) to be faster than C usually is. Often, Java is a pig, compared to C, BUT THERE ARE TIMES WHEN IT ISN'T. Really. There are times, few and far between, when it's actually, get this, FASTER. It's fun to look for those few times. And if you write programs which do that, that'd be cool. And as processors get wackier and wackier, there will be more and more times where this is true. Meanwhile, if your developers write good code, Java's easier to develop in and debug." Which would be more completely correct.
Excuse, me, now. I have to go back to my perl programming.
Yay. With continued displays of attitudes like that, I'm going to leave the industry.
It is getting increasingly difficult to hire S/W engineers that understand that there is an operating system and also hardware beneath the software they write. I need people NOW that can grok device drivers, understand and use Unix facilities, fiddle with DBs, write decent code in C, C++, Java, and shell, and can also whip together a decent WS interface. Someone who does all of those.
WhyTF has the S/W industry become so compartmentalized? I can hire a device driver person, but he won't know anything about web services. I can hire a DB person, but she won't know a damn thing about poking values into registers. I can hire a web-services person, but he will have never worked on a Unix platform before. WTF? Really, WTF?
In short, I can't hire someone who can take ownership of an entire system. It's always, "Well, that's a hardware thing, go ask Foo", "Oh, it looks like the database, need to talk to Bar", "The Web interface is borked, we'll need to bring Baz in", "Hm, it doesn't do this when we run it on Windows" (this one always pisses me off, because they can never explain why, and that's because they know nothing about Unix). How come I can't hire someone who could understand a whole vertical stack (and maintain it, and provide analysis and fixes when something breaks)?
I do this kind of thing now. If I can do it, it can't be that hard. But everybody thinks they have to specialize. THIS IS WHAT'S WRONG WITH THE INDUSTRY.
In the course of every project, it will become necessary to shoot the scientists and begin production.
My assembly code was done from his C code, I couldn't have done it easily without having the C code first. And the algorithm came from a scientific paper, having been benchmarked against many other algorithms for doing the same thing. Even if it wasn't optimal (as the other guy proved later), it wasn't sloppy or anything like it.
It WAS a different algorithm for the same routine, not simply a recoding of the same algorithm. Sorry for not having said it so explicitly the first time. Of course algorithms are more important than implementations, which doesn't mean that the effect of the implementation isn't important as well. Everyone with serious knowledge of software performance knows that.
Now you start to seem like you have a too broad view of what algorithmic improvement is. Algorithms have nothing to do with code, they're a level of abstraction above (as you can see in any scientific paper presenting a new algorithm, they rarely give anything more than pseudocode). Instruction scheduling is NOT an algorithmic improvement, it's an platform dependent implementation detail. Their FAQ answer which says compilers aren't good at it just shows that they also think a human is better at optimizing code.
This is, again a sentence coming from your broad view of what algorithmic improvement is.
I didn't paste the whole TODO file, and even on the part I pasted ALL the references are to assembly code. Look at them please. Even the only one which doesn't mention asm explictly is speaking about registers, which you can't manipulate directly in C. I don't want to sound like an ass but at least show some knowledge regarding what we're talking about...
And to clarify: my point is there a good assembly programmer can often do much better than any compiler, and that things will stay that way for some time to come. Eventually the situation may be the opposite, but right now it surely isn't!
The AACS key is NOT 0xF606EEFD628B1CA427BEA93A9CA9773F
Well, the first AC got it right. You're scared of syntactical differences. That's really bad. I was going to suggest that you read "On Lisp" and "Structure and Interpretation of Computer Programs" for enlightenment, but it's apparent that you're beyond help.
When Fortran was made, nobody thought that CPUs of 30 years in the future will have vector processing instructions. In fact, as Wikipedia says, vector semantics in Fortran arrived only in Fortran 90.
The only advantage of current Fortran over C is that the vector processing unit of modern CPUs is better utilised, thanks to Fortran semantics. But, in order to be fair and square, the same semantics could be applied to C, and then C would be just as fast as Fortran.
The fact that C does not have vector semantics reflects the domain C is used: most apps written in C do not need vector processing. In case such processing is needed, Fortran can easily interoperate with C: just write your time-critical vector processing modules in Fortran.
As for higher-level-than-C languages being faster than C, it is purely a myth. Code that operates on hardware primitives (e.g. ints or doubles) has exactly the same speed in C, Java and other languages...but higher level languages have semantics that affect performance as much as they can help performance. All the checks VMs do have an additional overhead that C does not have; the little VM routines run here and there all add up to slower performance, as well as the fact that some languages are overengineered or open the way for sloppy programming (like, for example, not using static members but creating new ones each time there is a call).
n Fortran, modifying the same variable through two different names leads to undefined behavior
So, COMMON blocks have been removed from the language?
Clear, Dark Skies
I'll stop being hard on you, but you REALLY need to get a clue about what you don't know. Believe me, this is not intended as an insult, you are a student, you couldn't possibly know.
.net have better debugging tools, but you don't even know what debugging tools are currently available. The little you think you know is be better than the rest that you don't, and that is not an informed way of approaching problems.
>>"I can't say I will learn everything I need to know, but I think it will be pretty close"
You best lose that attitude right now. It is wrong on almost every level. Pretty much every word, as ordered in that sentense, is wrong. You don't really learn until you leave school. School gives you foundation so that you are not utterly lost in the real world.
The smartest thing you wrote was this:
>> "Maybe C and assembly have this, I don't know."
You really don't, and that's sad. Whats even more sad is you don't realize that you do not know. For instance, you wrote: "We made one tool that let you see how many times every line of code was executed," that's called a profiler and they've been around for years (decades?), and, yes, they have them for C and assembly.
Listen, I don't want to play bash the nubee all day, while it is sort of fun, it isn't very nice, your arguments are making my point. You claim that java and
Yes, yes, quite, uhhuh... virtual code based programming languages are nice but once cannot scientifically show them to be faster than or even equal to machine-code based programming languages for most operations. Everything else is design fluff. I would much rather write a payroll system in Java (or COBOL) but will stick to C or Assembler for drivers, realtime graphics, or significant byte manipulation. True believers in JVM's should not feel threatened by this observation. Java is still cool but its not C.
If it were done when 'tis done, then t'were well it were done quickly... MacBeth
While this is true, it's not an impediment for 99.9% of programmers. Many modern microprocessors are not only designed to be programmed in C; they are optimized for it.
The key to fitting the code to the target CPU is in the tools. The hard part is in the optimizer, and that's where some OSS tools may be weak. It's one thing to generate code that will execute on a platform, but a completely different (and far, far more difficult) thing to generate code that will coax the maximum performance from a given CPU.
there are 3 kinds of people:
* those who can count
* those who can't
This paragraph is complete crap. If you're using a Dictionary API in a so called "low-level language", it's as possible for the API to do the same optimization as it is for the runtime he talks about; and you're still letting "someone else do the optimization".
That makes no sense. TFA says " This kind of dynamic optimization is simply impossible in a low-level language without building higher-level semantics on top..." and you say "this is crap because all I have to do is call a 3rd party API to get the same thing."
In other words, you're saying it's not true that you have to add another layer of abstraction to C to get dynamic dictionaries because all you have to do is add dynamic dictionaries.
Huh?
Clear, Dark Skies
No, what they say is 'the proof is in the pudding' as you admit when you point out that most people get it 'wrong'. If most people say 'the proof is in the pudding' then that is what they say, by definition.
"Who is the Journal of Quantum Physics going to believe?" --Stephen Hawking
was a fine virtual machine and UCSD Pascal (with the CPM board) was actually productive years before java brewed it's first cup.
If it were done when 'tis done, then t'were well it were done quickly... MacBeth
I just want to question that one assumption, which seems to get thrown around a lot. "Software sucks today". Really? My path was C64, Amiga, Win95, Linux, OSX. I feel that software became notably more powerful, less buggy, and easier to use over my computer experience. People love to say things suck, compared to some hypothetical (and quite possibly unrealistic) idea of how things should be. But by any measure that matters in practice, software today seems eons ahead of where it was two decades ago.
Cheers.
the compiler wouldn't have generated better code anyway since it wouldn't use MMX opcodes
Wasn't that a point of the original article - that languages that are "higher level" than C support constructs that could be mapped right onto MMX (now SIMD) instructions?
The lack of sophisticated data types in C is a consequence of the abilities of the machines C was originally designed to run on. While that was C's greatest strength of many years, someone starting from scratch could certainly design a new language that had a better mapping to the current generation of processors.
Clear, Dark Skies
C is best at what it was designed for - controlling the computer. It used to be that people chose the language to match the app they were writing: For math, use Fortran or APL. For reports use Cobol or RPG. C for flipping bits. Pascal for teaching.
We're where we are today because, for many years, C was the one you could get for free. The others cost hundreds of dollars.
I remember the first time I encountered a computer that shipped from the vendor with GCC instead of a proprietary compiler - it was like seeing a death sentence for Abacus, Lightspeed, and all those other little compiler companies.
Clear, Dark Skies
"On both languages" - what languages are you talking about? The original statement didn't mention any languages by name. I can easily imagine a Lisp compiler that dynamically decides how to store the data in a complex list, or a Fortran compiler that takes advantage of SIMD. The point is that a language that has a built-in Dictionary type allows the compiler to make optimizations that aren't possible in a language that doesn't.
In other words, none of your three points make any sense.
Clear, Dark Skies
It can be made to be fast, and it can be made to be as high level as you want. I ofter wonder what the world would have been like if more programmers had gone the Forth way instead of the C/*nix way.
This is all relatively moot right now, as it is hard to tell what the impact of the new generation of Intel (and presumably, soon, AMD) processors will have. As languages have evolved, so have processors. When C became popular, it was possible to optimize the common case of C-style function call conventions. As C++ and other langauges that used vtables became popular, processors had to re-align their optimization strategies (and in fact, were defeating compiler optimizations for years with respect to C++). Now that high-level virtual machines are the norm, another wave of processor optimization is about to kick in. From what I've heard, high-level languages such as Perl, Java and Lisp are substantially improved by the newest round of Intel processors, but it will be a while longer before we have enough experience with these new processors to be sure of what impact they have had.
High level languages have always been compared to cognitive semantics and grammatical styles. That is the higher the level of the language the easier it is for us humans to read and write it. Conversely, the lower the level the language is the more discreet steps are needed to describe an instruction or data.
Speed of program languages or machine languages are not measured by how high or low level they are to us. They are also measured by time to develop and implement the program. The article basically makes a point of it, that it's "better to let someone else" to optimize the low-level code while you write with the high-level language. You could write a super fast machine coded program, but it'll take you much longer to write it than with a simpler higher level language.
The new debate is over datatypes and the available methods to manipulate them. Older hardware gave us the old debate with primitive datatypes and a general set of instructions to manipulate the data. Newer hardware can give us more than just primitives. For example, a unicoded string datatype seen by the hardware as a complete object instead of an array of bytes. With hardware instructions to manipulate unicoded strings, that would pratically take away any low-level implementation of unicoded strings. The same could be done for UTF-8 strings. We could implement hardware support for XML documents and other common protocols. How these datatypes are actually implemented in hardware is the center of the debate.
Eventually, there will be so many datatypes that there will be seperate low-level languages specifically designed for a domain a datatypes. The article makes the point there exists an increase in complexity for newer compliers to understand what was intended by a set of low-level instructions. Today's CPUs have a static limit of low-level instructions. The future beholds hardware implemented datatypes and their dynamic availability of low-level instructions. Newer processors will need to be able to handle the dynamic set of machine language instructions.
Does the new debate conflict with Turing's goal to simply make a processor unit extensible without the need to add extra hardware? For now, we have virtualization.
"I do this kind of thing now. If I can do it, it can't be that hard. But everybody thinks they have to specialize. THIS IS WHAT'S WRONG WITH THE INDUSTRY."
So does it bother you that medicine has specialized then?
A number of the implementations at the Computer Language Shootout leave a great deal to be desired. I
am most familiar with the C and C++ ones, and know firsthand that many of them can be improved with respect
to performance (the C++ examples are particularly poor). They often aren't just "flawed"-- they aren't even
doing the same thing. This is not very easy to achieve.
Furthermore, they are microbenchmarking. I am not against this, but it has to be pointed out that they don't
take into consideration concurrency and other such issues. Of course, design and choice of correct algorithms
in a real application are where your biggest gains are going to come from-- saving some times with a "fast"
language is almost never as initially significant as doing the right thing to the data, in any language.
So, in theory, higher level languages could be faster than lower level ones, but in practice...
So your problem with Scheme is that it uses prefix notation for mathematical operations? If someone did not immediately answer the question of why the hell this is done by citing the "(function argument1 .. argumentN)" style of Scheme code then they did a shit job of teaching it. Prefix notation is useful in Scheme for two things: 1) It makes figuring out order of operations dead simple, and 2) It matches the style in which every other bit of code is written. No wonder software sucks today, the people that actually bother to go to school and learn it can't get competent treatment of the subject.
Slashdot: Where anecdotes and generalizations can be freely substituted for facts, logic, or intelligence
All these "twenty years ago" debates are to valid to some degree. However, during that time performance and storage has increase an order of magnitude every five years.
But there are still some apps where you hit the wall, e.g. gaming graphics. Coding efficiency still matters in some cases.
I'm not sure that this has to do with a low-level/high-level language debate any more. Consider, for example,
t m
that C++ offers both very low and very high-level semantics. When properly used, this yields high level
programs with excellent performance.
But, so what? Neither C++ today, or any other very widely-used programming language adequately manages the
real problem, which is concurrency.
Herb Sutter has written an excellent paper on this topic, called "The Free Lunch is Over". Let's get off this
hobby horse and on to some real (and interesting) problems!
Here is Mr. Sutter's article: http://www.gotw.ca/publications/concurrency-ddj.h
I just hope theres no meat in my pudding.
Wherever i go, There i am.
It's pretty ugly, but it is possible to hint some compilers about such things using OpenMP, etc.
What is the difference between an actual language feature and an implementation detail? Give an example of each. (5p)
"I suspect you are getting confused with the fact that VMware and such are fashionable these days. These virtual machines have nothing in common with programming language VMs."
Um, no. The trend in question is "abstraction" (when was the last time you toggled switches to program a computer? Miss it?). Now we're past the point of high-level languages, and onto frameworks and toolsets which are a layer above high-level. I see this continuing, AND I see CPU designs adjusting to accomodate this trend. As some of the posts here have pointed out, the path to productivity isn't "toggling switches"*, but programming your "intent" in a high-level language, and letting the middle-layers translate.
*The people who DO need to know about "toggle switches" are in the minority (those interpreters, compliers, VM's).
Nuff Said.
It's pointless to try and reason with these people: the idea that C and C++ are "efficient" has become an article of faith. This problem will only solve itself the way all such problems solve themselves: the generations brought up on C and C++ need to die out, and they need to get replaced by a new generation of people brought up with more rationally designed languages. We're going to be stuck with C and C++ as mainstream languages, and all the bloat and inefficiency that that entails, for at least another two decades.
How can you have any pudding if you don't eat your meat?
My blog. Good stuff (when I remember to update it). Read it.
The article is a bit simplistic.
With medium-level languages like C, some of the language constructs are lower-level than the machine hardware. Thus, a decent compiler has to figure out what the user's code is doing and generate the appropriate instructions. The classic example is
char tab1[100], tab2[100];
int i = 100;
char* p1 = &tab1; char* p2 = &tab2;
while (i--) *p2++ = *p1++;
Two decades ago, C programmers who knew that idiom thought they were cool. In the PDP-11 era, with the non-optimizing compilers that came with UNIX, that was actually useful. The "*p2++ = *p1++;" explicitly told the compiler to generate auto-increment instructions, and considerably shortened the loop over a similar loop written with subscripts. By the late 1980s and 1990s, it didn't matter. Both GCC and the Microsoft compilers were smart enough to hoist subscript arithmetic out of loops, and writing that loop with subscripts generated the same code as with pointers. Today, if you write that loop, most compilers for x86 machines will generate a single MOV instruction for the copy. The compiler has to actually figure out what the programmer intended and rewrite the code. This is non-trivial. In some ways, C makes it more difficult, because it's harder for the compiler to figure out the intent of a C program than a FORTRAN or Pascal program. In C, there are more ways that code can do something wierd, and the compiler must make sure that the wierd cases aren't happening before optimizing.
The next big obstacle to optimization is the "dumb linker" assumption. UNIX has a tradition of dumb linkers, dating back to the PDP-11 linker, which was written in assembler with very few comments. The linker sees the entire program, but, with most object formats, can't do much to it other than throw out unreachable code. This, combined with the usual approach to separate compilation, inhibits many useful optimizations. When code calls a function in another compilation unit, the caller has to assume near-unlimited side effects from the call. This blocks many optimizations. In numerical work, it's a serious problem when the compiler can't tell, say, that "cos(x)" has no side effects. In C, it doesn't; in FORTRAN, it does, which is why some heavy numerical work is still done in FORTRAN. The compiler usually doesn't know that "cos" is a pure function; that is, x == y implies cos(x) = cos(y). This is enough of a performance issue that GCC has some cheats to get around it; look up "mathinline.h". But that doesn't help when you call some one-line function in another compilation unit from inside an inner loop.
C++ has "inline" to help with this problem. The real win with "inline" is not eliminating the call overhead; it's the ability for the optimizers to see what's going on. But really, what should be happening is that the compiler should check each compilation unit and output not machine code, but something like a parse tree. The heavy optimization should be done at link time, when more of the program is visible. There have been some experimental systems that did this, but it remains rare. "Just in time" systems like Java have been more popular. (Java's just-in-time approach is amusing. It was put in because the goal was to support applets in browsers. (Remember applets?) Now that Java is mostly a server-side language, the JIT feature isn't really all that valuable, and all of Java's "packaging" machinery takes up more time than a hard compile would.)
The next step up is to feed performance data from execution back into the compilation process. Some of Intel's embedded system compilers do this. It's most useful for machines where out of line control flow has high costs, and the CPU doesn't have good branch prediction hardware. For modern x86 machines, it's not a big win. For the Itanium, it's essential. (The Itanium needs a near-omniscient compiler to perform well, because you have to decide at compile time which instructions should be executed
What's wrong with Perl, as a very powerful and flexible replacement for C?
Seriously, Perl can be ugly, but that's mostly the language revealing the real programmer inside, and being flexible enough to be ugly or pretty. I think it's also informative to try and compare languages another way: what do they fix?
Nathan's blog
C was a reaction to both BCPL (via the language B) and PL/I. The UNIX designers, Thompson, Ritchie, et. al., came from the Multics project, and Multics was mostly written in PL/I with some BCPL. Most (but not all) of the BCPL code was written by the Bell Labs members of the Multics team. BCPL was a completely type-less language. C introduced a few rudimentary types.
By contrast, PL/I had a much more complete type system, although it was not even close to "strongly typed".
PASCAL was still very very new when C was designed.
In particular, PL/I strings and arrays were first class data types with compiler-known lengths,
and buffer overflows were MUCH MUCH less common. (not impossible - just much less common).
Full PL/I was an enormous language and hard to compile, but the ANSI G subset was actually quite
reasonable and not hard to compile for. The DEC PL/I (ANSI G subset) and C compilers for the VAX used the same code generator back-end (written by Dave Cutler who also designed RSX-11/M, VMS, and Windows NT), but the PL/I compiler produced better code for string and array handling, precisely because the compiler knew more about what the programmer actually intended. It could take better advantage of the VAX instruction set, particularly for strings of maximum known length. String instructions, such as on the VAX or the IBM System/360 could easily handle PL/I strings, but null-terminated C strings were much harder to compile for. This is not surprising, since IBM designed PL/I as a language for the System/360.
You are a tool
The only advantage of current Fortran over C is that the vector processing unit of modern CPUs is better utilised, thanks to Fortran semantics.
The reason why Fortran often vectorizes better is not that Fortran has array ops (in reality, modern Fortran compilers actually scalarize array expressions before handing the code over to the middle end tree optimizers), but due to different aliasing rules than C. This was the main reason why Fortran 77 (with no array ops) often was an order of magnitude or so faster than C on old vector supercomputers.
Sure C can get the same kind of thing with const and restrict, but googling reveals that ironically one of the very few places where it's actually used is in the runtime library of the GNU Fortran compiler.
How about the fact that ruby is very significantly slower than perl and python? How about the fact that depending on your personal preferences, you could easily argue that perl or python are elegant too.
If you actually paid attention, you would notice that there are webserver written in high level languages that perform far better than 99% of people need. In fact, I wrote a webserver in kornshell that easily saturates a 100Mbps pipe. Using a webserver written in a high level language instead of apache is not a problem at all.
Your illiterate, incoherant rambling has given me a "massive headhache".
You people with your "languages". I write a program by randomly typing 1's and 0's. I'm half-way done with PONG.
Should I be ashamed that I graduated with a B.S. in computer science and still can't follow what discussions like these are talking about?
Maybe this is Ph.D stuff... ?
Too about this wonder I
I can think of several general applications that could NOT or at least should NOT be developed in a truly high-level language like Java:
- Real Time Client/Server programs
- Gaming (intensive CPU/Graphics)
- Servers that deal with large amount of data/connections/transactions
*** Not to mention any application that should run for a long period of time and thus must not "trust" OS's memory management and the inherent cost of memory fragmentation.
You claim that in your department you "focus on developing large software projects", and then say you "hate" Scheme (and it "sucks") because a simple arithmetic problem is written differently than C? *sigh*
I work at a company maintaining and developing medium-to-large (hundreds of thousands of LOC) systems. We're not using Scheme (we're using Python), but it would have been a good choice as well.
- Number of times I've had to do arithmetic on 6 small numbers: zero.
- Number of times I'm glad Python at least has first-class closures, bignums, map/apply, and gobs of other Scheme features: every day.
- Number of times I wished I had real macros: once or twice a week. (Decorators help a bit, and the with-statement in 2.5 -- which looks just like Lisp -- will make it even nicer.)
When you graduate to writing real programs, young one, you'll realize that there's more to programming than addition and multiplication.
We are taught to see languages as tools, you look at your problem and pull a tool out of the tool box that you think fit the problem best. You have to weigh whats important for the project and chose based off of that. [sic]
Sounds reasonable. Are all of your "large software projects" simple arithmetic, then?
My software engineering program has been very Java intensive. My software engineering class, object oriented class, and software testing class were all java based. We dabbled in C# a bit as well. [...] I feel like this is all pretty well rounded; I've learned a bunch of languages and am not really specialized in one. I'd say I am best at Java right now, but I can also write C++ code just fine.
If you know Java, C#, some C++, and have done just enough Scheme to not get it, then no, you are not "pretty well rounded". Go back to Start, do not collect $200.
I don't think the universities are the problem, at least not in my experience.
Uh...
dude, i've coded in a lot of languages and ruby is the coolest so far, by far.
yeah i write rails apps but I also use ruby for admin type stuff and it's great.
the test suite stuff alone is a HUGE sell. i don't give a fuck how fast it is, the CPU bandwidth is hardly ever the bottleneck. I'm faster at coding and fixing, that's for sure.
It will be interesting to see when and how runtime code optimization affects the high vs. low-level language debate. Systems like HP's Dynamo http://www.hpl.hp.com/techreports/1999/HPL-1999-77 .html show there's gains to be had here, but afaik these techniques are not being used by major language runtimes.
Perl is not ugly, just really really idiomatic. As with all idiomatic languages, you can't grok what something means if you're not exposed to it. :)
It's just a matter of "if you can't stand the line noise, get out from the code-kitchen!".
Even if I can understand easily Perl code, what I can't really stand is C pointer arithmetic if it steps too far...
for some odd reason, I'm having a very hard time thinking up a non-C based language that's compiled to an actual binary and not interpretted or run by a virtualmachine...
Typically compiled languages include Ada, ALGOL, BASIC, COBOL, FORTRAN, ML, Pascal and others. I think those mostly qualify as being non-C based.
Laws do not persuade just because they threaten. --Seneca
In the early days of C on PC's, it wasn't the most efficient language in the world. Thankfully there were good profilers. And I quickly learned to utilize those. Analyze your program, and you find that 90% of the time was spent in one area. So I'd optimize that one section by recoding the CPU-intensive bits in assembly, and *wow*, the program would fly. Profile it again, and I'd find that most of the time was spent in a very mundane and efficient outer loop, and I'd know the program was near optimal.
Fast forward 10 or 20 years, and I'm coding in Java. I find one section takes 90% of the CPU time, I recode that as a native method and things fly.
Same with my new favorite language, Perl, although I find there are native methods for most libraries that would otherwise be inefficient.
It's a simple technique, that can make almost any language fly, tweaking around the odd spot where there's a bottleneck.
Love many, trust a few, do harm to none.
What sort of line of C code (not using some sort of insane preprocessor macro expansion) can map to hundreds of assembler instructions?
Laws do not persuade just because they threaten. --Seneca
Could someone please, please, PLEASE rewrite yum in C or at least point me to a python compiler.
There's a time and a place for interpreted languages, and package managers isn't one of them.
"Nine times out of ten, starting a fire is not the best way to solve the problem." - my wife
I do stuff in embedded space using IAR or GreenHills and gcc. For the most part, the proprietary vendors are losing ground to gcc. The proprietary advantage is shrinking, especially with more modern micros and as gcc improves. For the most part, code that comes out of gcc is no worse than code coming out of IAR or GreenHills. Where the priopritary guys have a real advantage is in better Clib implementations. The Clib, and newlib, that are normally used with gcc are huge and bloaty in comparison.
Engineering is the art of compromise.
Take a look at the first sentence:
The closer to the metal you can get while programming, the faster your program will compile -- or so conventional wisdom would have you believe
As others have already mentioned he seems to use the term 'compile' oddly. This sentence would say to me that the time to take program and turn it into object code (assembly, byte-code, etc) is smaller the more similar your language is to the object code. I think it's difficult to disagree with that statement. However since the author seems to spend most of his time talking about program execution speed (and by the look of the comments here on SD that's what everyone else thought too) it seems safe to assume that he meant 'The more similar your language is to object code the faster it will run'.
In this article, I will show you how high-level languages like Java aren't slow by nature, and in fact low level languages may compile less efficiently.
The wierd bit here is he seems to take the idea 'high-level languages are slower than low-level languages' and assume it's being stated in the ABSOLUTE case. In other words that there is no case where a high-level language can be faster than any low-level language. I doubt even the hardest of the hard-core assembly language folk would say that. Now like his mistake above we might be tempted to believe that he isn't saying something so ridiculous. The problem with that POV is that he only provides a few cases where he believes his thesis is true (at least one of which is wrong). The only argument a minority of cases can refute is the absolute one above. So either he doesn't make his case or his he's attacking an argument that could hardly be called common wisdom.
But hey you might just say that he's giving a few examples for the sake of brevity. Except that...
Now consider a slightly higher-level language, FORTRAN (which predates C by more than two decades, incidentally). FORTRAN has a vector datatype, and operations on it.
The problem here is if we take what appears to be his definition of a high-level language. FORTRAN could (AFAIK he's speaking hypothetically) produce faster object code than his C implementation because it implements a abstraction that is close to object code. IOW it is (in that instance) operating at a low level. How does this make his point?
A lot of people complain about the overhead of Java bytecode being interpreted. This argument isn't entirely fair, for two reasons. The first is that Java doesn't have to be interpreted at all
Again this is just odd reasoning. True it doesn't have to be but for the most part it is. So again it seems like he's trying to refute kind of an odd case.
The reason for this improvement is that a virtual machine could perform some categories of optimization that weren't available to a static compiler.
Anyone else amused that his first reason and second reason are mutually exclusive? ( IOW: You can't compile Java AND have JIT optimizations).
Now here at least is something that approaches a useful argument. Sure there are kinds of optimization that can only be done at run time but the question of what is generally faster isnt' really answered. For example an in-lined function can easily cause performace to drop if the inlining also causes a cache miss. I'm also somewhat skeptical of this auto-inlining being 'impossible' to implement in C. It would appear that some people have discussed it at least : http://citeseer.ifi.unizh.ch/chang92profileguided. html
His final idea about compilers becoming more advanced is true. However again we run into the issue of "What argument does this actually refute?". Is it the general case? It's hard to say, it's also hard to say how this aligns with his thesis. One example of a compiler that can produce pretty significant speed increases is Intel's C compiler. So it would seem that 'lower le
...COMmon Algorithmic Language, also had this pre-compile bytecode stage and was jaw-dropping, blazing fast.
I think what happened at some point was that the parent, Pascal, came back in the form of TurboPascal and Delphi and killed off its more advanced progeny before they could reach critical popularity.
I think the author uses a confusing definition of high-level vs. low-level language. I've always thought of it as a matter of structure: a low-level language's constructs map relatively directly to hardware or machine-language constructs, a high-level language's constructs don't. The level of abstraction of the constructs doesn't matter, only the mapping between them and the hardware. So while vector operations may be a more abstract (higher level) concept than C's primitive arrays and loops to operate on them, a language implementing vectors and vector operations directly in the syntax would be a lower-level language (as far as vectors go) than C on hardware with a vector unit because it's vector construct maps directly to a hardware operation. His discussion seems to be that C and it's relatives don't map closely to hardware operations anymore, so they may not perform as well as languages that do map more closely. Well, duh. We knew that from the Lisp Machine where LISP was a low-level language and C wasn't.
The point about optimizations is more productive. The whole "interpreted languages are slower than compiled languages" deal came from a time when it wasn't feasible to compile at run-time. Bytecode blows that whole theory out of the water, but until Java bytecode wasn't thought about much (UCSD Pascal and Icon and possibly Forth are the only bytecode-based languages I know of that pre-date Java). You still can't compile Java on-the-fly feasibly, but you can compile Java bytecode in close enough to real-time to not make a difference. C++ programmers have been doing that for ages with inlined member functions, but that comes with all manner of headaches when classes change and inlined code elsewhere doesn't. Bytecode doesn't suffer from that. That's something a lot of programmers steeped in the advantages and limitations of C and C++ don't think about.
What matters is the compiler or the interpreter.
// Do something
:= 1 to 100 do
// Do something
//Do Something
a 2,Prolog,Turbo Prolog, etc. etc your writing in will also be bad when the end result is executed.
In C...
for(i=1,i<=100;i++){
}
In Pascal...
for i
begin
end;
In Basic...
100 for i% = 1 to 100
110 Do Something
120 next i%
All of these are lexicaly different, yet all result in the same set of assembler instructions when the complier or interpreter is well designed and written. The issue is not <b>language</b> rather the issue is the supporting compiler and linker. I could easily write the following, call it a new language, say "Slash":
Perform
100 times
Lexicaly different from C, Pascal or Basic but it performs the function and with a compiler I wrote for "Slash" I would make sure it generated the appropriate assembler or machine code.
What all of this boils down to is what people find either interesting, challanging, or fun to frustrate others with. The <b><i>implementation</i></b> makes all the difference. If the implementation of your development environment is bad, then the C,C++,VB,Delphi,.Net,FORTRAN,COBOL,ADA,LISP,Modul
My personal preference is Delphi, I can X-Compile it without too many headaches to Linux. I can write in C,Assembler, Basic ( Basica,Vbasic,Qbasic,DBasic ) and am thinking of learning ADA just for the sake of learning it. When I do a programming task I pick the lanugage that makes sense for what I am doing, although I will admit I find java rather distastefull.
Hey KID! Yeah you, get the fuck off my lawn!
The fact that C does not have vector semantics reflects the domain C is used: most apps written in C do not need vector processing. In case such processing is needed, Fortran can easily interoperate with C: just write your time-critical vector processing modules in Fortran.
... but we still don't believe you just because you call the truth "a myth".
Who's to say they don't need vector processing? That's a decision for the compiler, not the programmer. It sounds to me like saying "most apps written in Python do not need a compare-less-than instruction". Do they? Do they not? Beats me.
On some CPUs (esp. with 387-derived FPUs), it's even faster to use the vector hardware if you're only doing a single operation. So it's hard to say that a given program wouldn't benefit from a vectorizing compiler. Pretty much every program iterates over a list of items at some point.
As for higher-level-than-C languages being faster than C, it is purely a myth.
Evidence, please?
Code that operates on hardware primitives (e.g. ints or doubles) has exactly the same speed in C, Java and other languages
Strictly speaking *all* code "operates on hardware primitives". I think what you mean is that if they all use the CPU's 32-bit signed integer ADD instruction, that instruction takes the same time from any language it was compiled from, which is true, but only matters if you're writing code for one of the few apps that does only number crunching.
All the checks VMs do have an additional overhead that C does not have; the little VM routines run here and there all add up to slower performance
Now you're just being silly. A VM has lots of opportunities for optimization that a C compiler doesn't have, and the "additional overhead" that scares you usually isn't that bad. HP's Dynamo project showed that running HP/UX binaries on an HP/UX emulator on HP/UX hardware was faster than running them natively, for most applications, which is good evidence that the "overhead" isn't so bad. See also the 90/10 rule -- ask a programmer, they'll know what it is.
the fact that some languages are overengineered or open the way for sloppy programming
Ah, see, here's the real problem: you're a C programmer, and you feel contempt for people who don't have to go through the pain that you do. You have my sympathy
not very long in to find this is the same "Java really is (well, can be) faster" article I've been reading the past 10 years.
lord
I don't like java. Don't try to make me. I'm sick of it. And I don't want to marry your sister, yes, she's very nice, I'm sure, and no way is she as stupid as I think she is, we just don't connect, you understand... I know she has a PhD, but I'm tired of you telling me I'm stupid not to be attracted to her.
Besides, you two are already married and that's not even legal in my state, let alone polygamy.
-pyrrho
Yeah, but what ROMs did you use to test your Game Boy or Game Gear emulator? Does easy hobbyist access to assembly language induce piracy?
And when that chip is deployed in millions of units of a handheld system, and your app targets that system, anyone can see the point of profiling your app and then putting the inner loops in the hands of an assembly expert. This is why the audio mixers in most Game Boy Advance games are written in ARM7 assembly language.
O RLY? The Perl 5 language has three main data types: scalar, array, and dictionary.
It was naughty dog. They built an alternative runtime engine that was about on the level of C++, but written in a lisp-ish dialect. The win for them was that they could upload code to the game on the fly, which was / is an advantage that most other game studios still can't match. Gamasutra.com has some articles on it somewhere. Clever stuff, that.
In Relating FFTW and Split-Radix Oleg describes how to generate an optimal FFT from Scheme in a single pass. The secret is not repeated optimization passes or in-depth CPU knowledge, but instead to know exactly which identities (i.e., axioms) contributed to the optimum solution. I believe that in the future it will not be rare to generate optimal solutions, thus making choice of programming language a matter of personal taste or developer speed.
Shae Erisson - ScannedInAvian.com
Yes, and it's a valid point. But we were discussing whether compilers are better at optimizing code than people or not. And, nowadays, they aren't.
The AACS key is NOT 0xF606EEFD628B1CA427BEA93A9CA9773F
One counterexample that keeps me busy:
:-}
In C++, one line of code such as 'a = smartPtr->b;'
can have a whole smart-pointer mess behind it.
That can be an endless pain to debug, when it goes wrong (think large destructor chains).
I would argue instead that Java and C#, with their garbage collection,
have a more trivial mapping of the same line: Just a plain assignment.
Just my five cents
http://code2code.net/ - Migrate your C++ to C#
>>In C++, one line of code such as 'a = smartPtr->b;'
.NET, etc. because "real computers" are somehow less than hypothetical ones, they become less qualified to judge. To address Djikstra, no astronomer would construct a hypothetical universe because finite light speed made observable universe less perfect.
>>can have a whole smart-pointer mess behind it.
>>That can be an endless pain to debug, when it goes wrong (think large destructor chains).
>>I would argue instead that Java and C#, with their garbage collection,
>>have a more trivial mapping of the same line: Just a plain assignment.
Any language can be made to have horrible constructs. One line of code is by no means any measure of how destructive something can be.
IMHO, Garbage collection is for bad programers. When I teach C/C++ my mantra is "If you didn't do it, it didn't happen." This applies to memory allocation as well as freeing. I can't tell you how many times I've hit GC problems, objects not freed fast enough, GC running at the *WORST* time for performance, etc.
High level languages have a place where the specifics of program operation and performance don't matter. The problem shows up when people don't know enough to know that their language of choice isn't appropriate for a specific task.
As more and more people leave the McCS courses that focus on hypothetical computing, Java,
In electronics, think of the OPAmp circuit. It is taught as a "perfect" linear amplifier for theory, then it is beaten into the students heads that it is imperfect and where and how and why it is imperfect.
In McCS school, real computers are seen as bad and hypothetical computers are seen as good. That isn't science, that's kinderarten.
The only thing that slows down languages like C is damn eye candy.
Java, on the other hand... at work, running a (dual core? dual processor?) pentium, connected to a fast RISC 6000 AIX box, a small Java app I wrote takes nearly half a minute to come up.
But then, halfway up the lerning curver for Java, I'm also working on an article entitled "The Failure of Java", and one insight I've had, just last week, while looking at some professional code that's production at a Fortune 50 company: Java, at least in a class, not only actively, but agressively encourages global variables. Staring at this, it struck me that I *have* worked in a language like that... except we call them subroutines... in COBOL.
mark "Java: COBOL in a sexy suit"
that C was a reaction to PL/1 - the "everything plus the kitchen sink" language. Just as Unix was a reaction to Multics. This isn't really a topic for argument, I'm sure it's written down somewere. On paper.
EWD: Computer science is no more about computers than astronomy is about telescopes
Sigh: "Computer science is no more about computers than astronomy is about telescopes"
You are, like what, the 100th person to use that quote?
I counter that an astonomer does not work on a hypothetical universe because the real observable universe is limited by an imperfect finite speed of light.
But, technically, that quote is a bad analogy. Astronomy is the study of the universe, not the study of telescopes. The corrected Djistra analogy should be computer science is more about keyboards than astronomy is about telescopes.
Sorry, Djikstra is wrong.
You can thank hardware/software vendors for perverting the word. They couldn't just say "old" or "obsolete" (regarding support or compatibility) so they twisted "legacy" their way.
:-)
It used to be a purely positive concept -- now the word kinda appears positive but is really used for a pejorative purpose. Marketing as usual... don't get suckered in in their shenanigans.
In other words: "You keep using that word. I don't think it means what you think it means."
"The closer to the metal you can get while programming, the faster your program will compile -- or so conventional wisdom would have you believe"
Well actually I can disaggree here - Because for C there is the issue of
#include
Includes need to be read and parsed over again and over again. Most other compiled high level languages use modules or packages where the specification is read and parsed once. (On top of that they can determine the compilations order and package dependencies theself - almost no need for make)
Ohh shure, some clever C compiler builder thought of copy cating that feature and called it "precompiled header file". Only they don't work because of:
#if defined(....)
#endif
I the programm becomes complex enough then other high level languages start to outperform C in terms of turn around (edit - compile - debug - edit) speed. Apart from beeing more high level and therefore beeing easier to understant by humans.
Martin
PS: all that is even more true for C++ and it magic STL.
If you would not have said it I would have done so.
Martin
PS: If you do get around trying to learn Ada here my shamless plug:
http://en.wikibooks.org/wiki/Ada_Programming
Do I have to say more?
Martin
No real difference in testing compiled vs interpreted code really - both have great tools, run time debugging, variable tracing, breakpoints, etc, etc, ad nauseum.
> I would be very surprised if there's anything LISP can do that can't be done just as fast (or faster) in C.
http://www.cons.org/cracauer/lisp.html
"The CMUCL system produces overhead-free code (that means, it is as fast or even faster than C) for a large number of computation constructs."
The article addressed this point by mentioning that the definitions of high and low level language are a moving target.
No, it's not. I was there for most of the evolution of C, since the K&R days. C has always been considered a "low level language". Nor are the problems with it news. Strange as it may be to believe, there were decent and efficient high level languages in the 70's and 80's.
C caught on because it shipped free with UNIX, because it was easy to write compilers for it, because Microsoft adopted it, and because a "full" compiler for it fit on the PDP-11 and happened to generate OK code for that machine.
If you're going to go with the jargon as it's most often used nowadays (which is a perfectly reasonable thing to do), then C would certainly be about as low as you can get without manipulating individual registers - i.e., without being assembly language.
If you bother to read the C language specs, you'll see that the C language guarantees very little of the things you may think of when you say that "C is low level". ANSI C implementations can legitimately prevent you from doing any kind of low-level pointer manipulation or bit access; they can garbage collect and ignore "free" if they like. And there have been implementations like that. What you think of as "low level" is a particularly common set of implementation choices, not a part of the C language.
Yeah, I had a feeling that if any OS were in C++, it would be something in the embedded space.
To a Lisp hacker, XML is S-expressions in drag.
As far as I am concerned, smart pointers have become a decisive breakthrough in software development. It basically removes the garbage collection advantage of VIMs. Intelligent application of smart pointers, including extensions of the basic std::auto_ptr to include smart arrays and reference counting gives C++ programmers all the benefits of garbage collection without dedicated processes wasting MIPS monitoring your code. All of this VM background bookkeeping is not free; and is above all not perfect. I have witnessed first hand cases of the Microsoft VM taking hours to cleanup wrapped resources for DLLs I've developed. Just because the language prevents you from worrying about freeing heap blocks and handles doesn't mean it gets done right. And worse, if there is a bug in the VM; one's only recourse is to guess at a possible work around and hope it triggers the GC to do its job. -James
Heres the resun I hayte edumacation... compare these too lines and tell me which makse YOUR (not "you're") head hurt really bad:
1) you ain't got no grammar
2) you don't have no grammar
good grief... now their all illiterate...
It would have been extremely silly to write the first LISP compiler in C when LISP interpreters were readily available at the time. The usual method of bootstrapping a language is to first write an interpreter for (a possibly simplified version of) the language, and then use that interpreter to develop/run the compiler until the compiler can compile itself.
There are other high-level languages besides the standard imperative ones, btw. Those languages typically have much stronger type systems (or computational models) that can be leveraged to provide higher-level optmization opportunities that are simply not possible in C for computability/decidability reasons. Granted, there aren't that many languages that actually do this today, but one example would be Occam where logically separate processes can be mapped to a single "hardware" process doing voluntary multitasking without violating process isolation and preemption at the logical level. This allows the system to replace expensive "hardware" context switches with two unprivileged instructions -- thus making running, say, 100000 threads on a single machine a pracical proposition.
HAND.
Clearly, you've never used an HP calculator.
Seriously, though, the reason Scheme is so awesome is precisely because it has no syntax and the most minimalist semantics you'll find anywhere. Things that are part of other languages are libraries in Scheme, such as the class system:
(module test mzscheme
(require
(lib "class.ss")
(lib "mred.ss" "mred"))
(define my-frame@
(new frame%
[label "My Frame"]))
(define my-button@
(new button%
[parent my-frame@]
[label "My Button"]))
(send my-frame@ show #t))
Type that code into DrScheme in module mode, and it'll show you a frame with a button. Nothing too amazing there. But see how it requires the library "class.ss"? What errors do you think you get if you remove it?
expand: unbound variable in module in: new
Yep; the new operator -- so essential to writing anything in Java -- is part of the library.
If there was more syntax built into Scheme, this kind of stuff wouldn't be possible. It's precisely because of this simplicity that Scheme is so awesome.
On a side note, if you really want to, you can define Scheme macros which will let you write normal arithmetic expressions. But most professional Scheme programs have very little in the way of long strings of arithmetic, and so it's pretty irrelevant.
That said, you might be interested in Scala. It has much (though certainly not all) of the power of Lisp/Scheme, but its syntax is more expansive. For example, any member function can be used infix, simply by dropping the dot. So 5 + 4 is equivalent to 5.+(4) (obviously, either one is optimized out to pure arithmetic by the compiler), and myList.filter(isOdd?) is equivalent to myList filter isOdd?. Very clean and straightforward, to a non-Lisper, most programs will look much simpler.