Re[13]: Visual C# vs C++. Надо сравнить перспективы.
От: alex_public  
Дата: 09.01.17 09:12
Оценка:
Здравствуйте, lpd, Вы писали:

_>>
_>>auto make_object(int p)
_>>{
_>>    if(p<0) return big_object();
_>>    big_object obj(p);
_>>    prepare(obj);
_>>    return obj;
_>>}
_>>auto obj=make_object(1024);
_>>

_>>Вот прямо в таком коде будет работать семантика перемещения (если конечно у big_object определены соответствующие методы). А теперь покажи свой более простой вариант, только чтобы он тоже был без копирования... )
lpd>Честно говоря, я не понял, какой в данном случае метод нужно объявить у big_object, чтобы он стал rvalue-ссылкой.

Естественно конструктор перемещение. Т.е. банально добавить в класс big_object метод "big_object(big_object&& о) {}" и всё, семантика перемещения заработает для данного классса.

lpd>Нужно вызвать move и вернуть big_object &&.


Нет, никаких move не требуется, компилятор сам всё сделает для return. Да, и кстати если убрать auto в моём коде, то на его месте будет просто big_object, без всяких ссылок. Никакие rvalue ссылки в самом коде использовать не надо, в этом и смысл данной техники — работаем со всеми объектами (включая и тяжёлые) просто как с обычными int'ми. )))

lpd>Но ты привел типичный случай, который решается элементарно:

lpd>
lpd>big_object *make_object(int p)
lpd>{
lpd>    if (p<0) return new big_object;
lpd>    big_object *obj = new big_object(p);
lpd>    prepare(obj);
lpd>    return obj;
lpd>}
lpd>big_object *obj=make_object(1024);
lpd>...
lpd>delete obj;
lpd>


Ну так и какой код выглядит сложнее и объёмнее, мой или твой? ) Ты же заявлял, что код с применением семантики перемещения существенно усложняется...

lpd>Я не понимаю, это что, из управляемых языков пошло, что "всех new и delete нужно исключить"? В случае с move-семантикой вызывающий код получает локальный объект на стеке(?), который обречен быть локальным. В случае с указателем, его можно отдать разным обработчикам.


Вообще то это как раз в управляемых языках сплошные new (и неявные фоновые delete), которые и вызывают значительную часть тормозов языка. Вследствие введения дополнительного уровня косвенности, который не даёт нормально работать кэшу процессора. А как раз в современном C++ уходят от всего этого в сторону использования локальных переменных на стеке, которые являются самым эффективным инструментом. Да, а семантика перемещения как раз полностью решает проблему с передачей этого "локального" объекта куда-то ещё.

lpd>>>Давай конкретно: вот можешь описать случай с примером приложения и объекта, когда (бы) ты использовал move-семантику? хоть один?

_>>Вообще то там миллион сценариев. Более того, частенько даже древний код можно существенно ускорить без переписывания, если подключить (перекомпилировать с опцией C++11 или старше) ему семантику перемещения. Но если ты хочешь, то я покажу самый банальный пример с явным вызовом:
_>>
_>>vector<big_object> vec;
_>>big_object obj;
_>>prepare(obj);
_>>vec.push_back(move(obj));
_>>

lpd>Такое всегда решалось динамическим созданием объекта и записью указателя в вектор. В твоем случае при реаллокации вектора все большие объекты будут копироваться. И опять же, на мой взгляд указатель удобнее для дальнейшей работы(нескольких обращений к нему без копирования).

И именно такой подход существенно убивает производительность, т.к. добавляет лишний уровень косвенности.

P.S. Ты только не обижайся, но что-то ты сейчас демонстрируешь отсутствие целого набора базовых знаний (и современного стандарта языка и вопросов оптимизации под современные процессоры), необходимых для хорошего специалиста по C++.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.