循环,功能设计和效率:两个问题

时间:2012-06-13 16:20:17

标签: c++ loops function-pointers performance

我有两个相关的问题,一个是普通的,一个是我正在研究的项目。

  1. 一般来说,如果我有一个循环有很多迭代(数百万),某些代码部分在某些条件下执行,那么一个循环有多个条件语句或多个循环没有它们会更好(更有效)。例如。
  2. 示例1:

    while (something())
    {
        // some common code
        if (condition_a)
            // some code
        if (condition_b)
            // some code
        // some more common code
    }
    

    示例2:

    if (condition_a && condition_b)
    {
        while (something())
        {
            // some common and specific code
        }
    }
    else if (condition_a)
        while (something()) //..
    else if (condition_b)
        // Another loop
    else //...
    

    似乎示例2会以冗余为代价导致更高效的代码,因为条件只检查一次而不是百万次。如果公共代码很大或者有很多可能的条件,那么这似乎是多余的。

    1. 现在针对我的具体问题。我有一个函数,它从文件中读取点并将它们插入到数据结构中。它看起来像这样:

      while(reader-> read_point)     {         //做一些事情         //插入点     }

    2. 问题在于,有几个函数用于读取应根据用户提供的标准使用的点。例如read_point_inside_circle(),read_point_inside_rectangle()等。

      理想情况下,我想使用函数指针事先决定正确的函数,但是我不认为这是可能的,因为reader是Reader类的一个实例(如果有可能以某种方式解决我的所有问题)

      在这种情况下,如果我有多个循环只有条件不同或者我应该使用多个if语句以避免冗余代码,那就更好了,例如。

      for(;;)
      {
          if (read_every_point)
              if(!reader->read_point())
                  break;
          else if (read_inside_circle)
              if(!reader->read_inside_circle())
                  break;
          else if // ...
      }
      

2 个答案:

答案 0 :(得分:3)

回答您的具体问题:读取文件所花费的时间将超过在if / else中花费的时间。写任何更可读的东西。这通常更有效率,并且在您证明它是瓶颈之前不要对其进行优化。

回答你的一般问题:取决于很多事情,现代编译器非常善于独立于你的直觉而有效地做事。所以这是一个理论上的讨论,直到你在特定的编译器和架构上有代码。

答案 1 :(得分:2)

  

理想情况下,我想使用函数指针事先决定正确的函数,但是我不认为这是可能的,因为reader是Reader类的一个实例(如果有可能以某种方式解决我的所有问题)

您可以使用成员函数指针,假设所有读取函数具有相同的签名:

typedef void (Reader::*read_fun_t)();
read_fun_t read_fun = &Reader::read_point;
// or
read_fun_t read_fun = &Reader::read_inside_circle;

...

(reader->*read_fun)();

或者如果你觉得它们不舒服,只需创建自己的自由函数来包装方法调用:

void read_point( Reader* reader ){ reader->read_point(); }
void read_inside_circle( Reader* reader ){ reader->read_inside_circle(); }

并改为使用常规函数指针。