Tho*_*mas 67 java optimization android dalvik
我正在开发一个高性能的Android应用程序(游戏),尽管我首先尝试编写可读性代码,但我想在脑海中留下一个关于幕后发生的事情的图片.使用C++,我已经对编译器将为我做什么和不做什么做了很好的直觉.我正在尝试为Java/Android做同样的事情.
因此这个问题.我在网上找不到这个话题.Java编译器,Dalvik转换器(dx)和/或JITter(在Android 2.2+上)是否会执行如下优化?
方法内联.在什么条件下?private方法总是可以安全地内联; 这样做会吗?public final方法怎么样?关于其他类对象的方法?static方法?如果编译器可以轻松推导出对象的运行时类型,该怎么办?我要声明的方法final或static在可能的情况?
常见的子表达式消除.例如,如果我访问someObject.someField两次,查找只会进行一次吗?如果它是对吸气剂的召唤怎么办?如果我使用一些算术表达式两次会怎么样 它只会被评估一次吗?如果我使用某些表达式的结果,我知道它的值不会改变,作为for循环的上限,该怎么办?
检查数组查找的边界.工具链是否会在某些条件下消除这种情况,例如原型for循环?
价值内联.访问一些public static final int总是内联?即使他们在另一个班级?即使他们在另一个包裹?
分支预测.这甚至有多大问题?是否会在典型的Android设备上大幅提升性能?
简单算术.将someInt * 2被取代someInt << 1?
诸如此类......
Ben*_*Ben 104
这是Ben,JIT @ Google的工程师之一.当Bill和我开始这个项目时,我们的目标是尽快提供一个有效的JIT,对资源争用的影响最小(例如内存占用,CPU被编译器线程劫持),这样它就可以在低端设备上运行好.因此我们使用了非常原始的基于轨迹的模型.也就是说,传递给JIT编译器的编译实体是一个基本块,有时与单个指令一样短.这些跟踪将在运行时通过称为链接的技术拼接在一起,以便不会经常调用解释器和代码缓存查找.在某种程度上,加速的主要来源是消除重复的解释器解析频繁执行的代码路径上的开销.
也就是说,我们确实使用Froyo JIT实现了很多本地优化:
在Gingerbread中,我们为getter/setter添加了简单的内联.由于底层JIT前端仍然是基于简单的跟踪,如果被调用者在那里有分支,则不会内联.但是实现了内联缓存机制,以便可以毫无问题地内联虚拟getter/setter.
我们目前正致力于将编译范围扩展到简单的跟踪之外,以便编译器具有更大的代码分析和优化窗口.敬请关注.
首先,让我先说一下我不是dalvik的专家,我的一些回答可能是错的.但是我已经在dalvik中挖掘了JIT代码,而且我对dalvik运行的字节码非常熟悉.
方法内联 - 据我所知,这种情况从未发生过.我几乎肯定它永远不会发生在字节码级别,我认为它目前不会发生在JIT级别 - 尽管它可能在将来发生.
公共子表达式消除 - 我相信这只能用于不使用任何非最终变量/字段的子表达式.如果即便如此,我也不会完全肯定.如果完成,我希望它可以在字节码级别完成,可能不是JIT级别.
检查数组查找的边界 - 没有线索
价值内联 - 据我所知,是的 - 它们将在所有这些场景中被内联.
分支预测 - 不确定
简单的算术 - 据我所知
另外,我想提一下另一种方法 - dx和dalvik都是开源的,所以你可以随心所欲地挖掘它们.虽然,它们显然不是小代码库,但是需要花费相当多的努力才能在这个级别上深入挖掘它们
| 归档时间: |
|
| 查看次数: |
7587 次 |
| 最近记录: |