性能提升C ++

时间:2013-07-16 14:46:16

标签: c++ performance algorithm memory

以下是我的代码。

Point3* LASReader::GetPoint(int index)
{
    if (m_index == m_header.NPointRecords)
        return 0;

stream.seekg(GetOffset(index));
m_index++;

LASPOINTF1 p0;
LASPOINTF1 p1;
LASPOINTF2 p2;
LASPOINTF3 p3;
LASPOINTF4 p4;
LASPOINTF5 p5;
Vector3 position;

// Get the point values
switch (m_header.PointDataFormat)
{
case 0:
    stream.read((char *)&p0, sizeof(LASPOINTF0));
    position = Vector3(p0.X, p0.Y, p0.Z);
    break;
case 1:
    stream.read((char *)&p1, sizeof(LASPOINTF1));
    position = Vector3(p1.X, p1.Y, p1.Z);
    break;
case 2:
    stream.read((char *)&p2, sizeof(LASPOINTF2));
    position = Vector3(p2.X, p2.Y, p2.Z);
    break;
case 3:
    stream.read((char *)&p3, sizeof(LASPOINTF3));
    position = Vector3(p3.X, p3.Y, p3.Z);
    break;
case 4:
    stream.read((char *)&p4, sizeof(LASPOINTF4));
    position = Vector3(p4.X, p4.Y, p4.Z);
    break;
case 5:
    stream.read((char *)&p5, sizeof(LASPOINTF5));
    position = Vector3(p5.X, p5.Y, p5.Z);
    break;
}


// Calculate the real coordinates of the point
position = position * *m_scale + *m_offset;

return new Point3(position.GetX(), position.GetY(), position.GetZ());
}

// Main

int main()
{
    VertexPosColF* pcmVertices = new VertexPosColF[reader->GetHeader().NPointRecords];
    while (!reader->AllPointsRead())
{
    pcmVertices[i].Position = reader->GetPoint()->GetPosition()->GetD3DXVECTOR3();
    pcmVertices[i].Color = D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f);
    i++;
}
}

这是我的问题。我正在使用像GetFromFile()这样的方法读取文件(我知道这还不够,但它只是一个样本),也许我称之为数百万次,所以if else条件运行了数百万次。我想在调用方法之前调用一次。我该如何处理不同的类型?我认为开关盒块不能被调用数百万次。

我的第二个问题是当我调用GetFromFile方法数百万次时,有大量内存分配大约4gbs。在我的原始代码A,B,...结构的总大小接近200-300字节,当我调用GetFromFile方法20.000.000次时,我可以清楚地看到有5GB的内存分配。为什么?当方法结束时,结构A a和B b是否必须不从内存中释放?它们不是指针,因此我无法手动删除。

这是一个包含使用DirectX渲染的点云的las文件。 编辑:更新的代码和说明

3 个答案:

答案 0 :(得分:2)

首先,在......

pcmVertices[i].Position = reader->GetPoint()->GetPosition()->GetD3DXVECTOR3();

...你调用GetPoint()会返回一个新动态分配的对象,但是你没有引用指向delete的指针。如果你说改变...

Point3* LASReader::GetPoint(int index)

... ......的任何一个......

Point3 LASReader::GetPoint(int index)  // ALSO remove "new" from GetPoint's return

std::unique_ptr<Point3> LASReader::GetPoint(int index)

......内存释放将相对有效地处理自己。除非GetD3DXVECTOR3返回引用或指向Point3对象内任何内容的指针...如果是这种情况,那么最好保持对象不停 - 首先从GetPoint保存指针

pcmVertices更改为...

也是更典型的C ++
std::vector<VertexPosColF> pcmVertices(reader->GetHeader().NPointRecords);

...确保在VertexPosCoLF超出范围时运行pcmVertices析构函数,然后初始化为...

for (int i = 0; !reader->AllPointsRead(); ++i)
{
    VertexPosColF v;
    v.Position = reader->GetPoint()->GetPosition()->GetD3DXVECTOR3();
    v.Color = D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f);
    pcmVertices.push_back(v);
}

答案 1 :(得分:1)

如果您可以将您的方法作为对象的成员,您可以执行类似的操作(伪代码)

 class PLoaderInterface 
 {
      virtual P GetFromFile();
 }

基于该接口创建2个类LoaderA和LoaderB

在LoaderA和LoaderB的构造函数中 预加载P的数组中的所有内容(struct P看起来等于A)和B

的数组

现在创建一种工厂

   PLoaderIntetface GetLoader(string filename);

根据您的文件类型,您在类型或其他类型上分配!

答案 2 :(得分:0)

我不知道你是否可以避免if语句,但如果只是检查一个bool变量,那么它对性能没有太大影响。您可以通过仅在需要的范围内声明ab来稍微提高性能。

P GetFromFile()
{
   P p;

   if(file_is_A_formatted) {
      A a;
      stream.read((char*)&a, sizeof(A));
      p.x = a.x;
      p.y = a.y;
   }
   else {
      B b;
      stream.read((char*)&b, sizeof(B));
      p.x = b.x;
      p.y = b.y + b.z;
   }

  return p;
}

如果你有内存泄漏,那就是代码中的其他地方,因为这段代码不应泄漏。当然你的代码包含很多语法错误,但我想这只是你输入的内容。