Saturday, 19 May 2012

Is Recursion Good or Bad !!!

Why we use Recursion in methods?
  1. Code is easier to read
  2. Less lines of code
  3. Problem solving approach is somewhat divide and conquer: Solve bigger problem by solving simpler sub problems.
Classical Example: Factorial of a number
int factorial(int number)
{
    if (number==1) // simplest sub problem
      return 1;
    //building solution by solving sub problems
    return number*factorial(number-1);   
 }
Cons of Recursion
  • Lets say we have to calculate factorial of a very big number. Above method will be called recursively numerous times and each time before making recursive call we need to save next instruction address of calling method. StackOverFlow can easily occur.
What is Tail Call
A method call is said “Tail Call” if calling method directly returns the results of called method and do not performs any other operations on results returned by called method. Let us take example of Factorial(3). Above code will update call stack before calling factorial(2). It processes factorial(2) and gets the next instruction to execute from call stack. Then executes 3*factorial(2). Clearly above piece of code is not having tail call.

Why prefer Tail call style of code:
Tail call code can help compiler take decision of avoiding new stack frames each time method is called. Calling stack frame no longer performs any operations on return value of recursive call. No need of separate stack frame. Calling stack frame can be reused. This will be more memory efficient. This optimization called as tail call optimization becomes significant in case of Recursive methods having having lot of internal method calls.

Factorial Code in Tail Call style
int factorial(int number, int accumulator)
{
  if (number==1)   // simplest sub problem
    return accumulator;
  else
  {
     // tail call code –ready for optimization
     return factorial(number-1, accumulator * number);   
   }
 }
Tail call Support in Programming Languages
Compilers can optimize or transform code written in tail call manner into more memory efficient iterative code. For example:

Code input to Compiler
int factorial(int number)
{
  function foo(data) {
    a(data);
    return b(data);
}
Assembly Language Code generated by compiler
 foo:
  call B
  call A
 ret
Tail call optimization
 foo:
  call B
  jmp  A 
replaces last two lines with a single jump instruction:
Infact in functional languages like scala, tail call elimination is often guaranteed by the language standard.

Factorial Code Snippet in Scala:
import scala.annotation.tailrec
class Factorial2 {
  def factorial(n: Int): Int = {
    @tailrec def factorialAcc(acc: Int, n: Int): Int = {
      if (n <= 1) acc
      else factorialAcc(n * acc, n - 1)
    }
    factorialAcc(1, n)
  }
} 

@tailrec annotation helps the developer writing code in tail style in unit testing. If during compilation any code having @tailrec annotation is not tail optimized by compiler, error will be reorted to developer by compiler.

Arguments for Java not supporting Tail Call Optimization
  1. The ability to debug using a stacktrace will get affected if this optimization is performed.
  2. Unlike functional languages, Java supports iteration based constructs like loops.
  3. Java is going to support "GoTo" construct in Java 8 !!!!
References:
  1. https://blogs.oracle.com/darcy/entry/upcoming_jep
  2. http://en.wikipedia.org/wiki/Tail_call

Monday, 14 May 2012

Alternatives are for good !!!


I recently appeared for an interview where i was asked to write an algorithm for a problem. Later on during the interview i was asked to optimize the solution and provide alternate solution.
I found this practice of finding multiple/alternate solutions to a given problem worth learning. Thinking n approaching a problem from different directions gives a better grip over it.

Task: Given a pattern: "A1B3C7DE....", you need to print A '1' times followed by B '3' times and so on....

Diff ApproachesWe will start by fetching character by character to be printed some x/y/z number of times. Each character fetched will be printed before fetching next  character. We can optimize "printing a character some x number of times".
  • Crude way: loop to print character x number of times
private static void crudePrinting(char ch,int times)
{ 
    System.out.println();
    for(int i = 0; i< times; i++){
        System.out.print(ch);  
}
  • StringBuilder waykeep appending character in stringbuffer and print stringbuffer. Faster way of printing characters. Though Extra memory occupied by StringBuilder object but it is reused to print different characters like A,B... Time efficiency is a larger gain than small memory overhead loss.
private static void stringBuilderPrinting(char ch,int times,StringBuilder str)
{ 
     for(int i = 0; i< times; i++){
   str.append(ch);
     }   
     System.out.println(str);  
}
  • String Format waysingle line of code. Internally it uses StringBuilder to process format chunks. Memory and time wise better than crude way but not StringBuilder way.
private static void stringFormatPrinting(char ch,int times){
     String repString = String.format(String.format("%%0%dd", times), 0).replace('0',ch);
     System.out.println(repString);
}

Bench marking of alternatives




String.Format also uses String Buffer internally. Best among the three approaches is using StringBuilder. Though small memory overhead may occur but  gain over "Time to print the given pattern" seems more significant to me.

Say Hi to Bridge Pattern !!!

Few days back, I appeared for an interview and got the chance to present my Object Oriented design skills. I was given the task to design Switch and Light for a room. I had a pen and white board with me and from there my struggle started .....

Anybody who has heard of Bridge pattern will say it is meant to "decouple an abstraction from its implementation so that the two can vary independently" (http://en.wikipedia.org/wiki/Bridge_pattern)
However, this statement even after reading multiple times do not fit into my mind. I will try to explain this pattern in somewhat different way. In a typical software application, you may have multiple layers/hierarchy of code which will mix with other. Let us try to feel this using below examples: 
  1. One layer could be Switch layer: OnOff Switch, DimmerSwitch(can be used for dim the light apart from on/off). Another Layer could be Equipment: Light, Fan, TV. These two layers can be mixed: OnOff Switch for TV,Light and Fan, DimmerSwitch for Bulb. Whenever, you encounter this kind of mixing think of Bridge pattern as a Horse coming for rescue. Bridge patterns helps us in avoiding class explosion (if we use possible combinations among layers) and one layer mixing/using another layer instance resolved dynamically at runtime.
  2. One layer could be Shapes to draw: Circle,Rectangle. Second layer could be drawing implementation: Vector based, Bitmap based. Instead of having VectorCircle, VectorRectange, BitmapCircle, BitmapRectangle (class explosion  + maintenance nightmare when changed) we can use bridge to help us out .
Lets look at the design of Bridge Pattern:

Class Diagram:

Sequence Diagram:

Mixing of Switch with Bulb and light shown in above scenario. I hope "mixing of layers" makes more sense than "decouple an abstraction from its implementation so that the two can vary independently" !!!!

Another example:



Do Share your feedback and comments.