Take the 2-minute tour ×

I am fairly new to programming, I have studied in computer science for 3 years at college, but as you know, school is only 2% of what really makes one a fully-fledged programmer.

I have a lot of trouble understanding why people say language x is more efficient that language y. I only understand when it comes to pre-compiled vs runtime compiled. I understand defining data types like a constant in code is bound to be faster than letting the computer/language figure it out(like php or ruby), but when it comes to using C or Java what is it that makes C faster? Aren't they both going to be compiled into machine language in the most efficient way possible?

To me, it seems as if the only difference between using a language like C or Java is; a higher level language like java would be easier to organise and write/maintain large applications with classes and inheritance. But I feel as if it should really make no difference when once it is compiled. Can someone explain?

btw i only know higher level languages like php, java, ruby, vb, c#. Maybe that's why it is hard for me to imagine? the next language i want to explore is most probably C

share|improve this question

migrated from stackoverflow.com Apr 13 '11 at 20:24

This question came from our site for professional and enthusiast programmers.

Java is not compiled to machine code, it's byte-compiled for the JVM. JVM optimizations can include JIT compilation, but that involves compilation at runtime. –  nmichaels Apr 13 '11 at 20:22
@nmichaels: Java is compiled to machine code. Machine code for the Java Virtual Machine. It however is not compiled to native machine code. –  nightcracker Apr 13 '11 at 20:24
@nightcracker, and what then is native machine code? There are machines that are able to execute Java bytecode.. –  halfdan Apr 13 '11 at 20:26
@halfdan: Then in that case the meaning of native equals java. @Ave: C is directly compiled to native machine code (we usually say machine code and not machine language) –  nightcracker Apr 13 '11 at 20:29
I beg to differ, languages DO have speed. The ability of the compiler to perform optimisations is directly related to the language specification. Some languages (like Python) will never be fast because everything is correct. Optimisations depend on semantic constraints either expressed in a standard (undefined behaviour) or by suitable constrained syntax. For example, invariant code motion is easy to do in a functional language because the value of an expression cannot be dependent on where it is evaluated: all that matters is that the variables it refers to are in scope. –  Yttrill Dec 13 '11 at 0:42
show 4 more comments

6 Answers

While performance is really a result of implementation rather than languages, there are, in practice, faster and slower languages.

