当前位置: 首页 > 面试题库 >

为什么Android下的注释会导致性能问题(缓慢)?

步炯
2023-03-14
问题内容

我是ORMLite的主要作者,它使用类上的Java注释来构建数据库模式。我们的程序包最大的启动性能问题是在Android
1.6下调用注释方法。直到3.0我都看到了相同的行为。

我们看到以下简单的注释代码 难以置信地
占用大量GC,这是一个实际的性能问题。在快速的Android设备上,对注释方法的1000次调用几乎耗时一秒。Macbook
Pro上运行的相同代码可以同时进行2800万次(原文如此)调用。我们有一个包含25种方法的注释,并且我们希望每秒进行50种以上的注释。

有谁知道为什么会这样,是否有任何解决方法?在缓存此信息方面,ORMLite当然可以做一些事情,但是我们可以做些什么来在Android下“修复”注释吗?谢谢。

public void testAndroidAnnotations() throws Exception {
    Field field = Foo.class.getDeclaredField("field");
    MyAnnotation myAnnotation = field.getAnnotation(MyAnnotation.class);
    long before = System.currentTimeMillis();
    for (int i = 0; i < 1000; i++)
        myAnnotation.foo();
    Log.i("test", "in " + (System.currentTimeMillis() - before) + "ms");
}
@Target(FIELD) @Retention(RUNTIME)
private static @interface MyAnnotation {
    String foo();
}
private static class Foo {
    @MyAnnotation(foo = "bar")
    String field;
}

这将导致以下日志输出:

I/TestRunner(  895): started: testAndroidAnnotations
D/dalvikvm(  895): GC freed 6567 objects / 476320 bytes in 85ms
D/dalvikvm(  895): GC freed 8951 objects / 599944 bytes in 71ms
D/dalvikvm(  895): GC freed 7721 objects / 524576 bytes in 68ms
D/dalvikvm(  895): GC freed 7709 objects / 523448 bytes in 73ms
I/test    (  895): in 854ms

编辑:

@candrews指出正确的方向后,我在代码中做了一些戳记。性能问题似乎是由中的一些糟糕的总代码引起的Method.equals()。它同时调用这toString()两种方法,然后进行比较。每次toString()使用StringBuilder一堆追加方法时都没有很好的初始化大小。在做.equals比较的字段将显著加快。

编辑:

我得到了一个有趣的反射性能改进。现在,我们使用反射在AnnotationFactory类内部进行窥视,以直接读取字段列表。这使反射类对我们来说快了20_倍_ ,因为它绕过了使用该method.equals()调用的调用。这不是通用解决方案,但这是ORMLite
SVN存储库中的Java代码


问题答案:

Google已确认该问题并将其修复为“蜂窝后”

https://code.google.com/p/android/issues/detail?id=7811

因此,至少他们对此有所了解,并且可能已经针对某些将来的版本进行了修复。



 类似资料:
  • 问题内容: 好吧,我试图理解并阅读可能导致它的原因,但我却无法理解: 我的代码中有这个地方: 事实是,当它尝试调用某些方法时,它将引发而不是其他预期的异常(特别是)抛出 。我实际上知道调用了什么方法,所以我直接转到该方法代码,并为应该抛出的行添加了一个块 ,它实际上按预期抛出。然而,当它上升时,以某种方式更改了上面的代码并没有 按预期进行。 是什么原因导致这种行为的?我该如何检查? 问题答案: 通

  • 我有以下图像标记使用和属性来插入响应图像: 据我所知,我只是告诉浏览器我所有可用的图像大小,它应该只下载基于视口大小的最合理的大小,等等。如果我将浏览器窗口(Chrome)调整为较小并刷新页面,则网络选项卡告诉我,它将下载我期望的图像(在本例中为800px),加上最大的图像(我从属性中假设)。 我在使用picturefill.js和不使用picturefill.js的情况下都试过,我在OS X 1

  • 我试图处理这个错误(我在Android Studio更新东西之前从来没有过这个错误): 现在必须显式声明注释处理器。发现编译类路径上的以下依赖项包含注释处理器。请将它们添加到annotationProcessor配置中。-auto-value-1.4.jar(com.google.auto.value:auto-value:1.4)或者,设置android.defaultconfig.javaCo

  • 需求:实现将数组中所有元素调整为左右两部分,左边为奇数,右边为偶数。(c语言) 中这段代码: 能不能换成一下这个? 想问问为什么可换/为什么不能换? 谢谢指导,菜鸟万分感激。

  • 我正在尝试使用spring Boot运行一个web应用程序。 将密码映射为硬编码值。 我的问题是:当应用程序运行并且在主类上使用注释时,只要它命中URL就会发生以下异常: javax.servlet.ServletException:在org.springframework.web.servlet.dispatcherservlet.render(dispatcherservlet.java:13

  • 为什么我在下面的代码段中的X轴上有一个溢出? 在我的网格容器上应用时,就会产生溢出。 null null https://codepen.io/anon/pen/wdjexz?editors=1100