Donald Knuth [F]orget about small efficiencies, say about 97% of the time.
-
Upload
susanna-franklin -
Category
Documents
-
view
223 -
download
3
Transcript of Donald Knuth [F]orget about small efficiencies, say about 97% of the time.
Donald Knuth
[F]orget about small efficiencies, say about
97% of the time
CSC 313 – Advanced Programming Topics
Recursion is useful, powerful technique Often yields compact, easy-to-read code Highlights all possible cases making
testing simple Some algorithms naturally recursive
Divide-and-conquer algorithms Nearly anything that uses a tree LISP & other functional language
programs Recursion can reduce development
time
Why Recurse?
Why Not Use Recursion?
Method Call Overhead
Every method call has some overhead Load address of method to be called Allocate stack memory for method Push parameters onto a stack Push return value from stack Reload return address from the stack Deallocate stack memory
Pain of Recursion
Compiler optimizes much of method call Most become only 1 instruction Leaves allocating stack space as main
cost Program starts by allocating huge
stack Then optimizes assuming stack is
immobile But lots of concurrent method calls will
fill this Rarely code many concurrent calls…
except when using recursion
QuickSort Results
Convert algorithm to use tail-recursion Make recursive call as last step of
recursion Should directly return result of recursive
call
public int factorial(int i) { if (i <= 1) { return 1; } else { int result = factorial(i – 1); return result * i; }}
public int factorial(int i) { if (i <= 1) { return 1; } else { return i * factorial(i – 1); }}
What Can We Do?
public int factorial(int i, int fact) { if (i <= 1) { return fact; } else { return factorial(i – 1, fact * i); }}
Tail Recursion
Conversion of tail-recursion to iteration easy Create local variable to track most
recent result Recreate recursion using for or while
loop Get benefits of simplicity without the
costs
public int factorial(int i, int fact) { if (i <= 1) { return fact; } else { return factorial(i – 1, fact * i); }}
public int factorial(int i) { int fact; if (i <= 1) { // Stop recursion } else { fact *= i; // Continue recursion }}
public int factorial(int i) { int fact = 1; while (i > 1) { fact *= i; i--; } return fact;}
Tail Recursion Elimination Great technique for REMOVING
RECURSION End method with recursive call Directly return recursive result
NOT ALL ALGORITHMS CAN BE CONVERTED Recursion sometimes required
Remove Recursion By Cheating Slow performance due to stack
overhead While cannot always remove recursion Can remove overhead’s source
Instantiate Stack at beginning of method Program Stack replaced with local Stack
Method iterates while Stack is not empty Start loop by popping value to be
processed
public void printInOrder(BNode<T> root) {Stack stack = // Instantiate stackstack.push(root);while (!stack.isEmpty()) { Object node = stack.pop(); if (node instanceof BNode) { if (node.hasRight()) { push(node.rightChild()); } push(node.element()); if (node.hasLeft()) { push(node.leftChild()); } } else { System.out.println(node); }}
}
public void printInOrder(BNode<T> root) {if (root.hasLeft()) { printInOrder(root.leftChild());}System.out.println(root.element());if (root.hasRight()) { printInOrder(root.rightChild());}
}
public void printInOrder(BNode<T> root) {Stack stack = // Instantiate stackstack.push(root);while (!stack.isEmpty()) { Object node = stack.pop(); if (node.hasRight()) { push(node.rightChild()); } push(node.element()); if (node.hasLeft()) { push(node.leftChild()); }}
}
Remove Recursion By Cheating
Cheater Removing Recursion Use local Stack to replace program Stack Stack handles multiple data types Pop value off Stack with each iteration Loop’s actions depend on value’s type
Compiler can now optimize this method Stack methods highly optimized Growing & shrinking this Stack much
easier Single call means better chance of
optimizing
For Next Lecture
Lab #3 due before lab time tomorrow Asks you to implement OBSERVER
PATTERN Lab #4 available on web/Angel
tomorrow Will be a different kind of lab
Read pages 109 – 122 of the book How DO we instantiate objects? How SHOULD we instantiate objects? Pizza… haven’t we ALREADY USED it in a
pattern?