简体   繁体   English

在c ++中使用对象时对性能的影响

[英]Effect on performance when using objects in c++

I have a dynamic programming algorithm for Knapsack in C++. 我有一个用于C ++的Knapsack的动态编程算法。 When it was implemented as a function and accessing variables passed into it, it was taking 22 seconds to run on a particular instance. 当它作为函数实现并访问传递给它的变量时,在特定实例上运行需要22秒。 When I made it the member function of my class KnapsackInstance and had it use variables that were data members of that class, it started taking 37 seconds to run. 当我把它作为我的类KnapsackInstance的成员函数并让它使用属于该类的数据成员的变量时,它开始需要37秒才能运行。 As far as I know, only accessing member functions goes through the vtable so I'm at a loss to explain what might be happening. 据我所知,只有访问成员函数才能通过vtable,所以我无法解释可能发生的事情。

Here's the code of the function 这是函数的代码

int KnapsackInstance::dpSolve() {
 int i; // Current item number
 int d; // Current weight
 int * tbl; // Array of size weightLeft
 int toret;
 tbl = new int[weightLeft+1];
 if (!tbl) return -1;
 memset(tbl, 0, (weightLeft+1)*sizeof(int));
 for (i = 1; i <= numItems; ++i) {
  for (d = weightLeft; d >= 0; --d) {
   if (profitsWeights.at(i-1).second <= d) {
    /* Either add this item or don't */
    int v1 = profitsWeights.at(i-1).first + tbl[d-profitsWeights.at(i-1).second];
    int v2 = tbl[d];
    tbl[d] = (v1 < v2 ? v2 : v1);
   }
  }
 }
 toret = tbl[weightLeft];
 delete[] tbl;
 return toret;
}

tbl is one column of the DP table. tbl是DP表的一列。 We start from the first column and go on until the last column. 我们从第一列开始,一直到最后一列。 The profitsWeights variable is a vector of pairs, the first element of which is the profit and the second the weight. profitsWeights变量是对的向量,其中第一个元素是利润,第二个元素是权重。 toret is the value to return. toret是回归的价值。

Here is the code of the original function :- 这是原始功能的代码: -

int dpSolve(vector<pair<int, int> > profitsWeights, int weightLeft, int numItems) {
 int i; // Current item number
 int d; // Current weight
 int * tbl; // Array of size weightLeft
 int toret;
 tbl = new int[weightLeft+1];
 if (!tbl) return -1;
 memset(tbl, 0, (weightLeft+1)*sizeof(int));
 for (i = 1; i <= numItems; ++i) {
  for (d = weightLeft; d >= 0; --d) {
   if (profitsWeights.at(i-1).second <= d) {
    /* Either add this item or don't */
    int v1 = profitsWeights.at(i-1).first + tbl[d-profitsWeights.at(i-1).second];
    int v2 = tbl[d];
    tbl[d] = (v1 < v2 ? v2 : v1);
   }
  }
 }
 toret = tbl[weightLeft];
 delete[] tbl;
 return toret;
}

This was run on Debian Lenny with g++-4.3.2 and -O3 -DNDEBUG turned on 这是在Debian Lenny上运行的,启用了g ++ - 4.3.2和-O3 -DNDEBUG

Thanks 谢谢

In a typical implementation, a member function receives a pointer to the instance data as a hidden parameter ( this ). 在典型的实现中,成员函数接收指向实例数据的指针作为隐藏参数( this )。 As such, access to member data is normally via a pointer, which may account for the slow-down you're seeing. 因此,访问成员数据通常是通过指针,这可能会导致您看到的速度减慢。

On the other hand, it's hard to do more than guess with only one version of the code to look at. 另一方面,只需要查看一个版本的代码就很难做到。

After looking at both pieces of code, I think I'd write the member function more like this: 在查看了两段代码后,我想我会更像这样编写成员函数:

int KnapsackInstance::dpSolve() {
    std::vector<int> tbl(weightLeft+1, 0);
    std::vector<pair<int, int> > weights(profitWeights);
    int v1;

    for (int i = 0; i <numItems; ++i) 
        for (int d = weightLeft; d >= 0; --d)
            if ((weights[i+1].second <= d) && 
                ((v1 = weights[i].first + tbl[d-weights[i-1].second])>tbl[d]))
                    tbl[d] = v1;
    return tbl[weightLeft];
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM