FizzBuzz Optimisation | Modulus vs Decrement Operator Performance

This is not the typical debate in FizzBuzz code about how to handle repeated if statements. I believe that it is a matter of personal preference.

I am here to ask about the choice of repeated mathematical operation.

Usually the solution to a FizzBuzz code is to use the modulus operator on every iteration. However, I'm concerned with its performance impact.

From my knowledge, modulus operator is tightly connected with division operator, and has a considerable performance overhead compared to simple increment and decrement operator.

In addition, I don't believe compiler has the ability to analyse and optimise the use of modulus operator in a loop.

Hence, I give the alternative solution that uses only simple decrement operator. The following code is written in C++.

I seek insight on whether my approach will provide performance benefit, or if it is actually a horrible idea that worsen performance.

And if there are other ways I can optimize a FizzBuzz code even further. (I think in a modified FizzBuzz puzzle with lots of cases to compare against, a lookup table might be preferable)

Typical FizzBuzz solution.

for (unsigned int i = 1; i <= 1000000; ++i) {
if (!(i % 15))
std::cout << "FizzBuzz\n";
else if (!(i % 3))
std::cout << "Fizz\n";
else if (!(i % 5))
std::cout << "Buzz\n";
else
std::cout << i << '\n';
}


My optimized code.

static const unsigned int fa {3};
static const unsigned int fb {5};

unsigned int a {fa};
unsigned int b {fb};

for (unsigned int i = 1; i <= 1000000; ++i) {
--a, --b;
if (!a && !b) {
a = fa;
b = fb;
std::cout << "FizzBuzz\n";
} else if (!a) {
a = fa;
std::cout << "Fizz\n";
} else if (!b) {
b = fb;
std::cout << "Buzz\n";
} else {
std::cout << i << '\n';
}
}

• "I seek insight on whether my approach will provide performance benefit, or if it is actually a horrible idea that worsen performance." You have two horses. Race them. Do you know what a profiler is?
– Mast
Jan 16, 2021 at 11:35
• @Mast No. What's a profiler? Jan 16, 2021 at 11:37
• Analysis of a program to find time/space complexity, frequency and duration of function calls and execution time. Wiki
– Mast
Jan 16, 2021 at 11:40
• Fully agree with Mast, instead of speculating which is faster, test it! Write both pieces of code run then and measure the time it takes. Optimizing for performance without measuring is like painting your house blind. Jan 16, 2021 at 13:16

Looks good - you're using only simple integer addition and subtraction.

Except for the division hidden here:

    std::cout << i << '\n';


Note that division by a constant isn't necessarily as expensive as you think: it's always possible for an optimising compiler to implement it in terms of multiplication and bitwise operations. And a test for being an exact multiple is often simpler (think of the well-known algorithms for testing divisibility by 9 or 11 in decimal).

If you really want to drive up performance, consider storing the integer value as a string (any kind), and implement the ++ operation character by character.

You may also be interested in High throughput Fizz Buzz over on the Programming Puzzles site.

• Thanks, the linked thread is crazy, and full of resources to read over. Jan 16, 2021 at 11:01
• Can you please elaborate on how printing 'i' contain a hidden division? or link me to a resource to read in? Thanks in advance. Jan 17, 2021 at 4:25
• @a.Li - I'll turn that around into a challenge for you - convert an integer to a decimal string without library functions. Now do it without any / or %. It's not impossible, but not obvious either. Jan 17, 2021 at 9:15