2015-02-10 5 views
2

Мне хотелось бы узнать, есть ли более быстрый способ скопировать мои данные из mysqlpp :: storequeryresult в std :: vector.C++ mysqlpp :: storequeryresult и std :: vector

Мой пример выглядит следующим образом: Я сохраняю свой результат запроса с помощью query.store() в StoreQueryResult, и мой результат, например. стол с одним столбцом с удвоением в нем. Теперь я хочу скопировать эти двойники в std :: vector. То, как я делаю это прямо сейчас, - это получить доступ к каждому двойному с помощью оператора [] [] и скопировать его в мой вектор в цикле for.

Это работает, но это очень трудоемко, так как я копирую как 277000 двойных в цикле. Есть ли способ просто скопировать столбец в вектор? Дело в том, что мои другие функции используют std :: векторы в своих списках параметров. В качестве альтернативы я мог бы изменить свои функции, чтобы вызвать StoreQueryResult, я думаю, но я предпочел бы std :: vector.

Вот мой упрощенный код:

void foo() 
{ 
    vector<double> vec; 
    mysqlpp::StoreQueryResult sqr; 
    Query query; 
    query << "SELECT * FROM tablename"; 
    sqr = query.store(); 
    vec.reserve(sqr.num_rows()); 
    vec.resize(sqr.size()); 
     for(int i=0; i != vec.size(); i++) 
     { 
     vec[i] = sqr[i]["my_column"]; 
     } 
} 

Я хочу что-то вроде:

vec = sqr["my_column"] // when my_column is a field with doubles 

Thx заранее.

Martin

+0

Пожалуйста, подумайте над добавлением кода примера, что вы делаете. – tomvodi

+0

Вы резервируете этот целевой вектор до размера, эквивалентного количеству строк вашего SQR перед копией, не так ли? (* Введите код *). – WhozCraig

+0

Вправо вектор имеет тот же размер, что и количество строк StoreQueryResult. – Martin

ответ

0

В конце концов, если вам нужно скопировать, то вам необходимо скопировать, и писать ли вы Петля себя или получить библиотечную функцию, чтобы сделать это не особенно актуально.

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

vec.reserve(sqr.num_rows()); 
+0

Я попробую это. Посмотрите, помогает ли это. Я думал, что инициализация вектора с размером также означает выделение памяти для него ... Thx btw. – Martin

+0

@Martin: Да, это так - теперь, когда я вижу это в вашем коде (хотя я должен был догадаться из вашего использования 'vec [i]', а не 'vec.push_back'; whoops), это не происходит чтобы помочь вам! –

0

Вполне возможно, что вы хотите создать вектор, но только некоторые значения будут фактически доступны и будут использоваться.

В этом случае мы можем задержать переход от mysqlpp::String к другому типу данных:

std::vector<mysqlpp::String> data(res.num_rows()); 
for(size_t i=0, n=res.num_rows(); i<n; ++i) 
{ 
    data[i] = std::move(res[i]["value"]); 
} 

Некоторые вещи происходят здесь:

  1. Мы создаем vector, который хранит mysqlpp::String. Это интересный тип данных, который может быть преобразован во многие другие. В вашем случае вы использовали operator double() const.
  2. Мы получаем размер один раз, сохраняем его и затем используем это значение. Это микро-оптимизация, а также использование ++i, а не i++; они не содержат много циклов, но должны использоваться, чтобы сохранить код в духе оптимизации.
  3. Мы перемещаем данные, а не копируем их. См. std::move, если вы этого не встречали раньше.

Если тогда у вас есть что-то вроде:

double sum = 0.0; 
for(size_t i=0, n=data.num_rows(); i<n; i+=2) 
{ 
    sum+=double(data[i]); 
} 

Вы только запустить процедуру преобразования на ½ ваших ценностей.

Конечно, если вы планируете использовать результирующий вектор несколько раз, вы фактически начнете выполнять те же преобразования снова и снова. Таким образом, эта «оптимизация» действительно повредит производительности.

+0

MySQL ++ не поддерживает ходы, не так ли? В чем цель «std :: move» здесь? –

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