0

我正在使用 GLGravity 示例来找出与处理加速度计相关的一些性能细微差别。

这是问题代码:

- (void)accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration
{
    static int accelCallCount;
    accelCallCount++;
    if (accelCallCount % 100 == 0) {
        NSLog(@"accelCallCount:%d", accelCallCount);
    }

    //Use a basic low-pass filter to only keep the gravity in the accelerometer values
    accel[0] = acceleration.x * kFilteringFactor + accel[0] * (1.0 - kFilteringFactor);
    accel[1] = acceleration.y * kFilteringFactor + accel[1] * (1.0 - kFilteringFactor);
    accel[2] = acceleration.z * kFilteringFactor + accel[2] * (1.0 - kFilteringFactor);

    //Update the accelerometer values for the view
    [glView setAccel:accel];
}

这段代码运行得很慢。从视觉上,我可以看出茶壶的动作变得非常缓慢,而且越来越慢。最终,茶壶的移动很容易从我实际移动设备的时间延迟了 2 分钟以上。

调试器控制台中的输出也确实显示了一些延迟,但并不过分。它几乎(但不完全)是应有的速度的两倍。

2009-11-27 02:18:58.874 GLGravity[419:207] accelCallCount:100
2009-11-27 02:19:00.507 GLGravity[419:207] accelCallCount:200
2009-11-27 02:19:02.174 GLGravity[419:207] accelCallCount:300

不过,加速度计回调似乎堆积在某种队列中。因此,一开始还不算太糟糕的事情很快就会变得难以忍受。

但是,如果我只是将 accelCallCount 的声明移动到头文件并将其声明为实例 var,则此问题将消失:

int accelCallCount;

为什么要解决它?

在相关说明中,无论我使用此代码还是“固定”(accelCallCount 作为 ivar)代码,如果我触摸屏幕,整个事情也会变慢。为什么会这样?

4

2 回答 2

1

降低加速度计频率。

我将其降低到 50.0 赫兹,加速更新事件停止累积,从而提高了渲染速度。在 50hz 下,应用程序运行完美(iPhone 无论如何都无法以 100hz 渲染)。

#define kAccelerometerFrequency     50.0 // Hz
于 2010-01-05T17:49:36.457 回答
0

您会收到很多事件,目前它们都在主线程上的委托方法本身中处理。如果您发送给 glView 的消息也很昂贵,则系统将处理该消息,并且传入的事件将排队。

一个选项可能是在委托调用中对事件进行批处理,然后定期处理它们并获取摘要结果,然后更新显示。这也应该给主线程时间来处理触摸事件。

因此,例如,将事件添加到委托方法中的数组中,其中使用尽可能少的代码(使数组预先分配块,使用头和尾索引循环遍历),然后每 n 个事件,释放一个线程处理它们并使用 glView 更新值将其发回主线程(或者更好的是,保持后台线程处于活动状态,定期进行处理,如果需要,使用信号量保护数据)。

此外,您可以在加速度计对象上设置 updateInterval,也许您只需要放慢速度?

至于实例与方法静态......我的猜测是实例变量将一直可访问而没有开销,但方法中的静态访问将相对昂贵。但这是值得注意的,我也必须注意这一点。

希望这可以帮助。

于 2009-11-27T11:54:35.463 回答