FizzBuzz: Multiple ways to implement and their performance

FizzBuzz is a very common programming problem that is implemented to improve the understanding of conditional statements and loops in any programming language. Before we start off with the implementations, let’s define the problem.

Problem:

Write a program that prints the numbers from 1 to 100(or a positive integer provided by the user). But for multiples of three, print “Fizz” instead of the number and for the multiples of five, print “Buzz”. For numbers which are multiples of both three and five, print “FizzBuzz”.

The output should be:

1, 2, “Fizz”, 4, “Buzz”, “Fizz”, 7, 8, “Fizz”, “Buzz”, 11, “Fizz”, 13, 14, “FizzBuzz”, 16, 17………………

Implementations

Before we get into the detailed analysis, let’s look at the 3 base implementations that we will be first analyzing.

For all implementations:
* The output is displayed in console.log()
* For loop is used for iteration from 0 to 100

Implementation 1: Using if-else statements

for(var i = 1;i<=100; i++){
if (i%15==0){
console.log(“FizzBuzz”)
} else if (i%3==0){
console.log(“Fizz”)
} else if (i%5==0){
console.log(“Buzz”)
} else {
console.log(i)
}
};

This is a simple if-else loop which is checking the required cases and providing the output accordingly. The code is very much readable and less confusing compared to the next implementations.

Implementation 2: Using Ternary Operations

for(var i = 1; i<=100; i++){
console.log(i%5==0? i%3==0? “FizzBuzz”:”Buzz”:i%3==0?”Fizz”:i)
};

This is a nested ternary operation. First, the division by 5 is validated. Then division by 3 validated and accordingly the result is selected. Below tree shows how the comparisons are being done.

Implementation 3: Using Ternary & OR Operation

for(var i = 1; i<100; i++){
console.log((i%3==0? ”Fizz”:””)+(i%5==0? ”Buzz”:””) || i);
};

This is a clever usage of Ternary operations and logical OR operation to implement FizzBuzz. Here “FizzBuzz” is created as a string concatenation of “Fizz”(When the number is divisible by 3) and “Buzz”(When the number is divisible by 5). When both of these are empty, then OR logical function selects “i”.

Performance of all 3 implementations:

To measure the performance, I used jsperf.com. You can find the actual test here — https://jsperf.com/fizzbuzz-implementation-comparision.

And here is the result,

The chart shows the number of operations that are performed per second with specific logic. (I have made sure to run the test at least twice in each of the browsers specified)

The Insights from this are,

  1. The performance of the logic is dependent on the browser(Actually, the JS engine)
  2. OR-Ternary is the fastest logic in Google Chrome(Both desktop and mobile)
  3. Ternary is the fastest logic in Firefox (Again, both desktop and mobile)

Now, can we improve the performance of our current OR-Ternary implementation(Fastest on Chrome)?

I tried to check a few more variations of OR-Ternary implementation to see if the performance improves. The variations that I tried are,

Original(Normal equal comparison):

for(var i = 1; i<100; i++){
console.log((i%3==0? ”Fizz”:””)+(i%5==0? ”Buzz”:””) || i);
};

Strict equal comparison(===):

for(var i = 1; i<100; i++){
console.log((i%3===0? ”Fizz”:””)+(i%5===0? ”Buzz”:””) || i);
};

Truthy/Falsy comparison(no = ):

for(var i = 1; i<100; i++){
console.log((i%3? ””:”Fizz”)+(i%5===0? ””:”Buzz”) || i);
};

And the results were,

Test link — here

Again, the insights are,

  1. Ternary-Strict equal is the fastest implementation in Chrome. But only with a negligible improvement
  2. Ternary-Truty was the slowest in Chrome but was the fastest in Firefox.

Bottom line:

The variations in the performance were not very high between the implementations that were compared. Browser(JS engine) specific performance improvements were good for specific implements.

Like,

  • OR-Ternary showing 50% and 300% improvements compared to If-else and Ternary respectively
  • Truthy comparison was more than 3 times slow compared to the normal equal and strict equal comparison