计算两个CGPoints之间距离的最快方法?

时间:2012-02-02 06:44:22

标签: objective-c math optimization euclidean-distance

两点之间的距离:

sqrt((x1-x2)^2 + (y1-y2)^2)

有没有办法在Objective-C中更快地完成数学运算?

编辑:我想我需要澄清一下。我写了上面的公式只是为了澄清我用来计算距离的公式。 ^并不意味着代表xor - 我只想表示数学公式而不使用任何函数,如pow或任何东西,所以我的意思是使用^来“提升电源”。我想知道是否有人知道是否使用按位运算符,或者在汇编中编写代码会给出优化版本。我在iPhone / iPad应用程序中使用该公式。

5 个答案:

答案 0 :(得分:35)

不,如果你需要确切的距离,你就无法击败那个公式。

虽然要清楚^不是用于平方值的运算符,而是用于执行xor的位运算符。

你需要像

这样的东西
double dx = (x2-x1);
double dy = (y2-y1);
double dist = sqrt(dx*dx + dy*dy);

如果你只能住在广场上(当你想做一些像距离排序的事情时很有用,你就可以使用效率更高的

double dx = (x2-x1);
double dy = (y2-y1);
double dist = dx*dx + dy*dy;

这些至少和解决方案一样好。在最坏的情况下,pow()将使用堆栈并且效率较低,但是在这种情况下,您的编译器可能会将其转换为x * x。

答案 1 :(得分:8)

只是提供一个简单,漂亮的解决方案。它很可能没有任何先前给定的更快,只是更短。我个人正在使用hypot

double dist = hypot((x1-x2), (y1-y2));

根据docs,这将返回“(x ^ 2 + y ^ 2)的平方根。”

答案 2 :(得分:7)

在英特尔Mac上,Clang将编译:

double distance = ({double d1 = x1 - x2, d2 = y1 - y2; sqrt(d1 * d1 + d2 * d2); });

总共有6个数学指令:sub,mul,sub,mul,add,sqrt;很难打败那个。 (sqrt是一条指令,虽然它需要多个周期)。

答案 3 :(得分:3)

double dist = sqrt ( pow((x1-x2), 2) + pow((y1-y2), 2) );

考虑x1, x2, y1, y2floatdouble或整数。

答案 4 :(得分:3)

关于这里唯一可以改进的是平方根计算功能。

我尝试过这两个函数(在Wikipedia article on square root computation中找到)来计算近似平方根值:

float fsqrt(float x)
{
  float xhalf = 0.5f * x;
  union
  {
    float x;
    int i;
  } u;

  u.x = x;
  u.i = 0x5f3759df - (u.i >> 1);
  x *= u.x * (1.5f - xhalf * u.x * u.x);

  return x;
}

float fsqrt2(float z)
{
    union
    {
        int tmp;
        float f;
    } u;

    u.f = z;

    /*
     * To justify the following code, prove that
     *
     * ((((val_int / 2^m) - b) / 2) + b) * 2^m = ((val_int - 2^m) / 2) + ((b + 1) / 2) * 2^m)
     *
     * where
     *
     * val_int = u.tmp
     * b = exponent bias
     * m = number of mantissa bits
     *
     * .
     */

    u.tmp -= 1 << 23; /* Subtract 2^m. */
    u.tmp >>= 1; /* Divide by 2. */
    u.tmp += 1 << 29; /* Add ((b + 1) / 2) * 2^m. */

    return u.f;
}

但是在我的Core 2 Duo Pentium CPU上,它们似乎不比x87 FPU FSQRT指令快。看看它们是否比您平台上的标准sqrtf()/sqrt()工作得更快,并且准确性是否足够。