Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.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++_Vector - Fatal编程技术网

C++ 返回向量元素的副本与返回指向向量元素的指针

C++ 返回向量元素的副本与返回指向向量元素的指针,c++,vector,C++,Vector,我有一个这样的物体: class Node { float x, y, z; size_t tag; bool isFree; std::vector<size_t> connections; // Usually ~10-100 in length }; 类节点{ 浮动x,y,z; 尺寸标签; 布尔是免费的; std::vector connections;//长度通常约为10-100 }; 只是给你一个尺寸的概念。有一个包含数百万实例的节点对象

我有一个这样的物体:

class Node {
    float x, y, z;
    size_t tag;
    bool isFree;
    std::vector<size_t> connections; // Usually ~10-100 in length
};
类节点{
浮动x,y,z;
尺寸标签;
布尔是免费的;
std::vector connections;//长度通常约为10-100
};
只是给你一个尺寸的概念。有一个包含数百万实例的节点对象列表,我将其称为
std::vector masterNodes
。我在其他地方有一个函数,返回这些对象的容器,例如:

std::vector<Node> find_nodes()
{
    std::vector<Node> nodes;
    // copy some elements from masterNodes that meet our conditions
    return nodes;
}
std::vector find_nodes()
{
std::向量节点;
//从主节点复制一些符合我们条件的元素
返回节点;
}
我的问题是,返回Node*向量会更有效,还是我的编译器会对此进行足够的优化,以使像我这样的对象的增益最小?例如

std::vector<Node*> find_nodes()
{
    std::vector<Node*> nodes;
    // point to some elements from masterNodes that meet our conditions
    return nodes;
}
std::vector find_nodes()
{
std::向量节点;
//指向masterNodes中满足我们条件的一些元素
返回节点;
}

我已经看到一些回复(比如)表明拷贝可能和返回指针一样有效,承认返回指向向量元素的指针的危险

返回
节点*
的向量会更有效,因为
节点
主节点
节点
副本的向量,而
节点
比指针大得多。没有什么比返回值优化或移动语义更有用的了,因为您拥有(并返回)一个拷贝向量


顺便说一句,您可以返回
向量
,而不是
向量
。它与
节点*
一样高效,至少在发布版本中是如此,但在调试版本中通常有一些集成检查,这可能会有所帮助。

当您使用
std::vector
作为方法返回时,会复制所有数据,这需要时间。 使用
std::vector
只允许您拥有数据的地址,而不会进行复制。但是,如果使用此选项,则必须小心修改数据,因为修改是在主节点中进行的

根据参考,您应该尝试算法:

实际上,std::copy的实现避免了多次赋值,并使用了批量复制函数,例如值类型为

您可以使您的
节点
实现与要考虑的要求相匹配可复制(使用std::array,而不是std::vector进行连接),因此如果使用
std::copy\u应该非常快

另一方面,复制节点受到内存的限制,如果没有足够的内存,可能会出现内存不足错误,如果您确定永远不会返回超过100个节点,那么,您可以控制此操作

如果使用指针,应用程序将不得不管理内存,这将减少使用的内存数量,但会缩短内存管理所需的时间

但是,您将得到的最佳答案是测试两个选项。

参考位置 现实生活中的性能在很大程度上取决于硬件,如果您知道如何使用它,可以获得很多

当利用参考位置时,可以获得最大的硬件性能增益之一。这意味着,无论是在时间还是空间上,处理距离很近的数据都可以更好地利用内置的CPU缓存,这比使用主内存(RAM)快得多

这就是为什么复制数据以允许连续的本地访问可以提高性能的原因

与此相反的是使用间接寻址。间接寻址是使用引用或指针而不是值本身访问内存的能力。这允许您避免复制内容,但当硬件必须始终从主内存中的不同位置获取每一位数据时,您无法充分利用CPU缓存

必须测试性能 基本上,复制大型内容会导致一次性性能损失,但如果您大量使用数据,您可以使用引用的位置来弥补这一损失


但是,您必须自己测试它,以了解什么最适合您。在您的情况下,复制数据的成本可能会带来比更好地使用CPU缓存所能弥补的更大的性能损失。

如果每个
节点
都有一个可能包含100个元素的
std::vector
,并且您有一个
std::vector
,那么肯定会比
std::vector
大得多。只要确保你知道谁应该管理内存,这样你就不会泄漏内存,也不会抓住悬空的指针。很可能对象的向量会更有效率。但如果这很重要的话,您应该同时尝试这两种方法并查看(但在您的基准测试中包括第二个版本所需的潜在内存管理)。我认为,另一种选择是返回索引。但这将我与一个向量联系起来,这意味着我必须将索引引用回主节点。不过,这并不是一个完全没有吸引力的想法,因为索引也属于问题领域,而不仅仅是实现。节点有索引。我认为“返回”在这里并不相关。从masterNodes复制节点是这里真正的问题。一旦拷贝完成,返回应该非常有效(感谢RVO)。RVO可以应用,并将使返回非常有效。但是当
find_nodes()
中的复制本身很慢时,我们不关心快速返回。您如何处理从
find_nodes()中检索到的节点向量?这是确定您的问题最合适解决方案的一个重要细节。对不起,我想在问题中承认这一点。
find_nodes()
返回的大小远小于调用
find_nodes()
的次数。例如,将按主节点的大小顺序调用find_nodes()