C is usually the fastest in comparisons. C compilers are relatively mature, and C programs require minimal run-time support. A C program will normally be compiled to something that can be loaded and executed, with just a little preparation on the part of the computer. (There have been C interpreters, and they were slow like you'd expect.)

Fortran is not usually in those computations, but is similar in most respects. Fortran was inherently faster in large-scale floating-point computations than the C of the original Standard, since the Fortran compiler could assume, say, that the three matrices passed to a multiplication program were disjoint, and could optimize on that basis. C compilers couldn't assume that.

Java programs are normally compiled to an artificial machine language, and that is normally compiled on the fly (just-in-time compiling). That could theoretically be faster than C-style compilation (it could make better guesses about the flow of execution, and it could tailor the compilation to the exact system in use), but in practice isn't. Java also requires more run-time support, such as a garbage collector, and the JIT compiler and runtime have to load and get going. That results in increased startup time, which can be noticeable.

Python programs are normally compiled to an artificial machine language and then interpreted, which is slower. It is possible to store the compiled files (".pyc"), but frequently only the source is stored, so to execute it is necessary to compile first and then interpret, which is slow. Also, Python has dynamic typing, which means the compiler doesn't know everything's type up front, and therefore Python functions have to be able to take different data types at runtime, which is inefficient.

There's always room for surprises. On one celebrated occasion, a CMU Common Lisp program out-number-crunched a Fortran program. Common Lisp requires garbage collection, which apparently wasn't an issue in that application, and normally is dynamically typed, but it's possible to declare all types statically. The Fortran compiler had a small inefficiency the CMU Common Lisp compiler didn't, and was duly improved afterwards.

share|improve this answer
with regard to Python and dynamic typing, I think the V8 JavaScript Engine is kinda interesting there, and could greatly improve the runtime of dynamically typed languages (it basically creates virtual tables on the fly). –  Matthieu M. Apr 18 '11 at 19:03
"Pre/micro-optimization is the root of all evil." –  Qix Feb 6 '13 at 23:08
add comment

Before you can determine that language X is more efficient than language Y, you need to know in which manner "X is more efficient than Y".

Some languages are more efficient in run-time execution speed, some languages are more efficient in memory footprint, some are more efficient in lines of typed text. Odds are there are efficiencies that you are concerned about and efficiencies that you could care less about. Target the languages which have efficiencies you care about.

Remember that a language is like a tool, your focus shouldn't be on how efficient the tool is, it should be on selecting the right tool for the job. A nail gun is much more efficient than a hand held hammer for building a house's framing. A nail gun is much less efficient than a hand held hammer for hanging a single picture frame. Select the right tool for the job.

share|improve this answer
On the other hand, hanging picture frames with a nail gun is badass. Similarly, coding up your own web framework in C is glamorous and stupid. –  nmichaels Apr 13 '11 at 20:45
add comment

First of all, no. It doesn't matter. You're not writing code for a heavily constrained environment so you should write in a high level language and optimize (including writing the odd C module) as indicated by your profiler.

Secondly, since Java is not really a compiled language in the normal sense of the word, it makes a poor comparison to C. A more appropriate comparison would be between with another compiled language, like C++, Ada, D, Go, or even OCaml.

Your conclusion about higher-level compiled languages being capable of being as fast as lower-level compiled languages is both right and wrong. At the limit, code can be optimized to do stuff as fast as possible. However, the sufficiently intelligent compiler is a myth. The fewer layers of abstraction between human-readable code and machine code, the more direct the translation. That means compilers don't have to be as smart, which means they can be better.

That's not to say that a program written in C is automatically faster than one written in a much higher level language. The advantage you get from using high-level language features is that other (usually smarter) people have already thought about how to optimize what you're doing. So, for example, calling Python's built-in sort function on a Python list will get you better performance than if you had implemented bubble sort in C.

share|improve this answer
Java is compiled. Both in the sense that most of its implementations require a seperate compilation step before execution and that it ends up as machine code in virtually all implementations. Yes, it's not compiled to native machine code ahead of time. But that's not the definition of compiled. –  delnan Apr 13 '11 at 20:49
@Delnan: Bah. Python's compiled too, and once unladen swallow takes off it will have a JIT compiler. Does that mean it will be a compiled language "in the normal sense of the word"? –  nmichaels Apr 13 '11 at 20:59
I can't change that many people add a "... to native machine code" whenever they hear or read or say "compiled". To these people, everything that isn't compiled statically before it starts running will remain "interpreted". But for the "correct" definition of compiled and for practical purposes such as potential performance, having JIT compilation means you qualify as a compiled language. –  delnan Apr 13 '11 at 21:04
@mmichael: Bah, unladen swallow will be laden for a long time to come. PyPy in the other hand... –  Christopher Mahan Apr 13 '11 at 21:07
add comment

A concrete example: Let's take the following code fragment:


This is a call to the Run method. In machine code, this might look like:

$a0 = x                       // Use $a0/$a1 for argument passing
$r1 = [address of Run method]
call $r1

The [address of Run method] is the tricky part. In a statically typed OO language like Java or C++, we'd look it up in the virtual method table (VMT), which is an array of method addresses. At compile time, we may know that Run is the 2nd entry in the VMT, so we can load it from offset 4 (on a 32-bit machine):

$a0 = load x
$r2 = load $a0+0   // The VMT is the first address in the object
$r1 = load $r2+4   // Load the 2nd address from the VMT
call $r1

In a language like Python, an object's method table is some kind of string-to-address lookup data structure, possibly a hashtable, requiring a call to a lookup function first. The machine code might look something like:

$a0 = x
$a0 = load $a0     // Load the address of the method hashtable
$a1 = "Run"
$v0 = call lookup  // Expensive operation
$a0 = x
call $v0

So even though you're doing "the same thing" in both languages, the static typing in C++ and Java lets the compiler produce smaller, faster machine code.

NOTE: There are ways to speed things up. For example, you can do whole-program analysis of Python code to try and determine the address of the Run method at compile time, which would get rid of the hashtable lookup in some cases. But the point of my example was to demonstrate where the performance difference can come from even though you're "compiling to machine code" in both cases.

share|improve this answer
add comment

Like stated in comments, languages like Java and C# get converted into byte code and that byte code is then executed by the VM. Languages like ASM, C, C++ are compiled into machine code. The extra step of a language like Java or C# having to executed the code inside a VM does add some overhead however in a lot of cases the overhead in negligible (there are certain tasks though that generally run faster in languages like ASM).

One thing the VM have that negate the overhead of running the VM is that the VM can optimized the code for the system it is running on automatically. With languages that compile code into machine code like C++, when you compile it, you generally try to target the compilation options for the most general settings so that the program performance is very similar on a large amount of systems. C# and Java can take advantage of specific features of the system it is running on so that the program performs the best based on the system it is running on (with C++, you would have to compile the code for each system to take advantage of those features).

share|improve this answer
add comment

A lot of time is spent by CPU designers, hardware system architects and compiler writers on beating some competitor's benchmark. Historically, some of the most publicized benchmarks have been in Fortran and C. So that's the type of code that has gotten optimized system wide.

Furthermore, the layers of abstraction often used to provide high level language features often have impacts at the hardware level, not only in the number of machine instructions, but in cache hit ratios, and branch prediction penalties. These also can also potentially reduce performance, and are sometimes very difficult to optimize away without losing the safety of the HLL feature.

Highly object oriented languages often encapsulate things so well that it is hard for a compiler to optimized globally, which removes another performance tool.

That said, there can be a massive variation in the performance optimizations applied to any one language, from slow interpreters, to faster VMs, hot spot JITs, global JITs, trace-driven compilers, and other exotic compiling/parallelizing tricks. Plus, there's Moore's law: e.g. I have slow interpreted Basic programs that now run faster than equivalent hand-coded C and assembly language did a couple decades ago. So a lot of developers just use the language they are most familiar with, think they can best solve problems with, and wait for the hardware to catch up. However this thinking does have other impacts, including adding to the energy and pollution costs of global computing. Some people think the latter does matter.

share|improve this answer
Some compilers have had special code that recognized common benchmarks and came out with hand-optimized assembly language code. Or so the rumor goes. –  David Thornley Apr 13 '11 at 21:17
add comment

Your Answer

