java - Android:运行一个空方法会产生多少开销?

标签 java android performance overhead

我已经创建了一个类来处理我的调试输出,这样我就不需要在发布之前删除所有日志输出。

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 个结论:

  1. dalvik/java 在优化死代码方面很糟糕

  2. 静态函数调用可以比非静态函数调用优化得更好 (非静态函数是虚的,需要在虚表中查找)

  3. 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/

相关文章:

android - 服务不停

jQuery 选择器 - 按速度顺序

python - 在不使用 for 循环的情况下创建数据框的子集

javascript - 获取大数字(例如 1900234)并在每三位数字后添加逗号的最快方法是什么?

java - 使用 Comparator 降序排序(用户定义的类)

android - Firebase 实时数据库连接被终止 : Different Region

android - 在 Android 中找不到使用 DigestUtils 的方法

java - 如何在Java中解析和修改HTML文件

java - 需要强制转换的 getContentPane()

java - 如何将 List<String> 从 spring JPA 存储到数据库中的 text[] 数组