我正在玩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)代码,如果我触摸屏幕,整个事情也会变慢。为什么会这样?
答案 0 :(得分:1)
降低加速度计频率。
我将它减少到50.0 hz并且加速更新事件停止累积,从而提高了渲染速度。在50hz,应用程序运行完美(iPhone无论如何都无法以100hz渲染)。
#define kAccelerometerFrequency 50.0 // Hz
答案 1 :(得分:0)
你会收到许多事件,并且它们都是在主线程上的委托方法本身中处理的。如果您对glView的消息也很昂贵,系统将处理该消息并且传入的事件将排队。
选项可能是批处理委托调用中的事件,然后定期处理它们并获取摘要结果,然后更新显示。这应该给主线程时间来处理触摸事件。
因此,例如,在委托方法中将事件添加到数组中,尽可能少的代码(使用头尾索引创建循环的数组预分配块),然后每n个事件,使用线程来处理它们并使用glView更新值将该帖子返回到主线程(或者更好,保持后台线程处于活动状态,定期执行处理,如果需要,使用信号量保护数据)。
另外,你可以在加速度计对象上设置updateInterval,也许你只需要减速它?
至于实例vs方法静态...我的猜测是实例var将始终可访问而没有开销,但方法中的静态访问将相对昂贵。但这是值得注意的,我也必须注意这一点。
希望这有帮助。