我已经创建了一个类来处理我的调试输出,这样我就不需要在发布之前删除所有日志输出。
public class Debug {
public static void debug( String module, String message) {
if( Release.DEBUG )
Log.d(module, message);
}
}
看了另一个问题后,我了解到如果常量 Release.DEBUG 为 false,则 if 语句的内容不会被编译。
我想知道运行这个空方法会产生多少开销? (一旦删除了 if 子句,方法中就没有代码了)它会对我的应用程序产生任何影响吗?显然,在为手机编写时,性能是一个大问题 =P
谢谢
加里
最佳答案
在装有 Android 2.3.2 的 Nexus S 上完成的测量:
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
控制:
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
我已经多次重复测量。没有发现明显的偏差。 您可以看到每次调用的成本会因工作负载而有很大差异(可能是由于 JIT 编译), 但可以得出 3 个结论:
dalvik/java 在优化死代码方面很糟糕
静态函数调用可以比非静态函数调用优化得更好 (非静态函数是虚的,需要在虚表中查找)
nexus s 的成本不超过 70ns/调用(即约 70 个 cpu 周期) 并且与一次空 for 循环迭代的成本相当(即一次增量和一次局部变量条件检查)
请注意,在您的情况下,将始终评估字符串参数。如果您进行字符串连接,这将涉及创建中间字符串。这将非常昂贵并且涉及大量的 gc。例如执行一个函数:
void empty(String string){
}
调用参数如
empty("Hello " + 42 + " this is a string " + count );
100 次此类调用的 10^4 次迭代需要 10 秒。那是 10us/调用,即比空调用慢 1000 倍。它还会产生大量的 GC Activity 。避免这种情况的唯一方法是手动内联函数,即使用 >>if<< 语句而不是调试函数调用。这很丑陋,但却是让它发挥作用的唯一方法。
关于java - Android:运行一个空方法会产生多少开销?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4345845/