cem*_*ate 4 c math performance cocoa
我正在使用图形加速度计数据,我正在尝试纠正重力.为此,我得到球面坐标中的加速度矢量,将半径减小1g,然后转换回笛卡尔坐标.每0.03秒在一个计时器上调用此方法:
//poll accleration
ThreeAxisAcceleration current = self.accelerationData;
//math to correct for gravity:
float radius = sqrt(pow(current.x, 2) + pow(current.y, 2) + pow(current.z, 2));
float theta = atan2(current.y, current.x);
float phi = acos(current.z/radius);
//NSLog(@"SPHERICAL--- RADIUS: %.2f -- THETA: %.2f -- PHI: %.2f", radius, theta, phi);
radius = radius - 1.0;
float newX = radius * cos(theta) * sin(phi);
float newY = radius * sin(theta) * sin(phi);
float newZ = radius * cos(phi);
current = (ThreeAxisAcceleration){newX, newY, newZ};
//end math
NSValue *arrayVal = [NSValue value:¤t withObjCType:@encode(ThreeAxisAcceleration)];
if ([_dataHistoryBuffer count] > self.bounds.size.width) {
[_dataHistoryBuffer removeObjectAtIndex:0];
}
[_dataHistoryBuffer addObject:arrayVal];
[self setNeedsDisplay];
Run Code Online (Sandbox Code Playgroud)
不知何故,重力校正的加入逐渐使我的代码变得非常缓慢.我发现很难相信这个数学量会减慢程序的速度,但如果没有它,它仍然可以贯穿我的整个显示方法,这种方法非常冗长.我有什么选择可以考虑避免这种情况吗?我错过了什么,或者数学是那么缓慢?我可以在// math和// end math标签之间进行注释,就可以了.
谢谢你的帮助.
PS可能很重要,它可能对谁感兴趣,我正在用可可编程,这个方法属于CALayer的子类,使用-drawInContext:实现.
缩短矢量的常规方法是:
float originalMagnitude = sqrtf(current.x * current.x, current.y * current.y, current.z* current.z);
float desiredMagnitude = originalMagnitude - 1.0f;
float scaleFactor = (originalMagnitude != 0) ? desiredMagnitude / originalMagnitude : 0.0f; // avoid divide-by-zero
current.x *= scaleFactor;
current.y *= scaleFactor;
current.z *= scaleFactor;
Run Code Online (Sandbox Code Playgroud)
也就是说,不,每秒33次调用一些触发功能不应该让你失望太多.另一方面,-[NSMutableArray removeObjectAtIndex:]对于大阵列来说可能会很慢.甲环缓冲器(使用NSMutableArray或结构的C数组)会更有效.
假设你得到一个配置文件,显示所有的数学运算真的让你失望:
pow(someFloat,2).编译器应该能够为您优化这一点,但通常,在较新的硬件上,这些优化可能尚未到位.这应该总是写成someFloat*someFloat.pow()函数通常是数学库中最昂贵的函数.简单乘法将始终至少与调用pow()一样快,并且始终至少同样准确(假设符合IEEE-754算术).此外,编译器更容易优化.floatS IN C,使用数学库函数的后缀形式. sinf比...更快sin. sqrtf比...更快sqrt.除了功能本身更快,您可以避免不必要的转换double.