C++ 性能提升C++;

C++ 性能提升C++;,c++,performance,algorithm,memory,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; Vecto

下面是我的代码

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方法数百万次时,4GB的内存分配非常多。在我的原始代码A,B,。。。结构的总大小接近200-300字节,当我调用GetFromFile方法20.000.000次时,我可以清楚地看到有5GB的内存分配。为什么?当方法完成时,是否不能从内存中释放结构A和B?它们不是指针,因此我无法手动删除

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

我不知道是否可以避免使用if语句,但如果这只是对bool变量的检查,那么它对性能没有多大影响。通过仅在需要的范围内声明
a
b
,可以在一定程度上提高性能

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;
}
如果您有内存泄漏,那就在代码的其他地方,因为这段代码不应该泄漏。当然,您的代码包含很多语法错误,但我想这只是您在这里键入的内容。

首先,在

pcmVertices[i].Position = reader->GetPoint()->GetPosition()->GetD3DXVECTOR3();
…调用
GetPoint()
,它返回一个新的动态分配对象,但不保留对用于
删除它的指针的引用。如果你说从

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)
…这确保当PCMVerties超出范围时,
VertexPosCoLF
析构函数运行,然后按中所述进行初始化

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);
}

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

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

在LoaderA和LoaderB的构造函数中 预加载P数组(结构P似乎等于A)和B数组中的所有内容

现在创建一种工厂

   PLoaderIntetface GetLoader(string filename);

其中,根据您的文件类型,您可以根据类型或其他类型进行分配

此代码无法编译。这里没有分配。结构A和P是相同的。所有这些看起来都有点奇怪…没有必要编译,是吗?所有代码都只是一个示例。如果不清楚或有任何其他问题,我可以进一步解释我的问题。@Cahit Burak Küçkuksütcü:你真的想发布一个重现问题的帖子,特别是当我们谈论性能时。如果我们甚至不能运行它,我们也帮不上忙。这就像在出了问题时,把你汽车的塑料模型交给机修工,而不是交给你的实际汽车。好吧,彼得森修复了你的编译错误。。。您可以编写两个函数:GetFromFileA和GetFromFileB。测试文件\u被格式化一次,然后调用GetFromFileA或GetFromFileB百万次。数百万次调用
开关
不太可能成为性能瓶颈(与数百万次调用
新建
相比)。现代CPU非常擅长预测分支,尤其是当它们以相同的方式连续运行数百万次时。一如既往,评测是唯一可以确定的方法。谢谢你的回答,我很快就会回来。好的。我理解并解决了我的内存问题,但为什么Point3的析构函数没有在这里运行:pcmVertices[I].Position=reader->GetPoint()->GetPosition()->GetD3DXVECTOR3();
new
的目的是返回比返回它的函数调用更长的内存。。。这就是为什么不会调用析构函数,也不会释放内存。我的建议是尽量避免
new
,使用标准容器并按值返回,除非性能迫使您这样做,如果您有boost或C++11.Ok,则使用智能指针(unique_ptr、shared_ptr、weak_ptr)。这些答案真的帮助了我。我想我需要做一些关于C++的练习。我知道指针是什么,但实际上我很困惑。@CahitBurakKüçkuksütcü:我认为这可能会在中期为你节省时间和悲伤。祝你好运顺便说一句,我必须选择哪一个。Windows API如Get(point3*p)或point3 Get()?我知道第一个用于获取多个值。还有其他问题吗?
 class PLoaderInterface 
 {
      virtual P GetFromFile();
 }
   PLoaderIntetface GetLoader(string filename);