尽量缩短执行时间,但失败

时间:2017-03-27 21:08:11

标签: c++ function time

假设有一组点,几乎每个点都在四边形内。但有一些不是。我想知道哪些点不在四边形内。 所以函数看起来像这样。

bool isInside(Point a, Point b, Point c, Point d, Point p) // a,b,c,d are the points consist of the quadrilateral.
{
    if(orientation(a, b, p) < 0)
        return false;
    else if(orientation(b, c, p) < 0)
        return false;
    else if(orientation(c, d, p) < 0)
        return false;
    else if(orientation(d, a, p) < 0)
        return false;
    else 
        return true;
}

我想减少调用方向函数的数量,方向函数看起来像。

int orientation(const Point& p, const Point& q, const Point& r)
{
  double val = (q.x - p.x) * (r.y - p.y) - (q.y - p.y) * (r.x - p.x);

  if (val == 0)
    return 0; // colinear
  return (val < 0) ? -1 : 1; // right or left
}

所以我修改了像这样的函数isInside。

bool isInside(Point a, Point b, Point c, Point d, Point p) 
{
    int result;

    if(p.x <= b.x)
    {
       result = orientation(a, b, p);
    }

    else
    {
      result = orientation(b, c, p);
    }

    if(result == -1) return false;

    if(p.x <= d.x)
    {
      result = orientation(a, d, p);
    }

    else
    {
       result = orientation(d, c, p);
    }

    return (result == -1) ? true : false;
}

这样,调用方向功能的次数几乎减少了一半(如果超过100,000个点则是大量的数字)。但是,它似乎不会影响所花费的时间,有时需要更多。 我不知道怎么会发生这种情况,即使它减少了很多函数调用。

1 个答案:

答案 0 :(得分:3)

编译器优化

最好检查一下是否在启用优化的情况下进行构建。如果要在调试模式下构建应用程序,编译器可能无法优化代码。如果是,请尝试在发布模式下运行。它可以在启用优化或更高级别的优化的情况下构建应用程序。这样,您可以保留代码,而不必担心优化代码(除非绝对需要快速性能)。

定量结果

您还可以添加测试代码,这将允许您获得定量性能结果(运行函数x()n次需要m秒,因此每个x()调用需要m除以n秒)。然后,您应该能够确定哪个代码块花费的时间最多。

如何进行上述操作(不为您编写)的示例如下:

#include <iostream>
#include <chrono>

//Doesn't matter where it is called, just using main as an example
int main(int argc, char *argv[])
{
  int numRuns = 1000000; //Or passed in to allow changing # of runs
                         //without rebuilding: int numRuns = atoi(argv[1]);

  //Code to initialize Point a, b, c, d, and p.

  high_resolution_clock::time_point orien_start_time = high_resolution_clock::now();
  for(int i = 0; i < numRuns; ++i)
  {
    orientation(a, b, p); //Ignore the return value
  }
  high_resolution_clock::time_point orien_end_time = high_resolution_clock::now();

  high_resolution_clock::time_point orien_start_time = high_resolution_clock::now();
  for(int i = 0; i < numRuns; ++i)
  {
    isInside(a, b, c, d, p); //Ignore the return value
  }
  high_resolution_clock::time_point orien_end_time = high_resolution_clock::now();

  //Format and print/log the results
}

然后,使用这些时间点,您可以计算每个函数运行的时间。然后,您可以使用这些数字来确定应用程序的确切速度。走这条路,您可以测试旧实现与新实现,并查看新方法是否更快。您甚至可以尝试不同的点集,以查看是否会改变应用程序性能(例如,尝试使用点p1到p5的两个函数,然后再次尝试使用p6到p10)。

注意:在您编写的代码之外,有很多事情会影响应用程序性能,这就是我为硬编码numRuns使用了一百万的原因。如果你进行少量的迭代,那么每个函数调用的执行时间可以非常大,这取决于系统上运行的其他内容。我对收集定量结果的建议是在新重启的系统上运行测试,其中您的应用程序是唯一运行的用户进程,这样就不必与其他应用程序共享尽可能多的资源。