Перемещение с помощью вектора :: push_back

17

Предположим, что у меня есть следующий код:

#include <vector>
struct A {
    int a;
    int x;
};
int main() {
    using namespace std;
    A a1;
    A a2;
    vector<A> va;
    va.push_back(a1);
    va.push_back(move(a2));
}

Мне известно, что элементы std :: vector хранятся смежно, в отличие от std :: list. В приведенном выше коде a2 перемещается, но действительно ли нет копирования a2 в вектор va ? В чем разница между va.push_back(a2); и va.push_back(move(a2)); ?

    
задан ggg 20.07.2012 в 05:57
источник

3 ответа

25

В вашем случае нет эффективной разницы, поскольку вы используете конструкторы копирования, предоставленные компилятором. Вы увидите заметную разницу в производительности при использовании объектов, которые могут быть построены с возможностью перемещения, и приложите много усилий для копирования. В этом случае использование push_back(x) создаст копию объекта, а push_back(move(x)) скажет push_back() , что он может «украсть» содержимое x , оставив x в непригодном и неопределенном состоянии.

Учтите, если у вас есть вектор списков ( std::vector<std::list<int> > ), и вы хотите нажать список, содержащий 100 000 элементов. Без move() будет скопирована вся структура списка и все 100 000 элементов. С move() некоторые указатели и другие мелкие биты данных перетасовываются, и это все. Это будет намного быстрее и потребует меньше общего объема памяти.

    
ответ дан cdhowie 20.07.2012 в 06:03
источник
14

При использовании va.push_back(a2) версии будет вызываться vector<T>::push_back(const T&) , когда вы будете использовать va.push_back(move(a2)) version vector<T>::push_back(T&&) будет вызываться ...

Но в вашем случае нет разницы в производительности, поскольку

  

15 Неявно заданный конструктор копирования / перемещения для неединичного класса   X выполняет частичную копию / перемещение своих оснований и членов.

Пункт 12.8 проект n3337.

    
ответ дан ForEveR 20.07.2012 в 05:59
источник
0

Я хочу отметить то, что другие ответы не прошли; заключается в том, что ?.push_back(move(?)) будет медленнее, чем ?.push_back(?) в вашем случае (когда у вас есть объекты с возможностью трехмерного копирования), потому что для перемещения конструктора необходимо установить нуль \ set перемещенный объект, который эффективно вы пишете \ копируете два объекта.

    
ответ дан LyingOnTheSky 19.11.2016 в 18:10
источник

Раскрывающаяся папка с использованием javascript onchange

___ taggcc ___ GCC - это сборник компиляторов GNU. Это де-факто стандартный компилятор C на Linux и поддерживает многие другие языки и платформы. ___ ___ Является ли qstnhdr Googles GOLANG интерпретатор или компилятор? ___ qstntxt ___

Я изучаю Golang, и вижу, что у него есть компилятор. Но компилирует ли он код уровня сборки или просто преобразует его в BYTECODES, а затем вызывает эту компиляцию? Я имею в виду, что даже в PHP мы можем преобразовать его в BYTECODES и иметь более высокую производительность. Является ли golang ЗАМЕНА для программирования и компиляции системного уровня?

    
___ tagystem ___ Система может ссылаться на набор взаимозависимых компонентов; Инфраструктура низкого уровня, такая как операционная система (с высокой языковой точки зрения) или объект или функция для доступа к предыдущей ___ answer12249365 ___

Это действительно компилятор (на самом деле он содержит 2 компилятора), и он делает полностью самостоятельные исполняемые файлы. Вам не нужна никакая дополнительная библиотека или какая-либо среда выполнения для ее выполнения на вашем сервере. Вам просто нужно скомпилировать его для вашей целевой компьютерной архитектуры.

Из документации :

  

Существуют две официальные цепочки инструментов компилятора Go. Этот документ фокусируется   на компилятор gc Go и инструменты (6g, 8g и т. д.). Информацию о том, как   для работы с gccgo, более традиционным компилятором, использующим задний конец GCC,   см. Настройка и использование gccgo.

     

Компиляторы Go поддерживают три набора инструкций. Существуют важные   различия в качестве компиляторов для разных   архитектуры.

     

amd64 (a.k.a. x86-64); 6g, 6l, 6c, 6a   Зрелая реализация.   компилятор имеет эффективный оптимизатор (регистратор) и генерирует хорошие   кода (хотя иногда gccgo может заметно улучшить).

     

386 (a.k.a. x86 или x86-32); 8g, 8л, 8с, 8а   Сравнение с портом amd64.

     

arm (a.k.a. ARM); 5g, 5l, 5c, 5a   Поддерживает только двоичные файлы Linux. Менее широко используется, чем   другие порты и, следовательно, не прошли тщательную проверку.

     

За исключением   такие как код интерфейса операционной системы низкого уровня, время выполнения   поддержка одинакова во всех портах и ​​включает мусор маркировки и разметки   коллектора, эффективного массива и нарезки строк и поддержки для   эффективные горуты, такие как стеки, которые растут и сокращаются по требованию.

     

Компиляторы могут ориентироваться на FreeBSD, Linux, NetBSD, OpenBSD, OS X   (Darwin) и операционных систем Windows. Полный набор поддерживаемых   комбинации перечислены в обсуждении переменных среды   ниже.

На сервере вы обычно будете нацеливаться на платформу %code% .

Заметим, что Go хорошо известен скоростью компиляции. При развертывании моих серверных программ я не создаю для разных платформ на компьютере разработки: я развертываю источники и компилирую непосредственно на производственных серверах. Начиная с Go1, у меня никогда не было компиляции кода на одной платформе, а не для компиляции на других.

В Windows у меня не возникло проблем с созданием %code% на моем компьютере разработки и просто отправкой этого %code% людям, которые никогда не устанавливали ничего связанных с Go.

    
___ taggo ___ Go - это язык программирования с открытым исходным кодом, первоначально разработанный в Google. Он статически типизирован с синтаксисом, слабо полученным из C, добавляя автоматическое управление памятью, безопасность типов, некоторые возможности динамического ввода, дополнительные встроенные типы, такие как массивы переменной длины и карты значений ключа, и большую стандартную библиотеку. ___