In the first article of this series, we looked at how important it is to choose the right programming language when beginning a new project. In part 2 of our programming languages series, we will look at different types of languages, how they work, and how each could affect your project.
The Inner Workings of a Computer
Computers can do billions of calculations per second, make complex decisions, crunch huge amounts of data, and control nearly all aspects of our lives. While all components of a computer are arguably equal in importance, the CPU is where most of the magic happens. But what is a CPU, and are they really that complex?
Modern CPUs have advanced instructions and features, but they still share similarities to CPUs made back in the day. For example, most CPUs can do basic arithmetic, perform comparisons, and do conditional branching. So why is any of this important, and how is it relevant to programming languages?
For a computer to do an action, it must be given a valid instruction that it can read and understand. Imagine you have a speech-recognition-enabled computer and you ask, “What will the weather be like today?” The computer will respond with the current weather, but how did it get this information and what instructions did it physically execute?
Chances are, the CPU has no idea what speech is, how to process it, or how to get weather information. Instead, the computer needs to perform millions of basic instructions that it does understand in order to produce the desired result. These basic instructions are what are known as the “Instruction Set” of the computer, and these instructions can interact to produce a result that the CPU otherwise cannot do in one go.
Below is a basic example written in Z80 CPU instructions that make the Z80 multiply two numbers. What you need to understand here is that the Z80 does not have an instruction to multiply two numbers. So in order to do this, you have to create a piece of code that will.
While modern CPUs can do complex instructions such as multiplication and division, they still cannot do operations like “open a file” or “go to Google”. These functions have to be converted into instructions that the computer can understand, and this can make or break a language, as we will see.
A compiled language is one in which the program is converted into machine code that the computer can directly read and execute. Three main compiled languages are Assembly, C, and C++.
Assembly language is arguably the simplest and most complex language there is, as assembly code only consists of instructions that the CPU can read.
C and C++, however, are referred to as high-level languages since they are written in a syntax that needs to be converted into machine code that the computer can understand. This conversion process is called “compiling” and it only needs to be done by the programmer once.
Compiled languages are usually the fastest languages (in processing time), because there are no intermediate steps being done — the CPU will literally just take bytes from the program and shove them straight into its instruction execution system. Compiled languages are also not compiled by the end user, so when a user runs the program, the CPU can immediately start executing instructions.
Because interpreted languages require an interpreter to run, they often come with massive speed penalties that make user programs slower than compiled programs. However, interpreted languages have the potential benefit of being cross-platform, as only the interpreter needs to be coded for different platforms. This means that user-written programs require little to no adjustment to allow them to run on different machines including Windows, Macs, and Linux.
Interpreted languages commonly use easy-to-understand syntax, which helps to reduce development time while also providing complex features like multi-processing, multi-threading, use of hardware ports, sockets, and much more.
Byte-code languages are those that rely on a virtual machine to execute the user’s program, but instead of the user program being compiled into native computer instructions, it is converted into bytes that the virtual machine understands.
Byte-code languages take the best of both worlds from compiled languages and interpreted languages by providing speed, thanks to the compilation into byte-code stage and cross-platform capabilities provided by the virtual machine (languages include Java, C#, and VB.net).
Usually written in a high-level syntax with plenty of functionality, including objects, classes, hardware access, and OS interactions, byte-code languages still suffer from performance issues since the host machine needs to run a virtual machine to execute the user program. This means that the computer will most likely be running the OS, the virtual machine, and then your program instead of just the OS and the user program.
When Does Programming Language Choice Matter the Most?
While it may not seem that important, a project’s success could be dependent on whether the code is compiled, interpreted, or byte-code compiled.
One project may rely on cross-platform capabilities, which is easier to achieve in a language such as Java or Python than C++, but another project may need to be as fast as it can be, in which case a compiled language such as C will be highly beneficial.
One classic example of a program that uses a language that is somewhat inappropriate is Minecraft, since it is coded in Java. While the use of Java allows the game to be played on many different platforms, the use of the Java Virtual Machine means that there are serious performance issues on slower, older computers (which I with suffered for years).
For Minecraft to run at a decent FPS (frames per second), you need a half-decent CPU. Otherwise, the Java Virtual Machine will struggle. Despite having a GTX 1050 and a 6 core AMD A10 processor, the game would still lag and have FPS drops.
The solution involved overclocking the processor to 3.79GHz and improving the PC cooling system, which strongly suggests that the CPU was the bottleneck (this comes as no surprise when the virtual machine is having to decode instructions before they can be executed).
So what language should YOU choose? While not entirely complete or representative of all languages, the flowchart below should give you a rough guide of what language you can expect to use.
The comments and opinions in this article are based on my personal experience, and, at the end of the day, the only person who can make the decision of which programming language to use is you. Remember to be careful and make sure that the language you choose is best for your project, or you could regret it!