高效返回二维向量
Posted
技术标签:
【中文标题】高效返回二维向量【英文标题】:Return two dimensional vector efficiently 【发布时间】:2014-01-22 09:32:33 【问题描述】:我有一个问题,如何从函数中有效地返回一个大的二维向量。 我的任务是读取一个大文件并返回一个矩阵数据。
设计一:
std::vector<std::vector<double> > loadMatrix(const char* fileName)
//read file
return matrix;
这个效率不高。
设计二:
std::vector<std::vector<double> >& loadMatrix(const char* fileName)
//read file
return matrix;
//get some errors
我只是想知道有没有办法解决这个问题。
【问题讨论】:
为什么说效率不高?您是否对优化进行了分析? 首先,不要返回对本地对象的引用(不是低效,是UB)。其次,如果您的编译器支持 C++11,则按值返回。否则考虑使用交换技巧。无论哪种方式,配置文件配置文件(优化之前和优化之后)。 对于 C++11,第一个很可能会移动而不是复制。对于第二个变体,存在未定义行为的风险(如果您返回对局部变量的引用)。 还有第三种选择:将“矩阵”作为非常量引用参数传递给函数,并返回布尔成功/失败指示符。 @JoachimPileborg 我怀疑它会被移动。该副本很可能会被完全删除,因此无需移动任何内容。 【参考方案1】:如果向量是在函数中创建的,那么您的第一个实际上是未定义的行为。如果向量是在函数内部创建的,您可以像这样简单地返回它:
std::vector<std::vector<double> > loadMatrix(const char* fileName)
std::vector<std::vector<double> > matrix;
//read file
return matrix;
感谢RVO(返回值优化),matrix
对象将被移动(或副本将被省略)。
【讨论】:
【参考方案2】:交换技巧涉及交换值而不是赋值,当您可以负担进行破坏性复制时:
原代码:
std::vector<std::vector<double> > loadMatrix(const char* fileName)
//read file
return matrix; // Uses RVO
// create copy of temporary object returned by loadMatrix
std::vector<std::vector<double> > result = loadMatrix("matrixfile");
交换技巧:
std::vector<std::vector<double> > result;
result.swap(loadMatrix("matrixfile"));
交换技巧将指针与临时指针交换。这将导致loadMatrix
返回的临时对象销毁一个空对象(在result
中默认构造的对象)并且result
接收该值而无需任何深度复制或重新分配。
交换技巧是在 C++11 移动语义之前按值返回的快速解决方案。
【讨论】:
【参考方案3】:顺便说一句,如果您的编译器不支持移动语义,您也可以在此函数中初始化矩阵:
bool loadMatrix(const char* fileName, std::vector<std::vector<double> > & matrix)
// shows if something went wrong
bool returnFlag = true;
// read file and init matrix
return returnFlag;
// create matrix
std::vector<std::vector<double> > matrix;
if (true == loadMatrix("matrixfile", matrix))
// do something
在这种情况下,不会执行矩阵复制。
【讨论】:
以上是关于高效返回二维向量的主要内容,如果未能解决你的问题,请参考以下文章