Tuesday, October 20, 2015

Easy to maintain logic(?) vs speed

Read this blog post about the FizzBuzz problem:

Write a program which return "fizz" if number is multiplier of 3, return "buzz" if its multiplier of 5 and return "fizzbuzz" if number is divisible by both 3 and 5. If number is not divisible by either 3 or 5 then it should just return the number itself

Here are some implementations and test codes:

I personally prefer the implementation of doFizzBuzz1: the logic captures the sense of "if the number is dividable by x, append y to the result".  It makes future modification of adding similar logic easier without understanding the existing code. (e.g. say adding "print 'buzzbazz' if the number is divisible by 10 and 'fizzbuzzbazz' if divisible by 30" etc).

But of course, it is going to be slower as it involves creation of additional objects.  But by how much?  Here are some test results of running the three implementations against the whole range of integer:

Time taken to run net.clarenceho.test.TestFizzBuzz$$Lambda$1/1212899836@75a1cd57 is 175.717783485s
Time taken to run net.clarenceho.test.TestFizzBuzz$$Lambda$2/1285044316@3d012ddd is 141.0544738s
Time taken to run net.clarenceho.test.TestFizzBuzz$$Lambda$3/1607460018@6f2b958e is 140.644691232s

So it is about 25% slower.  Is it worth it? Probably not in this trivial case.  But worth to consider if the logic is complicated and expected to change / enhance in the future.

doFizzBuzz3 is cleaner without nested conditions and runs slightly faster possibly due to fewer branching.

JUnit code used to test the implementations.  Also a good exercise to practice Java lambda and parallel streams.  Tests done on AMD X4 925.

No comments: