Search code examples
performancecompiler-constructionassemblytheory

Why are some programming languages faster than others?


I know that ASM is basically the fastest one can get, but is what makes HLLs slower than ASM the abstraction? What I mean by abstraction is that for instance in C++ you have a class, data needs to be stored about what is stored in the class, what it derives from, private/public accessors, and other things. When this code is compiled, is there actual assembly code that does work to figure out information about the class? Like CPython is built upon C so there is even more abstraction and instructions to be run at run-time than C. Is any of what I am saying true? I think I have answered my own question but I would like to get an answer from a more experienced individual other than myself.

EDIT: I understand that Python is interpreted but wouldn't it still be slower than C if it were compiled?


Solution

  • That's a broad question.

    Fundamentally, compiled languages get translated into machine instructions (op codes) just as ASM does (ASM is a layer of abstraction, too). A good compiler is actually likely to out-perform an average ASM coder's result because it can examine a large patch of code and apply optimization rules that most programmers could not do by hand (ordering instructions for optimal execution, etc).

    In that regard, all compiled languages are created "equal". However, some are more equal than others. How well the compiled code performs depends fundamentally on how good the compiler is, and much less on the specific language. Certain features such as virtual methods incur a performance penalty (last time I checked virtual methods were implemented using a table of function pointers, though my knowledge may be dated here).

    Interpreted languages fundamentally examine human-readable language as the program executes, essentially necessitating the equivalent of both the compile and execution stages during program runtime. Therefore they will almost always be somewhat slower than a compiled counterpart. Smart implementations will incrementally interpret parts of the code as executed (to avoid interpreting branches that are never hit), and cache the result so that a given portion of code is only interpreted once.

    There's a middle ground as well, in which human-readable language is translated into pseudo-code (sometimes called P-code or byte code). The purpose of this is to have a compact representation of the code that is fast to interpret, yet portable across many operating systems (you still need a program to interpret the P-code on each platform). Java falls into this category.