Languages like PHP and Perl, on the other hand, are interpreted. The same program source
code can be run on any CPU as long as the machine has the correct interpreter (that is, the
program called php or perl ). The interpreter translates each line of the program into binary
code as that line is executed.
There are advantages and disadvantages to each of these systems. Programs written in inter-
preted languages are portable: you can take the same code, drop it on any machine with the
appropriate interpreter, and it will run. However, it might run slowly. As a simple case, con-
sider what happens in a loop: the interpreter will retranslate each line of code when it is ex-
ecuted in the loop. The compiled code doesn't need to repeatedly make that translation.
There are a number of factors that a good compiler takes into account when it produces a
binary. One simple example of this is the order of the binary statements: not all assembly lan-
guage instructions take the same amount of time to execute. A statement that adds the values
stored in two registers might execute in one cycle, but retrieving (from main memory) the
values needed for the addition may take multiple cycles.
Hence, a good compiler will produce a binary that executes the statement to load the data,
executes some other instructions, and then—when the data is available—executes the addi-
tion. An interpreter that is looking at only one line of code at a time doesn't have enough in-
formation to produce that kind of code; it will request the data from memory, wait for it to
become available, and then execute the addition. Bad compilers will do the same thing, by
the way, and it is not necessarily the case that even the best compiler can prevent the occa-
sional wait for an instruction to complete.
For these (and other) reasons, interpreted code will almost always be measurably slower than
compiled code: compilers have enough information about the program to provide a number
of optimizations to the binary code that an interpreter simply cannot perform.
Interpreted code does have the advantage of portability. A binary compiled for a SPARC
CPU obviously cannot run on an Intel CPU. But a binary that uses the latest AVX instruc-
tions of Intel's Sandy Bridge processors cannot run on older Intel processors either. Hence, it
is common for commercial software to be compiled to a fairly old version of a processor and
not take advantage of the newest instructions available to it. There are various tricks around
this, including shipping a binary with multiple shared libraries where the shared libraries ex-
ecute performance-sensitive code and come with versions for various flavors of a CPU.
Java attempts to find a middle ground here. Java applications are compiled—but instead of
being compiled into a specific binary for a specific CPU, they are compiled into an idealized
assembly language. This assembly language (know as Java bytecodes) is then run by the
java binary (in the same way that an interpreted PHP script is run by the php binary). This