Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么我的代码是C++;比我用C编写的代码慢很多_C++_C - Fatal编程技术网

C++ 为什么我的代码是C++;比我用C编写的代码慢很多

C++ 为什么我的代码是C++;比我用C编写的代码慢很多,c++,c,C++,C,到目前为止,我用C编写代码(性能是最重要的)。然而,我想开始以一种通用的方式编写我的算法。所以,我决定尝试C++。我在C中使用了一个简单的代码,并用模板将其翻译成C++。令我失望的是,C++代码运行速度慢了2.5倍。(C代码用GCC—O3编译;C++代码用G++O3编译)< /P> 我在C++中做了什么错误吗?为什么会有这样的演出热播 下面是C代码: #include <stdio.h> #include <stdlib.h> #include <string.h&

到目前为止,我用C编写代码(性能是最重要的)。然而,我想开始以一种通用的方式编写我的算法。所以,我决定尝试C++。我在C中使用了一个简单的代码,并用模板将其翻译成C++。令我失望的是,C++代码运行速度慢了2.5倍。(C代码用GCC—O3编译;C++代码用G++O3编译)< /P> 我在C++中做了什么错误吗?为什么会有这样的演出热播

下面是C代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

static int df_output = 0;
int nCalls = 0;

typedef struct {
  int *pancakes;
  int n;
} STATE;
STATE **solution;

void shuffle(STATE *s) {
  int i;
  for (i = 0; i < s->n; i++) {
    int i1 = rand() % s->n;
    int i2 = rand() % s->n;
    int temp = s->pancakes[i1];
    s->pancakes[i1] = s->pancakes[i2];
    s->pancakes[i2] = temp;
  }
}

STATE *copyState(STATE *s) {
  STATE *res = malloc(sizeof(STATE));
  res->n = s->n;
  res->pancakes = (int *)malloc(res->n * sizeof(int));
  memcpy(res->pancakes, s->pancakes, res->n * sizeof(int));
  return res;
}

// reverse n pancakes
void makeMove(STATE *s, int n) {
  int i;
  for (i = 0; i < n/2; i++) {
    int temp = s->pancakes[i];
    s->pancakes[i] = s->pancakes[n - 1 - i];
    s->pancakes[n - 1 - i]=temp;
  }
}

void printState(STATE *s) {
  int i;
  printf("[");
  for (i = 0; i < s->n; i++) {
    printf("%d", s->pancakes[i]);
    if (i < s->n - 1)
      printf(", ");
  }
  printf("]");
}

int heuristic(STATE *s) {
  int i, res = 0;
  nCalls++;
  for (i = 1; i < s->n; i++)
    if (abs(s->pancakes[i]-s->pancakes[i-1])>1)
      res++;
  if (s->pancakes[0] != 0) res++;
  return res;
}

void tabs(int g) {
  int i;
  for (i = 0; i < g; i++) printf("\t");
}

int df(STATE *s, int g, int left) {
  int h = heuristic(s), i;
  if (g == 0) printf("Thereshold: %d\n", left);
  if (df_output) {
    tabs(g);
    printf("g=%d,left=%d ", g, left); printState(s); printf("\n");}
  if (h == 0) {
    assert(left == 0);
    solution = (STATE **)malloc((g+1) * sizeof(STATE *));
    solution[g] = copyState(s);
    return 1;
  }
  if (left == 0)
    return 0;
  for (i = 2; i <= s->n; i++) {
    makeMove(s, i);
    if (df(s, g+1, left-1)) {
      makeMove(s, i);
      solution[g] = copyState(s);
      return 1;
    }
    makeMove(s, i);
  }
  return 0;
}

void ida(STATE *s) {
  int threshold = 0, i;
  while (!df(s, 0, threshold)) threshold++; 

  for (i = 0; i <= threshold; i++) {
    printf("%d. ", i);
    printState(solution[i]);
    printf("\n");
    //if (i < threshold - 1) printf("->");
  }
}

