4

我在 onDraw() 方法的调用堆栈中有一个方法 3 级。每次重绘被称为数百次,有时甚至数千次。我已经对 onDraw() 方法进行了广泛的分析,我可以看到以下方法占总数的 14%,因此绝对值得一看。我需要在捏缩放和拖动操作期间提高帧速率。

private void getVisiblePointsFromPath(){

   double longRads = longitude * (Math.PI / 180);
   double latRads = latitude * (Math.PI / 180);

   ...

}

当方法退出并且双打超出范围时,我假设它们有资格进行 GC,尽管我认识到这可能发生的时间是不确定的。

这样做有什么好处吗:

public class GisView extends ImageView{

    private double longRads;
    private double latRads;

    private void getVisiblePointsFromPath(){

       longRads = longitude * (Math.PI / 180);
       latRads = latitude * (Math.PI / 180);

       ...

    }

}

我假设这个习惯用法会导致双打被清空,然后在每次传递时重新分配,但不会导致额外的垃圾,从而减少我造成的 GC 数量。还是虚拟机比这更聪明?

请注意,我的问题本身并不是“哪个更快”,而是关于哪个可能导致更少的 GC。我可以测量速度差异,但我对 Dalvik VM 和 Android GC 的了解还不够,无法预测哪个会导致更少的垃圾。

4

1 回答 1

7

我假设这个习惯用法会导致双打被清空,然后在每次传递时重新分配,但不会导致额外的垃圾,从而减少我造成的 GC 数量。还是虚拟机比这更聪明?

原始局部变量存在于堆栈上,而不是堆上,因此它们根本不需要进行 GC。一旦函数返回,它们就会有效地消失——因为这会清除堆栈帧。

也就是说,是的,每次传递都会重新分配双打,因为这就是您编写的代码所说的。如果您想提高此特定方法的速度,请计算longRadsand latRadswhen longitudeand latitudeare set。正确的做法是始终将这些字段的设置委托给 setter 方法。例如:

public void setLongitude(double longitude) {
    this.longitude = longitude;
    this.longRags = longitude * (Math.PI / 180);
}

当然,这会使设置速度变慢,但这不是您所要求的优化。

于 2013-02-02T20:52:04.033 回答