Android: How much overhead is generated by running an empty method?

I have created a class to handle my debug outputs so that I don't need to strip out all my log outputs before release.

public class Debug {
    public static void debug( String module, String message) {
        if( Release.DEBUG )
            Log.d(module, message);
    }
}

After reading another question, I have learned that the contents of the if statement are not compiled if the constant Release.DEBUG is false.

What I want to know is how much overhead is generated by running this empty method? (Once the if clause is removed there is no code left in the method) Is it going to have any impact on my application? Obviously performance is a big issue when writing for mobile handsets =P

Thanks

Gary

Answers


Measurements done on Nexus S with Android 2.3.2:

10^6 iterations of 1000 calls to an empty static void function: 21s  <==> 21ns/call
10^6 iterations of 1000 calls to an empty non-static void function: 65s  <==> 65ns/call

10^6 iterations of 500 calls to an empty static void function: 3.5s  <==> 7ns/call
10^6 iterations of 500 calls to an empty non-static void function: 28s  <==> 56ns/call

10^6 iterations of 100 calls to an empty static void function: 2.4s  <==> 24ns/call
10^6 iterations of 100 calls to an empty non-static void function: 2.9s  <==> 29ns/call

control:

10^6 iterations of an empty loop: 41ms <==> 41ns/iteration
10^7 iterations of an empty loop: 560ms <==> 56ns/iteration
10^9 iterations of an empty loop: 9300ms <==> 9.3ns/iteration

I've repeated the measurements several times. No significant deviations were found. You can see that the per-call cost can vary greatly depending on workload (possibly due to JIT compiling), but 3 conclusions can be drawn:

  1. dalvik/java sucks at optimizing dead code

  2. static function calls can be optimized much better than non-static (non-static functions are virtual and need to be looked up in a virtual table)

  3. the cost on nexus s is not greater than 70ns/call (thats ~70 cpu cycles) and is comparable with the cost of one empty for loop iteration (i.e. one increment and one condition check on a local variable)

Observe that in your case the string argument will always be evaluated. If you do string concatenation, this will involve creating intermediate strings. This will be very costly and involve a lot of gc. For example executing a function:

void empty(String string){
}

called with arguments such as

empty("Hello " + 42 + " this is a string " + count );

10^4 iterations of 100 such calls takes 10s. That is 10us/call, i.e. ~1000 times slower than just an empty call. It also produces huge amount of GC activity. The only way to avoid this is to manually inline the function, i.e. use the >>if<< statement instead of the debug function call. It's ugly but the only way to make it work.


Need Your Help

How do I prevent a slow $http initiated in one route from potentially resolving after the user has changed routes?

javascript angularjs angularjs-routing

Let's say my current route is /books and I make an $http call to get all of the books we want to show a user. Normally, the call would resolve quickly and the books would be ng-repeated into the DOM.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.