问题描述
我想知道如果返回一个列表,而不是返回一个指针,在性能上是昂贵的,因为如果我记得,一个列表没有很多属性(不是像3指针的东西?
I was wondering if returning a list, instead of returning a pointer to one, was costly in term of performance because if I recall, a list doesn't have a lot of attributes (isn't it something like 3 pointers? One for the current position, one for the beginning and one for the end?).
推荐答案
如果你返回一个 std :: list
按值,它不会只复制列表头,它将复制列表中每个项目一个列表节点。所以是的,对于一个大的列表是昂贵的。
If you return a std::list
by value it won't just copy the list head, it will copy one list node per item in the list. So yes, for a large list it is costly.
如果列表是建立在返回它的函数,那么你可能能够从命名返回值优化,以避免不必要的复制。这是特定于你的编译器,但。如果例如列表在调用函数之前已经存在(例如,它是一个对象的成员变量),它就永远不会应用。
If the list is built in the function which is returning it, then you might be able to benefit from the named return value optimisation, to avoid an unnecessary copy. That's specific to your compiler, though. It never applies if for example the list already existed before the function was called (for example if it's a member variable of an object).
在C ++中的常见习语避免按值返回容器,是将输出迭代器作为参数。因此,而不是:
A common idiom in C++, to avoid returning containers by value, is to take an output iterator as a parameter. So instead of:
std::list<int> getListOfInts() {
std::list<int> l;
for (int i = 0; i < 10; ++i) {
l.push_back(i);
}
return l;
}
您执行:
template<typename OutputIterator>
void getInts(OutputIterator out) {
for (int i = 0; i < 10; ++i) {
*(out++) = i;
}
}
然后调用者执行:
std::list<int> l;
getInts(std::back_inserter(l));
通常,一旦编译器完成内联和优化,代码或多或少相同。
Often once the compiler has finished inlining and optimising, the code is more or less identical.
这样做的好处是,调用者不会绑定到特定的集合 - 例如,他可以将项目添加到向量而不是列表,如果更有用的特殊情况。如果他只需要查看每个项目一次,而不是所有的项目,那么他可以通过使用他自己设计的输出迭代器以流模式处理它们来节省内存。
The advantage of this is that the caller isn't tied to a particular collection - for instance he can have the items added to a vector instead of a list if that is more useful for the particular circumstances. If he only needs to see each item once, instead of all of them together, then he can save memory by processing them in streaming mode using an output iterator of his own devising.
缺点是与任何模板代码相同:实现必须在编译时可用于调用程序,并且最终可能有很多重复对象代码为模板的多个实例化。当然,您可以使用相同的模式而不使用模板,通过将函数指针(如果需要,加上用户数据指针)作为参数,并对每个项调用一次,或者使用纯虚拟成员定义IntVisitor抽象类函数,并让调用者提供它的实例。
The disadvantages are the same as with any template code: the implementation must be available to the caller at compile time, and you can end up with a lot of "duplicate" object code for multiple instantiations of the template. Of course you can use the same pattern without using templates, by taking a function pointer (plus a user data pointer if desired) as a parameter and calling it once with each item, or by defining an IntVisitor abstract class, with a pure virtual member function, and having the caller provide an instance of it.
这篇关于返回一个std :: list昂贵吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!