哪些最容易犯的错误可能会导致 Android 性能下降?
文档提到“一些浮点运算”可以是“毫秒级”——有人测试过吗?
为了便于讨论,我们假设它在 G1/类似设备上运行。
哪些最容易犯的错误可能会导致 Android 性能下降?
文档提到“一些浮点运算”可以是“毫秒级”——有人测试过吗?
为了便于讨论,我们假设它在 G1/类似设备上运行。
wrt浮点:
在 G1 上,添加两个浮点数大约需要 400ns。添加两个整数大约需要 250ns。
在运行 eclair (pre-JIT) 的 nexus one 上,这两个操作都需要大约 120ns。(int 稍微快一点,但你必须进行微基准测试才能注意到。) int 和 long、float 和 double 之间的百分比差异很小,但基本上如果你买得起一个,你可能买得起另一个。
其他当前设备将介于这些极端之间。(其他操作也会有所不同。乘法比加法/减法更昂贵,除法更昂贵。目前没有硬件整数除法。)
但在你遇到问题之前不要执着于这些。很可能,您的性能问题将归结为算法或数据结构的错误选择,就像每个人的性能问题一样。
大多数当前(eclair)性能文档都是不正确的。在您关心的设备上自己对事物进行基准测试。
但如果你真的问“桌面/服务器 java 程序员应该注意什么?”,我建议:不必要的分配。您没有像在台式机/服务器上那样做 GC 的备用核心,也没有像在台式机/服务器上那样拥有千兆字节的堆。如果你在做 GC,你没有做真正的工作,你的堆在当前设备上最多为 24MiB。因此您可能希望避免在内部循环中进行不必要的分配。
有关特定于渲染的性能提示,请参阅这些 Google I/O 2009 演讲:
他们希望您避免使用 float 的原因是因为它很少在电话 cpu(可能是 arm)上实现,并且必须在速度较慢的软件中实现。不过,定点通常在硬件中得到支持。
有些手机确实在硬件中实现了浮点,但由于您不知道您的应用程序可能部署到哪部手机,因此它们不会冒险。
很多人还说避免使用对象,在手机和 java me 非常慢的时代,人们过去常常用静态函数在程序上编写 java。不过,我现在不建议这样做。
在您知道代码存在重大问题之前,不要担心性能。小的调整(整数而不是浮点数,使用迭代器而不是显式数组枚举)往往非常小,当你的应用程序关闭时你最好看看它们。让 5% 的慢代码变得更复杂,而不是让整个应用程序变得更复杂。
根据 Android 人员的说法,您应该避免将接口名称用于集合。例如,标准 Java 的标准最佳实践是说
List<String> strings = new ArrayList<String>();
而在 Android 中,他们说最好用它的运行时类型声明它
ArrayList<String> strings = new ArrayList<String>();
我发现 AppInventor 模拟器对于浮点运算来说非常慢,即使在 2014 i3/4Gb 机器上也是如此。我编写了一个分形生成器来对模拟器进行基准测试,发现要计算一个像素,10 次迭代只需要两秒多一点——是的,2000 毫秒。我还没有完全解开它来找出哪些特定的操作如此缓慢,但我很快就会这样做。
每次迭代涉及四次乘法,两次加法和一次减法,五个变量。每次迭代后的测试涉及两次乘法、一次加法和两次比较——大约 30 次失败。我还没有通过存储下一次迭代的结果来优化代码。
显然,如果有办法强制定点或仅使用整数会有所帮助,但我在这个小项目中面临的问题的严重性并不是一个好兆头。