int main(int argc, char **argv) {
  STATE *s = (STATE *)malloc(sizeof(STATE));
  int i, n;
  int myInstance[] = {0,5,4,7,2,6,1,3};
  s->n = 8;
  s->pancakes = myInstance;
  printState(s); printf("\n");
  ida(s);
  printf("%d calls to heuristic()", nCalls);
  return 0;
}
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <vector>

using namespace std;

static int df_output = 0;
int nCalls = 0;

class PancakeState {
public:
    PancakeState(int n) : n(n), pancakes(n) 
    {
    }
    PancakeState(int n, int *v) : n(n), pancakes(n) 
    {
        for(int i = 0; i < n; i++)
        pancakes[i] = v[i];
    }
    PancakeState(): n(0) {}
public:
    vector<int> pancakes;
    int n;
    PancakeState *copyState();
    void printState();
};

void PancakeState::printState() {
  int i;
  cout << "[";
  for (i = 0; i < this->n; i++) {
    cout << this->pancakes[i];
    if (i < this->n - 1)
      cout << ", ";
  }
  cout << "]";
}

class PancakeMove {
public:
    PancakeMove(int n) : n(n)  {}
    int n;
};

class Pancake {
public:
  int heuristic (PancakeState &);
  int bf(PancakeState&);
  PancakeMove getMove(int);
  void makeMove(PancakeState &, PancakeMove &);
  void unmakeMove(PancakeState &, PancakeMove &);
};

int Pancake::bf(PancakeState& s) {
  return s.n - 1;
}

PancakeMove Pancake::getMove(int i) {
  return PancakeMove(i + 2); 
}

// reverse n pancakes
void Pancake::makeMove(PancakeState &s, PancakeMove &m) {
  int i;
  int n = m.n;
  for (i = 0; i < n/2; i++) {
    int temp = s.pancakes[i];
    s.pancakes[i] = s.pancakes[n - 1 - i];
    s.pancakes[n - 1 - i]=temp;
  }
}

void Pancake::unmakeMove(PancakeState &state, PancakeMove &move) {
  makeMove(state, move);
}

int Pancake::heuristic(PancakeState &s) {
  int i, res = 0;
  nCalls++;
  for (i = 1; i < s.n; i++)
    if (abs(s.pancakes[i]-s.pancakes[i-1])>1)
      res++;
  if (s.pancakes[0] != 0) res++;
  return res;
}

void tabs(int g) {
  int i;
  for (i = 0; i < g; i++) cout << "\t";
}

template <class Domain, class State, class Move>
class Alg {
public:
  vector<State> solution;
  int threshold;
  bool verbose;
  int df(Domain &d, State &s, int g);
  void ida(Domain &d, State &s);
};

template <class Domain, class State, class Move>
int Alg<Domain, State, Move>::df(Domain &d, State &s, int g) {
  int h = d.heuristic(s), i;
  if (g == 0) 
    cout << "Thereshold:" << threshold << "\n";
  if (this->verbose) {
    tabs(g);
    cout << "g=" << g;
    s.printState(); cout << "\n";
  }
  if (h == 0) {
      solution.resize(g+1);
      solution[g] = s;
      return 1;
  }
  if (g == this->threshold)
    return 0;
  for (i = 0; i < d.bf(s); i++) {
    Move move = d.getMove(i);
    d.makeMove(s, move);
    if (this->df(d, s, g+1)) {
      d.unmakeMove(s, move);
      solution[g] = s;
      return 1;
    }
    d.unmakeMove(s, move);
  }
  return 0;
}

template <class Domain, class State, class Move>
void Alg<Domain, State, Move>::ida(Domain &d, State &s) {
  int i;
  this->threshold = 0;
  while (!this->df(d, s, 0)) threshold++; 

  for (i = 0; i <= threshold; i++) {
    cout << i << ".";
    solution[i].printState();
    cout << "\n";
    //if (i < threshold - 1) printf("->");
  }
}

