Understanding the limitations of the hardware you’re working with and the sizes of the data types involved can be critical to writing well-performing code. Using a floating-point number on a desktop computer is usually fine, the performance difference versus integer isn’t usually worth discussing for a single-threaded desktop application. However, the Arduino has no FPU (floating-point unit), so while integer operations may only take a clock cycle or two, a single floating point multiply operation can take well over 500 clock cycles on the Arduino, and some sources indicate well over 1000 clock cycles. This is because the floating point math is being emulated in software. Therefore, floating point math is hundreds of times slower than integer math on the Arduino.
At 16MHz, 16 million clock cycles per second, it’s still fast enough to do some useful work with floating point, but floating point can become a limiting factor pretty quickly. For a different example of the hardware having limitations that developers need to consider when developing software, it is becoming increasingly popular these day to write programs that run on the big discrete GPUs in desktop computers – they have thousands of processor cores and really fast memory, which is perfect for doing large simulations of the real world. Even a small discrete GPU can easily be an order of magnitude more powerful than the main processor. However, conditional branching and most pointer math is remarkably slow on GPUs which can easily destroy that performance advantage, if the developer doesn’t take care to minimize the usage of those items. AMD’s current FX processor architecture has two integer cores per floating point unit, so an “8 core” processor can only do 4 floating point threads in parallel. Therefore, if you were developing software to run on that processor, using integer values in parallel threads could be about twice as fast as using floating point values in parallel threads.
These are just some fairly obvious performance considerations. There are far more subtle ones that can make a huge difference. This question on StackOverflow is a great example – I recommend reading the question and then scrolling down and reading the answer.
(Branching is the act of jumping the program execution in a non-linear manner. Instead of executing one instruction after the other, the processor reaches a branch and moves to a different part of the program, such as when a function call happens, or when an if
statement may lead to two or more different lines of code, based on a condition. A conditional branch is one that doesn’t always happen, such as with an if statement. A function call will always branch, which is called an unconditional branch.)