【发布时间】:2021-01-10 23:01:49
【问题描述】:
因此,为了提高效率,我需要手动处理 std::vector 分配的内存。而且我注意到我的程序比预期的要慢,所以我在我的代码库中到处添加了这个习语:
const uint new_edges_capacity = mesh.edges.size() + 6;
if(new_edges_capacity > mesh.edges.capacity())
mesh.edges.reserve(new_edges_capacity * 2);
原来我只是在做:
const uint new_edges_capacity = mesh.edges.size() + 6;
mesh.edges.reserve(new_edges_capacity * 2);
嗯,第一个 sn-p 比第二个快几个数量级。
我不明白,官方文档似乎表明储备应该已经在做同样的检查。但是,perf 绝对将 std::reserve 标记为我的代码中最昂贵的操作,并且确实修改表明不调用 reserve 并依赖它来检查分配更快。
我使用此模式的函数示例:
template<typename V>
void HMesh<V>::SplitFace(uint face_id, HMesh<V>& mesh)
{
mesh.vertex_data.push_back({});
mesh.verts.push_back({&mesh});
HMesh<V>::MVert& c = mesh.verts.back();
const uint new_edges_capacity = mesh.edges.size() + 6;
if(new_edges_capacity > mesh.edges.capacity())
mesh.edges.reserve(new_edges_capacity * 2);
mesh.edges.push_back({&mesh});
HMesh<V>::MEdge& n00 = mesh.edges.back();
mesh.edges.push_back({&mesh});
HMesh<V>::MEdge& n01 = mesh.edges.back();
mesh.edges.push_back({&mesh});
HMesh<V>::MEdge& n10 = mesh.edges.back();
mesh.edges.push_back({&mesh});
HMesh<V>::MEdge& n11 = mesh.edges.back();
mesh.edges.push_back({&mesh});
HMesh<V>::MEdge& n20 = mesh.edges.back();
mesh.edges.push_back({&mesh});
HMesh<V>::MEdge& n21 = mesh.edges.back();
const uint new_faces_capacity = mesh.faces.size() + 2;
if(new_faces_capacity > mesh.faces.capacity())
mesh.faces.reserve(new_faces_capacity * 2);
mesh.faces.push_back({&mesh});
HMesh<V>::MFace& f1 = mesh.faces.back();
mesh.faces.push_back({&mesh});
HMesh<V>::MFace& f2 = mesh.faces.back();
auto& face = mesh.faces[face_id];
HMesh<V>::MFace& f0 = face;
HMesh<V>::MEdge& e0 = face.EdgeD();
HMesh<V>::MEdge& e1 = face.EdgeD().NextD();
HMesh<V>::MEdge& e2 = face.EdgeD().PrevD();
HMesh<V>::MVert& v0 = e0.VertD();
HMesh<V>::MVert& v1 = e1.VertD();
HMesh<V>::MVert& v2 = e2.VertD();
ConnectFace(f0, n00, e0, n10);
ConnectFace(f1, n11, e1, n21);
ConnectFace(f2, n20, e2, n01);
Pair(n00, n01);
Pair(n10, n11);
Pair(n20, n21);
AttachVertices(n00, c, v0);
AttachVertices(n11, c, v1);
AttachVertices(n20, c, v2);
c.Data({
(v0.Data().position + v1.Data().position + v2.Data().position) / 3.0,
(v0.Data().uv + v1.Data().uv + v2.Data().uv) / 3.0,
{0,0,1}
});
}
【问题讨论】:
-
没有优化的 Gcc(由于调试原因)
-
第一个装满后会加倍。您的第二个可能会在每次运行时添加 2 个元素。你的第二个做了更多的保留。
-
reserve检查是否为new_edges_capacity * 2 > capacity(),但您正在检查new_edges_capacity > capacity()。没有优化的时间也是没有意义的 -
对数千个数据点进行线性运算的时序并非毫无意义。以防万一,此更改使代码数量级更快。
-
但我也认为你的评论是我的问题。