Tail recursion optimization and recursion in Java - java

I have a question about tail calls optimization, I need to know how this java code behaves:
private void doSomething(int v) {
inf f = someCalculation(v);
if (f < 0) doSomething(v/2);
else doSomething(v*2);
}
This code is a nonsense example but my question is, in such a case:
The first doSomething() call would be optimized?
The second doSomething() call would be optimized?
The if/else block affects in any way the optimization?
Thanks
EDIT:
Please provide an example on how you would do this if the language was not Java but something else that has TCO

Java 8 has no Tail Call Optimization whatsoever. No calls will be optimized (turned into iteration/goto statements).
The discussion over TCO for Java has a long history, though, with Guy Steele being one of its best-known proponents.
I recommend reading this post from the mlvm-dev mailing list for a recent review of the subject.

Try running the following code:
public static void main(String[] args) {
for (int i = 1; i > 0; i *= 2) { doSomething(i); }
}
private static void doSomething(int start) {
doSomething(start, start);
}
private static void doSomething(int i, int start) {
if (i == 0) { System.out.println("done from " + start); }
else { doSomething(i - 1, start); }
}
If the JVM can run it without stack overflow, then it should mean it can do tail recursion optimization (or a very good constant propagation).

Related

Multiplication in Java using recursion

I am new to programming and I am writing a simple code in Java that is using recursion. I want to show the product of two numbers (from start to End). The return of the method is the multiplication of the numbers from start to end. (For Example: If the numbers are 1 and 3 then I want the method to return 6.
I managed to do the recursion but I am not sure if the code is effective at all. Here is my code so far. Thanks
public class ÜbungsblattSieben {
public static void main(String[] args) {
System.out.println(multiplyFromStartToEnd(1, 3));
}
public static int multiplyFromStartToEnd(int start, int end) {
if (start == end) {
return end;
} else {
return start * multiplyFromStartToEnd(++start, end);
}
}
}
Your code is as effective as a recursive multiplication can be. Well done.
That said, here are a few notes:
You may write start + 1 instead of ++start. Generally easier to read and understand. Also you do not have to change the start variable itself, you just want to pass a bigger number to the method call, thats all.
You may also want to properly indent your code (just hit the auto-format key in your IDE).
I would also suggest to rename your method to multiplyFromTo, but thats a very subjective note.
All in all, your code would then look like:
public class ÜbungsblattSieben {
public static void main (String[] args) {
System.out.println(multiplyFromStartToEnd(1, 3));
}
public static int multiplyFromTo(int start, int end) {
if (start == end) {
return end;
} else {
return start * multiplyFromStartToEnd(start + 1, end);
}
}
}
For reference, here is how an iterative version could look like:
int result = 1;
for (int i = start; i <= end; i++) {
result *= i;
}
System.out.println(result);
Obviously, this is a lot faster than recursion.

using recursion to add to a variable

below the code is using a private method to add to the variable count. Below that variable are conditionals which by my understanding, will not run until the recursion stack traces upword. Am I correct? My test is failing, and I am trying to see if it is because my code is wrong or I'm using recursion wrong.
public boolean containsRightRedEdge() {
int count = 0;
count += containsRightRedEdge(root);
if(count > 0) return true;
return false;
}
private int containsRightRedEdge(Node n) {
if (n == null) return 0;
if (isRed(n.right)) {
return 1;
}
return containsRightRedEdge(n.left) + 0 + containsRightRedEdge(n.right);
}
I would say you are using recursion pretty much correctly, but your choice of method names could be less confusing, and your logic could be simplified.
I am not too familiar with the algorithm you're trying to implement, but you might try something like this:
public boolean containsRightRedEdge(Node root) {
return getNumRightRedEdges(root) > 0;
}
private int getNumRightRedEdges(Node n) {
if (n == null) return 0;
if (isRedEdge(n)) return 1;
return getNumRightRedEdges(n.left) + getNumRightRedEdges(n.right);
}
Generally a recursive method shouldn't have the same name as a non-recursive method. These method names communicate more clearly what each one does. Also your base cases might be wrong as you've got them written currently based on how I'm interpreting the algo should work. Of course, I don't know the code inside isRed() so I'm probably making wrong assumptions here.
The code above in my question, is the correct way to use recursion in this instance. I just had a typo which is now resolved. Leaving the question for other peoples reference.

java optimization nitpick: is it faster to cast something and let it throw exception than calling instanceof to check before cast?

Before anyone says anything I'm asking this out of curiosity only; I'm not planning to do any premature optimization based off of this answer.
My question is about speed in using reflection and casting. The standard saying is 'reflection is slow'. My question is what part exactly is slow, and why; particularly in comparing if something is a parent of another instance.
I'm pretty confident that just comparing the class of an object to another Class object is about as fast as any comparison, presumably just doing direct comparison of singleton objects that are already stored int he Object's state; but what if one class is a parent of the other?
I usually think of instanceof as being about as fast as regular class checking, but today I thought about it and it seems that some reflection has to happen 'under the scenes' for instanceof to work. I checked online and found a few places where someone said instanceof is slow; presumably due to reflection required to compare the parent of an object?
This lead to the next question, what about just casting. If I cast something as an object it's not I get a ClassCastException. But this doesn't happen if a cast an object to a parent of itself. Essentially I'm doing an instanceof call, or logic to that effect, when I do the cast at run time am I not? I've never heard anyone hint that casting an object could be slow before. Admittedly not all casts are to a parent of the provided object, but plenty of casts are to parent classes. Yet never has anyone hinted at all that this could be slow.
So which is it. Is instanceof really not that slow? Are both instanceof and casting to parent class kind of slow? or is there some reason a cast can be done faster then an instanceof call?
As always try it and see in your particular situations, but:
-Exceptions are expensive, remarkably so.
-Using exceptions for code flow is almost always a bad idea
Edit:
Ok I was interested so I wrote a quick test system
public class Test{
public Test(){
B b=new B();
C c=new C();
for(int i=0;i<10000;i++){
testUsingInstanceOf(b);
testUsingInstanceOf(c);
testUsingException(b);
testUsingException(c);
}
}
public static void main(String[] args){
Test test=new Test();
}
public static boolean testUsingInstanceOf(A possiblyB){
if (possiblyB instanceof B){
return true;
}else{
return false;
}
}
public static boolean testUsingException(A possiblyB){
try{
B b=(B)possiblyB;
return true;
}catch(Exception e){
return false;
}
}
private class A{
}
private class B extends A{
}
private class C extends A{
}
}
Profile results:
by InstanceOf: 4.43 ms
by Exception: 79.4 ms
as I say, remarkably expensive
And even when its always going to be a B (simulating when you're 99% sure its B you just need to be sure its still no faster:
Profile results when always B:
by InstanceOf: 4.48 ms
by Exception: 4.51 ms
There is a general answer and a particular answer.
General case
if (/* guard against exception */) {
/* do something that would throw an exception */
} else {
/* recover */
}
// versus
try {
/* do something that would throw an exception */
} catch (TheException ex) {
/* recover */
}
It is a fact that creating/throwing/catching an exception is expensive. And they are likely to be significantly more expensive than doing the test. However, that doesn't mean that the "test first" version is always faster. This is because in the "test first" version, the tests may actually be performed: first time in the if, and second time in the code that would throw the exception.
When you take that into account, it is clear that if the cost of the (extra) test is large enough and the relative frequency of exceptions is small enough, "test first" will actually be slower. For example, in:
if (file.exists() && file.isReadable()) {
is = new FileInputStream(file);
} else {
System.err.println("missing file");
}
versus
try {
is = new FileInputStream(file);
} catch (IOException ex) {
System.err.println("missing file");
}
the "test first" approach performs 2 extra system calls, and system calls are expensive. If the "missing file" scenario is also unusual ....
The second confounding factor is that the most recent HotSpot JIT compilers do some significant optimization of exceptions. In particular, if the JIT compiler can figure out that the state of the exception object is not used, it may turn the exception create/throw/catch into a simple jump instruction.
The specific case of instanceof
In this case we are most likely comparing these two:
if (o instanceof Foo) {
Foo f = (Foo) o;
/* ... */
}
// versus
try {
Foo f = (Foo) o;
} catch (ClassCastException ex) {
/* */
}
Here a second optimization occurs. An instanceof followed by a type cast is a common pattern. A HotSpot JIT compiler can often eliminate the dynamic type check that is performed by the type cast ... since this is repeating a test that just succeeded. When you factor this in, it the "test first" version cannot be slower than the "exception" version ... even if the latter is optimized to a jump.
Unfortunately, Richard's code can't be run directly to produce timings. I've modified the question slightly, assuming that you really want "if A is a B, do something on B", rather than just asking the question "is A a B?". Here is the test code.
UPDATED FROM ORIGINAL
It was rather challenging to write trivial code that the HotSpot compiler didn't reduce to nothing, but I think the following is good:
package net.redpoint.utils;
public class Scratch {
public long counter = 0;
public class A {
public void inc() { counter++; }
}
public class B extends A {
public void inc() { counter++; }
}
public class C extends A {
public void inc() { counter++; }
}
public A[] a = new A[3];
public void test() {
a[0] = new A();
a[1] = new B();
a[2] = new C();
int iter = 100000000;
long start = System.nanoTime();
for(int i = iter; i > 0; i--) {
testUsingInstanceOf(a[i%3]);
}
long end = System.nanoTime();
System.out.println("instanceof: " + iter / ((end - start) / 1000000000.0) + " per second");
start = System.nanoTime();
for(int i = iter; i > 0; i--) {
testUsingException(a[i%3]);
}
end = System.nanoTime();
System.out.println("try{}: " + iter / ((end - start) / 1000000000.0) + " per second");
start = System.nanoTime();
for(int i = iter; i > 0; i--) {
testUsingClassName(a[i%3]);
}
end = System.nanoTime();
System.out.println("classname: " + iter / ((end - start) / 1000000000.0) + " per second");
}
public static void main(String[] args) {
Scratch s = new Scratch();
s.test();
}
public void testUsingInstanceOf(A possiblyB){
if (possiblyB instanceof B){
((B)possiblyB).inc();
}
}
public void testUsingException(A possiblyB){
try{
((B)possiblyB).inc();
} catch(Exception e){
}
}
public void testUsingClassName(A possiblyB){
if (possiblyB.getClass().getName().equals("net.redpoint.utils.Scratch$B")){
((B)possiblyB).inc();
}
}
}
The resulting output:
instanceof: 4.573174070960945E8 per second
try{}: 3.926650051387284E8 per second
classname: 7.689439655530204E7 per second
Test was performed using Oracle JRE7 SE on Windows 8 x64, with Intel i7 sandy bridge CPU.
If the cast can throw an exception, it means that it's doing implicitly what instanceof would do. So, in both cases you are implicitly using reflection, probably in exactly the same way.
The difference is that if the result of instanceof comes back false, no more reflection is happening. If a cast fails and an exception is thrown, you'll have unrolling of the execution stack and, quite possibly, more reflection (for the runtime to determine the correct catch block, based on whether the thrown exception object is an instance of the type to be caught).
The above logic tells me that an instanceof check should be faster. Of course, benchmarking for your particular case would give you the definitive answer.
I don't think you would find one being clearly better than the other.
For instanceof, the work done use memory and cpu time. Creating a exception use memory and cpu time also. Which use less of each, only a well done benchmark would give you that answer.
Coding-wise, I would prefer to see a instanceof rather than casting and having to manage exceptions.

what's the reason for stackoverflow exception in this?

import java.math.BigInteger;
import java.util.HashMap;
/**
*
* #author cypronmaya
*/
public class test {
static HashMap<Integer, BigInteger> cache = new HashMap<Integer, BigInteger>();
public static void main(String[] args) {
System.out.println(factorial(20000));
}
public static BigInteger factorial(int n) {
BigInteger ret;
if (n == 0) {
return BigInteger.ONE;
}
if (null != (ret = cache.get(n))) {
return ret;
}
ret = BigInteger.valueOf(n).multiply(factorial(n - 1));
cache.put(n, ret);
return ret;
}
}
Exception in thread "main" java.lang.StackOverflowError at
java.util.HashMap.get(Unknown Source)
Hi,
Why am i getting stackoverflow exception to this program?
i know that stackoverflow usually means you have an infinite loop,
but this works fine when i'm using 10000 or some other numbers lesser, wht becomes suddenly infinite with big numbers?
A StackOverflowError occurs when the call stack overflows. This happens when you have too many nested calls (because each call requires space to be reserved on the stack, and it's a finite size). I guess in your case, 20000 is too many.
You can modify the stack size of the JVM with the -Xss flag. But I'd suggest that you find a different way to compute a factorial.
The recursive function each time that is called create a new pointer in the stack, so with an high number of calls of a recursive function you can get a StackOverflow Exception ...
Tip : replace the recursive function with a loop to resolve.
The reason is that your factorial function is recursive and this is NOT tail recursion.
It means that every time you call the "factorial" function this call is put to the stack.
I have no idea if Java compiler can generate tail recursion calls at all, but if it can, you can simply refactor your function to a tail-call way. Otherwise just avoid recursion (a good practice in imperative languages anyway).
Non-recursive versions (not so much as compiled - this is Stack Overflow). There will be clearer ways to write this.
public class Test {
private static final Object lock = new Object();
private static final List<BigInteger> cache = new ArrayList<>(
Arrays.asList(BigInteger.ONE)
);
public static void main(String[] args) {
System.out.println(factorial(20000));
}
public static BigInteger factorial(int n) {
if (n < 0) {
throw new IllegalArgumentException();
}
synchronized (lock) {
int r = cache.size();
if (n < r) {
return cache.get(n);
}
BigInteger current = cache.get(r-1);
for (;;) {
current = BigInteger.valueOf(r).multiply(current);
cache.add(current);
if (n == r) {
return current;
}
++r;
}
}
}
}
You can resize the Java default stack size runtime with the -Xss switch
eg: java -Xss2048k YourClass

Refactor this recursive method?

I'm pretty new to the idea of recursion and this is actually my first attempt at writing a recursive method.
I tried to implement a recursive function Max that passes an array, along with a variable that holds the array's size in order to print the largest element.
It works, but it just doesn't feel right!
I have also noticed that I seem to use the static modifier much more than my classmates in general...
Can anybody please provide any general tips as well as feedback as to how I can improve my code?
public class RecursiveTry{
static int[] n = new int[] {1,2,4,3,3,32,100};
static int current = 0;
static int maxValue = 0;
static int SIZE = n.length;
public static void main(String[] args){
System.out.println(Max(n, SIZE));
}
public static int Max(int[] n, int SIZE) {
if(current <= SIZE - 1){
if (maxValue <= n[current]) {
maxValue = n[current];
current++;
Max(n, SIZE);
}
else {
current++;
Max(n, SIZE);
}
}
return maxValue;
}
}
Your use of static variables for holding state outside the function will be a source of difficulty.
An example of a recursive implementation of a max() function in pseudocode might be:
function Max(data, size) {
assert(size > 0)
if (size == 1) {
return data[0]
}
maxtail = Max(data[1..size], size-1)
if (data[0] > maxtail) {
return data[0]
} else {
return maxtail
}
}
The key here is the recursive call to Max(), where you pass everything except the first element, and one less than the size. The general idea is this function says "the maximum value in this data is either the first element, or the maximum of the values in the rest of the array, whichever is larger".
This implementation requires no static data outside the function definition.
One of the hallmarks of recursive implementations is a so-called "termination condition" which prevents the recursion from going on forever (or, until you get a stack overflow). In the above case, the test for size == 1 is the termination condition.
Making your function dependent on static variables is not a good idea. Here is possible implementation of recursive Max function:
int Max(int[] array, int currentPos, int maxValue) {
// Ouch!
if (currentPos < 0) {
raise some error
}
// We reached the end of the array, return latest maxValue
if (currentPos >= array.length) {
return maxValue;
}
// Is current value greater then latest maxValue ?
int currentValue = array[currentPos];
if (currentValue > maxValue) {
// currentValue is a new maxValue
return Max(array, currentPos + 1, currentValue);
} else {
// maxValue is still a max value
return Max(array, currentPos + 1, maxValue);
}
}
...
int[] array = new int[] {...};
int currentPos = 0;
int maxValue = array[currentPos] or minimum int value;
maxValue = Max(array, currentPos, maxValue);
A "max" function is the wrong type of thing to write a recursive function for -- and the fact you're using static values for "current" and "maxValue" makes your function not really a recursive function.
Why not do something a little more amenable to a recursive algorithm, like factorial?
"not-homework"?
Anyway. First things first. The
static int[] n = new int[] {1,2,4,3,3,32,100};
static int SIZE = n.length;
have nothing to do with the parameters of Max() with which they share their names. Move these over to main and lose the "static" specifiers. They are used only once, when calling the first instance of Max() from inside main(). Their scope shouldn't extend beyond main().
There is no reason for all invocations of Max() to share a single "current" index. "current" should be local to Max(). But then how would successive recurrences of Max() know what value of "current" to use? (Hint: Max() is already passing other Max()'s lower down the line some data. Add "current" to this data.)
The same thing goes for maxValue, though the situation here is a bit more complex. Not only do you need to pass a current "maxValue" down the line, but when the recursion finishes, you have to pass it back up all the way to the first Max() function, which will return it to main(). You may need to look at some other examples of recursion and spend some time with this one.
Finally, Max() itself is static. Once you've eliminated the need to refer to external data (the static variables) however; it doesn't really matter. It just means that you can call Max() without having to instantiate an object.
As others have observed, there is no need for recursion to implement a Max function, but it can be instructive to use a familiar algorithm to experiment with a new concept. So, here is the simplified code, with an explanation below:
public class RecursiveTry
{
public static void main(String[] args)
{
System.out.println(Max(new int[] {1,2,4,3,3,32,100}, 0, 0));
}
public static int Max(int[] n, int current, int maxValue)
{
if(current < n.Length)
{
if (maxValue <= n[current] || current == 0))
{
return Max(n, current+1, n[current]);
}
return Max(n, current+1, maxValue);
}
return maxValue;
}
}
all of the static state is gone as unnecessary; instead everything is passed on the stack. the internal logic of the Max function is streamlined, and we recurse in two different ways just for fun
Here's a Java version for you.
public class Recursion {
public static void main(String[] args) {
int[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
System.out.println("Max: " + max(0, data));
}
public static int max(int i, int[] arr) {
if(i == arr.length-1) {
return arr[i];
}
int memo = max(i+1, arr);
if(arr[i] > memo) {
return arr[i];
}
return memo;
}
}
The recurrence relation is that the maximum element of an array is either the first element, or the maximum of the rest of the array. The stop condition is reached when you reach the end of the array. Note the use of memoization to reduce the recursive calls (roughly) in half.
You are essentially writing an iterative version but using tail recursion for the looping. Also, by making so many variables static, you are essentially using global variables instead of objects. Here is an attempt at something closer to a typical recursive implementation. Of course, in real life if you were using a language like Java that doesn't optimize tail calls, you would implement a "Max" function using a loop.
public class RecursiveTry{
static int[] n;
public static void main(String[] args){
RecursiveTry t = new RecursiveTry(new int[] {1,2,4,3,3,32,100});
System.out.println(t.Max());
}
RecursiveTry(int[] arg) {
n = arg;
}
public int Max() {
return MaxHelper(0);
}
private int MaxHelper(int index) {
if(index == n.length-1) {
return n[index];
} else {
int maxrest = MaxHelper(index+1);
int current = n[index];
if(current > maxrest)
return current;
else
return maxrest;
}
}
}
In Scheme this can be written very concisely:
(define (max l)
(if (= (length l) 1)
(first l)
(local ([define maxRest (max (rest l))])
(if (> (first l) maxRest)
(first l)
maxRest))))
Granted, this uses linked lists and not arrays, which is why I didn't pass it a size element, but I feel this distills the problem to its essence. This is the pseudocode definition:
define max of a list as:
if the list has one element, return that element
otherwise, the max of the list will be the max between the first element and the max of the rest of the list
A nicer way of getting the max value of an array recursively would be to implement quicksort (which is a nice, recursive sorting algorithm), and then just return the first value.
Here is some Java code for quicksort.
Smallest codesize I could get:
public class RecursiveTry {
public static void main(String[] args) {
int[] x = new int[] {1,2,4,3,3,32,100};
System.out.println(Max(x, 0));
}
public static int Max(int[] arr, int currPos) {
if (arr.length == 0) return -1;
if (currPos == arr.length) return arr[0];
int len = Max (arr, currPos + 1);
if (len < arr[currPos]) return arr[currPos];
return len;
}
}
A few things:
1/ If the array is zero-size, it returns a max of -1 (you could have another marker value, say, -MAX_INT, or throw an exception). I've made the assumption for code clarity here to assume all values are zero or more. Otherwise I would have peppered the code with all sorts of unnecessary stuff (in regards to answering the question).
2/ Most recursions are 'cleaner' in my opinion if the terminating case is no-data rather than last-data, hence I return a value guaranteed to be less than or equal to the max when we've finished the array. Others may differ in their opinion but it wouldn't be the first or last time that they've been wrong :-).
3/ The recursive call just gets the max of the rest of the list and compares it to the current element, returning the maximum of the two.
4/ The 'ideal' solution would have been to pass a modified array on each recursive call so that you're only comparing the first element with the rest of the list, removing the need for currPos. But that would have been inefficient and would have bought down the wrath of SO.
5/ This may not necessarily be the best solution. It may be that by gray matter has been compromised from too much use of LISP with its CAR, CDR and those interminable parentheses.
First, let's take care of the static scope issue ... Your class is defining an object, but never actually instantiating one. Since main is statically scoped, the first thing to do is get an object, then execute it's methods like this:
public class RecursiveTry{
private int[] n = {1,2,4,3,3,32,100};
public static void main(String[] args){
RecursiveTry maxObject = new RecursiveTry();
System.out.println(maxObject.Max(maxObject.n, 0));
}
public int Max(int[] n, int start) {
if(start == n.length - 1) {
return n[start];
} else {
int maxRest = Max(n, start + 1);
if(n[start] > maxRest) {
return n[start];
}
return maxRest;
}
}
}
So now we have a RecursiveTry object named maxObject that does not require the static scope. I'm not sure that finding a maximum is effective using recursion as the number of iterations in the traditional looping method is roughly equivalent, but the amount of stack used is larger using recursion. But for this example, I'd pare it down a lot.
One of the advantages of recursion is that your state doesn't generally need to be persisted during the repeated tests like it does in iteration. Here, I've conceded to the use of a variable to hold the starting point, because it's less CPU intensive that passing a new int[] that contains all the items except for the first one.

Categories

Resources