2014-01-22 6 views
0

У меня проблема, как эффективно вернуть большой двумерный вектор из функции. Моя задача - прочитать большой файл и вернуть данные матрицы.Эффективный возврат двухмерного вектора

Дизайн один:

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 

Мне просто интересно, если есть способ решить эту проблему.

+1

Почему вы говорите, что это не эффективно? Вы профилировались с оптимизацией? –

+0

Во-первых, _do not_ возвращает ссылку на локальный объект (это неэффективно, это UB). Во-вторых, если ваш компилятор поддерживает C++ 11, верните его значение. В противном случае подумайте об использовании трюка подкачки. В любом случае, профиль профиля профиля (до оптимизации и после оптимизации). – utnapistim

+2

С C++ 11 первый, скорее всего, будет * перемещен * и не скопирован. Для второго варианта существует риск неопределенного поведения (если вы возвращаете ссылку на локальную переменную). –

ответ

3

Ваш первый, если вектор создан внутри функции, на самом деле является неопределенным поведением. Если вектор создается внутри функции вы можете просто вернуть его, как это:

std::vector<std::vector<double> > loadMatrix(const char* fileName){ 
    std::vector<std::vector<double> > matrix; 
    //read file 
    return matrix; 
} 

Объект matrix будет перемещен (или копия будет опущены), благодаря оптимизации (возвращаемое значение) в RVO.

0

Своп трюк предполагает обмен значений вместо задания, когда вы можете позволить себе сделать разрушительную копию:

исходный код:

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 для получения значения без какой-либо глубокой копии или перераспределения.

The swap trick - быстрое решение для возврата к значению перед семантикой перемещения C++ 11.

0

Так же, как возможность, если ваш компилятор не поддерживает перемещение семантики, вы можете также инициализировать вы матрицу в этой функции:

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 
} 

В этом случае не будет выполнена не матрица копии.

Смежные вопросы