int main(int argc, char **argv) {
  Pancake d = Pancake();
  int myInstance[] = {0,5,4,7,2,6,1,3};
  PancakeState s(8, myInstance);
  s.printState(); cout << "\n";
  Alg<Pancake, PancakeState, PancakeMove> *alg = new Alg<Pancake, PancakeState, PancakeMove>();
  //alg->verbose = true;
  alg->ida(d, s);
  cout << nCalls < "calls to heuristic()";
  delete alg;
  return 0;
}
#包括
#包括
#包括
#包括
静态int df_输出=0;
int-nCalls=0;
类型定义结构{
国际*煎饼;
int n;
}国家;
国家**解决方案;
无效洗牌(状态*s){
int i;
对于(i=0;in;i++){
int i1=rand()%s->n;
int i2=rand()%s->n;
int temp=s->煎饼[i1];
s->煎饼[i1]=s->煎饼[i2];
s->煎饼[i2]=温度;
}
}
州*copyState(州*s){
STATE*res=malloc(sizeof(STATE));
res->n=s->n;
res->pancakes=(int*)malloc(res->n*sizeof(int));
memcpy(res->pancakes,s->pancakes,res->n*sizeof(int));
返回res;
}
//烤饼
void makeMove(状态*s,整数n){
int i;
对于(i=0;i煎饼[i];
s->煎饼[i]=s->煎饼[n-1-i];
s->煎饼[n-1-i]=温度;
}
}
无效打印状态(状态*s){
int i;
printf(“[”);
对于(i=0;in;i++){
printf(“%d”,s->煎饼[i]);
如果(in-1)
printf(“,”);
}
printf(“]”);
}
int启发式(STATE*s){
int i,res=0;
nCalls++;
对于(i=1;in;i++)
如果(abs(s->pancakes[i]-s->pancakes[i-1])>1)
res++;
如果(s->煎饼[0]!=0)res++;
返回res;
}
空制表符(整数g){
int i;
对于(i=0;ipancakes=myInstance;
printState;printf(“\n”);
国际开发协会(s);
printf(“%d个对启发式()的调用”,ncall);
返回0;
}

这里是C++代码:

#include <iostream>
#include "stdlib.h"
#include "string.h"
#include "assert.h"
using namespace std;

static int df_output = 0;
int nCalls = 0;

class PancakeState {
public:
  int *pancakes;
  int n;
  PancakeState *copyState();
  void printState();
};

PancakeState *PancakeState::copyState() {
  PancakeState *res = new PancakeState();
  res->n = this->n;
  res->pancakes = (int *)malloc(this->n * sizeof(int));
  memcpy(res->pancakes, this->pancakes, 
     this->n * sizeof(int));
  return res;
}

void PancakeState::printState() {
  int i;
  cout << "[";
  for (i = 0; i < this->n; i++) {
    cout << this->pancakes[i];
    if (i < this->n - 1)
      cout << ", ";
  }
  cout << "]";
}

class PancakeMove {
public:
  PancakeMove(int n) {this->n = n;}
  int n;
};

class Pancake {
public:
  int heuristic (PancakeState &);
  int bf(PancakeState &);
  PancakeMove *getMove(int);
  void makeMove(PancakeState &, PancakeMove &);
  void unmakeMove(PancakeState &, PancakeMove &);
};

int Pancake::bf(PancakeState &s) {
  return s.n - 1;
}

PancakeMove *Pancake::getMove(int i) {
  return new PancakeMove(i + 2); 
}

// reverse n pancakes
void Pancake::makeMove(PancakeState &s, PancakeMove &m) {
  int i;
  int n = m.n;
  for (i = 0; i < n/2; i++) {
    int temp = s.pancakes[i];
    s.pancakes[i] = s.pancakes[n - 1 - i];
    s.pancakes[n - 1 - i]=temp;
  }
}

void Pancake::unmakeMove(PancakeState &state, PancakeMove &move) {
  makeMove(state, move);
}

int Pancake::heuristic(PancakeState &s) {
  int i, res = 0;
  nCalls++;
  for (i = 1; i < s.n; i++)
    if (abs(s.pancakes[i]-s.pancakes[i-1])>1)
      res++;
  if (s.pancakes[0] != 0) res++;
  return res;
}

void tabs(int g) {
  int i;
  for (i = 0; i < g; i++) cout << "\t";
}

template <class Domain, class State, class Move>
class Alg {
public:
  State **solution;
  int threshold;
  bool verbose;
  int df(Domain &d, State &s, int g);
  void ida(Domain &d, State &s);
};

template <class Domain, class State, class Move>
int Alg<Domain, State, Move>::df(Domain &d, State &s, int g) {
  int h = d.heuristic(s), i;
  if (g == 0) 
    cout << "Thereshold:" << this->threshold << "\n";
  if (this->verbose) {
    tabs(g);
    cout << "g=" << g;
    s.printState(); cout << "\n";
  }
  if (h == 0) {
    solution = (State **)malloc((g+1) * sizeof(State *));
    solution[g] = s.copyState();
    return 1;
  }
  if (g == this->threshold)
    return 0;
  for (i = 0; i < d.bf(s); i++) {
    Move *move = d.getMove(i);
    d.makeMove(s, *move);
    if (this->df(d, s, g+1)) {
      d.unmakeMove(s, *move);
      solution[g] = s.copyState();
      delete move;
      return 1;
    }
    d.unmakeMove(s, *move);
    delete move;
  }
  return 0;
}

template <class Domain, class State, class Move>
void Alg<Domain, State, Move>::ida(Domain &d, State &s) {
  int i;
  this->threshold = 0;
  while (!this->df(d, s, 0)) threshold++; 

  for (i = 0; i <= threshold; i++) {
    cout << i << ".";
    this->solution[i]->printState();
    cout << "\n";
    //if (i < threshold - 1) printf("->");
  }
}

int main(int argc, char **argv) {
  Pancake *d = new Pancake();
  PancakeState *s = new PancakeState();
  int myInstance[] = {0,5,4,7,2,6,1,3};
  s->pancakes = myInstance;
  s->n = 8;
  s->printState(); cout << "\n";
  Alg<Pancake, PancakeState, PancakeMove> *alg = new Alg<Pancake, PancakeState, PancakeMove>();
  //alg->verbose = true;
  alg->ida(*d, *s);
  cout << nCalls < "calls to heuristic()";
  delete alg;
  return 0;
}
#包括
#包括“stdlib.h”
#包括“string.h”
#包括“assert.h”
使用名称空间std;
静态int df_输出=0;
int-nCalls=0;
煎饼州{
公众:
国际*煎饼;
int n;
PancakeState*copyState();
无效打印状态();
};
PancakeState*PancakeState::copyState(){
PancakeState*res=新的PancakeState();
res->n=此->n;
res->pancakes=(int*)malloc(this->n*sizeof(int));
memcpy(res->pancakes,this->pancakes,
这个->n*sizeof(int));
返回res;
}
void PancakeState::printState(){
int i;
cout n;i++){
煎饼;
如果(in-1)
法庭(1)
res++;
如果(s.pancakes[0]!=0)res++;
返回res;
}
空制表符(整数g){
int i;
对于(i=0;iprintState();cout verbose=true;
alg->ida(*d,*s);
CUT

你有很多MalCube()和操作符新的调用。停止这样做,性能会提高。在C++中不要使用MalCube(),使用运算符NeXT。< /P>


例如,PancakeMove是一个小而平凡的结构。但是动态分配它的实例,这很慢。只需按值传递它。

基本上,您在堆上而不是在堆栈上分配很多小东西。这相当“昂贵”,因此需要额外的时间

此代码(从原始代码修改而来)在C代码的1ms内运行:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

static int df_output = 0;
int nCalls = 0;

typedef struct {
  int *pancakes;
  int n;
} STATE;
STATE **solution;

void shuffle(STATE *s) {
  int i;
  for (i = 0; i < s->n; i++) {
    int i1 = rand() % s->n;
    int i2 = rand() % s->n;
    int temp = s->pancakes[i1];
    s->pancakes[i1] = s->pancakes[i2];
    s->pancakes[i2] = temp;
  }
}

STATE *copyState(STATE *s) {
  STATE *res = malloc(sizeof(STATE));
  res->n = s->n;
  res->pancakes = (int *)malloc(res->n * sizeof(int));
  memcpy(res->pancakes, s->pancakes, res->n * sizeof(int));
  return res;
}

// reverse n pancakes
void makeMove(STATE *s, int n) {
  int i;
  for (i = 0; i < n/2; i++) {
    int temp = s->pancakes[i];
    s->pancakes[i] = s->pancakes[n - 1 - i];
    s->pancakes[n - 1 - i]=temp;
  }
}

void printState(STATE *s) {
  int i;
  printf("[");
  for (i = 0; i < s->n; i++) {
    printf("%d", s->pancakes[i]);
    if (i < s->n - 1)
      printf(", ");
  }
  printf("]");
}

int heuristic(STATE *s) {
  int i, res = 0;
  nCalls++;
  for (i = 1; i < s->n; i++)
    if (abs(s->pancakes[i]-s->pancakes[i-1])>1)
      res++;
  if (s->pancakes[0] != 0) res++;
  return res;
}

void tabs(int g) {
  int i;
  for (i = 0; i < g; i++) printf("\t");
}

int df(STATE *s, int g, int left) {
  int h = heuristic(s), i;
  if (g == 0) printf("Thereshold: %d\n", left);
  if (df_output) {
    tabs(g);
    printf("g=%d,left=%d ", g, left); printState(s); printf("\n");}
  if (h == 0) {
    assert(left == 0);
    solution = (STATE **)malloc((g+1) * sizeof(STATE *));
    solution[g] = copyState(s);
    return 1;
  }
  if (left == 0)
    return 0;
  for (i = 2; i <= s->n; i++) {
    makeMove(s, i);
    if (df(s, g+1, left-1)) {
      makeMove(s, i);
      solution[g] = copyState(s);
      return 1;
    }
    makeMove(s, i);
  }
  return 0;
}

void ida(STATE *s) {
  int threshold = 0, i;
  while (!df(s, 0, threshold)) threshold++; 

  for (i = 0; i <= threshold; i++) {
    printf("%d. ", i);
    printState(solution[i]);
    printf("\n");
    //if (i < threshold - 1) printf("->");
  }
}

int main(int argc, char **argv) {
  STATE *s = (STATE *)malloc(sizeof(STATE));
  int i, n;
  int myInstance[] = {0,5,4,7,2,6,1,3};
  s->n = 8;
  s->pancakes = myInstance;
  printState(s); printf("\n");
  ida(s);
  printf("%d calls to heuristic()", nCalls);
  return 0;
}
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <vector>

using namespace std;

static int df_output = 0;
int nCalls = 0;

class PancakeState {
public:
    PancakeState(int n) : n(n), pancakes(n) 
    {
    }
    PancakeState(int n, int *v) : n(n), pancakes(n) 
    {
        for(int i = 0; i < n; i++)
        pancakes[i] = v[i];
    }
    PancakeState(): n(0) {}
public:
    vector<int> pancakes;
    int n;
    PancakeState *copyState();
    void printState();
};

void PancakeState::printState() {
  int i;
  cout << "[";
  for (i = 0; i < this->n; i++) {
    cout << this->pancakes[i];
    if (i < this->n - 1)
      cout << ", ";
  }
  cout << "]";
}

class PancakeMove {
public:
    PancakeMove(int n) : n(n)  {}
    int n;
};

class Pancake {
public:
  int heuristic (PancakeState &);
  int bf(PancakeState&);
  PancakeMove getMove(int);
  void makeMove(PancakeState &, PancakeMove &);
  void unmakeMove(PancakeState &, PancakeMove &);
};

int Pancake::bf(PancakeState& s) {
  return s.n - 1;
}

PancakeMove Pancake::getMove(int i) {
  return PancakeMove(i + 2); 
}

// reverse n pancakes
void Pancake::makeMove(PancakeState &s, PancakeMove &m) {
  int i;
  int n = m.n;
  for (i = 0; i < n/2; i++) {
    int temp = s.pancakes[i];
    s.pancakes[i] = s.pancakes[n - 1 - i];
    s.pancakes[n - 1 - i]=temp;
  }
}

void Pancake::unmakeMove(PancakeState &state, PancakeMove &move) {
  makeMove(state, move);
}

int Pancake::heuristic(PancakeState &s) {
  int i, res = 0;
  nCalls++;
  for (i = 1; i < s.n; i++)
    if (abs(s.pancakes[i]-s.pancakes[i-1])>1)
      res++;
  if (s.pancakes[0] != 0) res++;
  return res;
}

void tabs(int g) {
  int i;
  for (i = 0; i < g; i++) cout << "\t";
}

template <class Domain, class State, class Move>
class Alg {
public:
  vector<State> solution;
  int threshold;
  bool verbose;
  int df(Domain &d, State &s, int g);
  void ida(Domain &d, State &s);
};

template <class Domain, class State, class Move>
int Alg<Domain, State, Move>::df(Domain &d, State &s, int g) {
  int h = d.heuristic(s), i;
  if (g == 0) 
    cout << "Thereshold:" << threshold << "\n";
  if (this->verbose) {
    tabs(g);
    cout << "g=" << g;
    s.printState(); cout << "\n";
  }
  if (h == 0) {
      solution.resize(g+1);
      solution[g] = s;
      return 1;
  }
  if (g == this->threshold)
    return 0;
  for (i = 0; i < d.bf(s); i++) {
    Move move = d.getMove(i);
    d.makeMove(s, move);
    if (this->df(d, s, g+1)) {
      d.unmakeMove(s, move);
      solution[g] = s;
      return 1;
    }
    d.unmakeMove(s, move);
  }
  return 0;
}

template <class Domain, class State, class Move>
void Alg<Domain, State, Move>::ida(Domain &d, State &s) {
  int i;
  this->threshold = 0;
  while (!this->df(d, s, 0)) threshold++; 

  for (i = 0; i <= threshold; i++) {
    cout << i << ".";
    solution[i].printState();
    cout << "\n";
    //if (i < threshold - 1) printf("->");
  }
}

int main(int argc, char **argv) {
  Pancake d = Pancake();
  int myInstance[] = {0,5,4,7,2,6,1,3};
  PancakeState s(8, myInstance);
  s.printState(); cout << "\n";
  Alg<Pancake, PancakeState, PancakeMove> *alg = new Alg<Pancake, PancakeState, PancakeMove>();
  //alg->verbose = true;
  alg->ida(d, s);
  cout << nCalls < "calls to heuristic()";
  delete alg;
  return 0;
}
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
静态int df_输出=0;
int-nCalls=0;
煎饼州{
公众:
煎饼国(国际n):n(n),煎饼(n)
{
}
煎饼状态(int n,int*v):n(n),煎饼(n)
{
对于(int i=0;in-1)
cout n*sizeof(int));
-memcpy(res->pancakes,this->pancakes,
-这个->n*sizeof(int));
-返回res;
-}
-
void PancakeState::printState(){
int i;
cout n=n;}
+煎饼运动(intn):n(n){
int n;
};
班级煎饼{
公众:
int启发式(煎饼状态&);
-int bf(煎饼州&);
-PancakeMove*getMove(int);
+int bf(煎饼州&);
+薄煎饼移动getMove(int);
void makeMove(PancakeState&,PancakeMove&);
无效取消移动(PancakeState和PancakeMove和);
};
-内部煎饼::bf(煎饼州和南部){
+内部煎饼::bf(煎饼州和南部){
返回序列号-1;
}
-PancakeMove*Pancake::getMove(inti){
-返回新的煎饼移动(i+2);
+PancakeMove Pancake::getMove(inti){
+返回煎饼移动(i+2);
}
//烤饼
@@ -91,7 +94,7 @@
样板
类Alg{
公众:
-国家**解决方案;
+向量解;
int阈值;
冗长的;
int df(域与d、州与s、int g);
@@ -102,30 +105,28 @@
int Alg::df(域与d、状态与s、int g){
int h=d.启发式,i;
如果(g==0)

-难道我们不打算浏览成百上千行的代码吗?尝试使用探查器来识别特定的瓶颈,然后根据这些瓶颈创建简化的代码示例。您是否尝试过RAAI(基于堆栈的分配)而不是自制的
new()
/
删除
内存管理?使用哪种编译器,使用哪种编译器