Сообщение Re[14]: Visual C# vs C++. Надо сравнить перспективы. от 09.01.2017 9:39
Изменено 09.01.2017 10:31 lpd
Re[14]: Visual C# vs C++. Надо сравнить перспективы.
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, lpd, Вы писали:
_>>>
_>Естественно конструктор перемещение. Т.е. банально добавить в класс big_object метод "big_object(big_object&& о) {}" и всё, семантика перемещения заработает для данного классса.
OK, move-конструктор. Тем не менее, я считаю, что с ними слишком запутанные правила. Я бы предпочел, чтобы по вызывающему коду было понятно, что тут move, и не требовалось каждый раз смотреть определение класса.
lpd>>Но ты привел типичный случай, который решается элементарно:
lpd>>
_>Ну так и какой код выглядит сложнее и объёмнее, мой или твой? ) Ты же заявлял, что код с применением семантики перемещения существенно усложняется...
Более короткий код не значит простой, кроме того:
lpd>>В случае с move-семантикой вызывающий код получает локальный объект на стеке(?), который обречен быть локальным. В случае с указателем, его можно отдать разным обработчикам.
_>Да, а семантика перемещения как раз полностью решает проблему с передачей этого "локального" объекта куда-то ещё.
Как передать этот локальный объект в другой поток? он на стеке и может быть уничтожен, пока другой поток будет еще выполняться. С указателем это делается легко и непринужденно.
lpd>>>>Давай конкретно: вот можешь описать случай с примером приложения и объекта, когда (бы) ты использовал move-семантику? хоть один?
_>>>Вообще то там миллион сценариев. Более того, частенько даже древний код можно существенно ускорить без переписывания, если подключить (перекомпилировать с опцией C++11 или старше) ему семантику перемещения. Но если ты хочешь, то я покажу самый банальный пример с явным вызовом:
_>>>
lpd>>Такое всегда решалось динамическим созданием объекта и записью указателя в вектор. В твоем случае при реаллокации вектора все большие объекты будут копироваться. И опять же, на мой взгляд указатель удобнее для дальнейшей работы(нескольких обращений к нему без копирования).
_>И именно такой подход существенно убивает производительность, т.к. добавляет лишний уровень косвенности.
Ты что, всерьез заботишься о времени разыменования указателя? оно ничтожно, а в тех очень редких случаях, где играет роль, пишут просто вставки на ассемблере. Или как такой подход убивает производительность?
Большие объекты в векторе лучше не хранить из-за реаллокации при изменении размера и фрагментации после eraseов. Поэтому и в этом случае указатели удобнее.
Так что все еще необходим пример(желательно конкретного приложения, т.к. big_object это обычно по сути массив для вычислений, и редко что-либо иное, что нежелательно копировать), в котором нужна move-семантика. На мой взгляд — обычный C++ это баланс производительностью и удобством, с возможностью ручного ассемблера.
_>Здравствуйте, 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 метод "big_object(big_object&& о) {}" и всё, семантика перемещения заработает для данного классса.
OK, move-конструктор. Тем не менее, я считаю, что с ними слишком запутанные правила. Я бы предпочел, чтобы по вызывающему коду было понятно, что тут move, и не требовалось каждый раз смотреть определение класса.
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>>В случае с move-семантикой вызывающий код получает локальный объект на стеке(?), который обречен быть локальным. В случае с указателем, его можно отдать разным обработчикам.
_>Да, а семантика перемещения как раз полностью решает проблему с передачей этого "локального" объекта куда-то ещё.
Как передать этот локальный объект в другой поток? он на стеке и может быть уничтожен, пока другой поток будет еще выполняться. С указателем это делается легко и непринужденно.
lpd>>>>Давай конкретно: вот можешь описать случай с примером приложения и объекта, когда (бы) ты использовал move-семантику? хоть один?
_>>>Вообще то там миллион сценариев. Более того, частенько даже древний код можно существенно ускорить без переписывания, если подключить (перекомпилировать с опцией C++11 или старше) ему семантику перемещения. Но если ты хочешь, то я покажу самый банальный пример с явным вызовом:
_>>>
_>>>vector<big_object> vec;
_>>>big_object obj;
_>>>prepare(obj);
_>>>vec.push_back(move(obj));
_>>>
lpd>>Такое всегда решалось динамическим созданием объекта и записью указателя в вектор. В твоем случае при реаллокации вектора все большие объекты будут копироваться. И опять же, на мой взгляд указатель удобнее для дальнейшей работы(нескольких обращений к нему без копирования).
_>И именно такой подход существенно убивает производительность, т.к. добавляет лишний уровень косвенности.
Ты что, всерьез заботишься о времени разыменования указателя? оно ничтожно, а в тех очень редких случаях, где играет роль, пишут просто вставки на ассемблере. Или как такой подход убивает производительность?
Большие объекты в векторе лучше не хранить из-за реаллокации при изменении размера и фрагментации после eraseов. Поэтому и в этом случае указатели удобнее.
Так что все еще необходим пример(желательно конкретного приложения, т.к. big_object это обычно по сути массив для вычислений, и редко что-либо иное, что нежелательно копировать), в котором нужна move-семантика. На мой взгляд — обычный C++ это баланс производительностью и удобством, с возможностью ручного ассемблера.
Re[14]: Visual C# vs C++. Надо сравнить перспективы.
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, lpd, Вы писали:
_>>>
_>Естественно конструктор перемещение. Т.е. банально добавить в класс big_object метод "big_object(big_object&& о) {}" и всё, семантика перемещения заработает для данного классса.
OK, move-конструктор. Тем не менее, я считаю, что с ними слишком запутанные правила. Я бы предпочел, чтобы по вызывающему коду было понятно, что тут move, и не требовалось каждый раз смотреть определение класса.
lpd>>Но ты привел типичный случай, который решается элементарно:
lpd>>
_>Ну так и какой код выглядит сложнее и объёмнее, мой или твой? ) Ты же заявлял, что код с применением семантики перемещения существенно усложняется...
Более короткий код не значит простой, кроме того:
lpd>>В случае с move-семантикой вызывающий код получает локальный объект на стеке(?), который обречен быть локальным. В случае с указателем, его можно отдать разным обработчикам.
_>Да, а семантика перемещения как раз полностью решает проблему с передачей этого "локального" объекта куда-то ещё.
Как передать этот локальный объект в другой поток? он на стеке и может быть уничтожен, пока другой поток будет еще выполняться. С указателем это делается легко и непринужденно.
lpd>>>>Давай конкретно: вот можешь описать случай с примером приложения и объекта, когда (бы) ты использовал move-семантику? хоть один?
_>>>Вообще то там миллион сценариев. Более того, частенько даже древний код можно существенно ускорить без переписывания, если подключить (перекомпилировать с опцией C++11 или старше) ему семантику перемещения. Но если ты хочешь, то я покажу самый банальный пример с явным вызовом:
_>>>
lpd>>Такое всегда решалось динамическим созданием объекта и записью указателя в вектор. В твоем случае при реаллокации вектора все большие объекты будут копироваться. И опять же, на мой взгляд указатель удобнее для дальнейшей работы(нескольких обращений к нему без копирования).
_>И именно такой подход существенно убивает производительность, т.к. добавляет лишний уровень косвенности.
Ты что, всерьез заботишься о времени разыменования указателя? оно ничтожно, а в тех очень редких случаях, где играет роль, пишут просто вставки на ассемблере. Или как такой подход убивает производительность?
Большие объекты в векторе лучше не хранить из-за реаллокации при изменении размера и фрагментации после eraseов. Поэтому и в этом случае указатели удобнее.
Так что все еще необходим пример(желательно конкретного приложения, т.к. big_object это обычно по сути массив для вычислений, и редко что-либо иное, что нежелательно копировать), в котором нужна move-семантика. На мой взгляд — обычный C++ это баланс производительностью, удобством и простотой, с возможностью ручного ассемблера. А с move-семантикой теряется простота. Кроме того, вот я когда то достаточно написал программ на ассемблере, и мне с моим опытом не очевидно, как move-семантика реализована. Компилятор резервирует место на стеке, выходит из функции, а когда стек возвращается к передвинутой локальной переменной, пропускает этот кусок памяти? или как?
_>Здравствуйте, 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 метод "big_object(big_object&& о) {}" и всё, семантика перемещения заработает для данного классса.
OK, move-конструктор. Тем не менее, я считаю, что с ними слишком запутанные правила. Я бы предпочел, чтобы по вызывающему коду было понятно, что тут move, и не требовалось каждый раз смотреть определение класса.
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>>В случае с move-семантикой вызывающий код получает локальный объект на стеке(?), который обречен быть локальным. В случае с указателем, его можно отдать разным обработчикам.
_>Да, а семантика перемещения как раз полностью решает проблему с передачей этого "локального" объекта куда-то ещё.
Как передать этот локальный объект в другой поток? он на стеке и может быть уничтожен, пока другой поток будет еще выполняться. С указателем это делается легко и непринужденно.
lpd>>>>Давай конкретно: вот можешь описать случай с примером приложения и объекта, когда (бы) ты использовал move-семантику? хоть один?
_>>>Вообще то там миллион сценариев. Более того, частенько даже древний код можно существенно ускорить без переписывания, если подключить (перекомпилировать с опцией C++11 или старше) ему семантику перемещения. Но если ты хочешь, то я покажу самый банальный пример с явным вызовом:
_>>>
_>>>vector<big_object> vec;
_>>>big_object obj;
_>>>prepare(obj);
_>>>vec.push_back(move(obj));
_>>>
lpd>>Такое всегда решалось динамическим созданием объекта и записью указателя в вектор. В твоем случае при реаллокации вектора все большие объекты будут копироваться. И опять же, на мой взгляд указатель удобнее для дальнейшей работы(нескольких обращений к нему без копирования).
_>И именно такой подход существенно убивает производительность, т.к. добавляет лишний уровень косвенности.
Ты что, всерьез заботишься о времени разыменования указателя? оно ничтожно, а в тех очень редких случаях, где играет роль, пишут просто вставки на ассемблере. Или как такой подход убивает производительность?
Большие объекты в векторе лучше не хранить из-за реаллокации при изменении размера и фрагментации после eraseов. Поэтому и в этом случае указатели удобнее.
Так что все еще необходим пример(желательно конкретного приложения, т.к. big_object это обычно по сути массив для вычислений, и редко что-либо иное, что нежелательно копировать), в котором нужна move-семантика. На мой взгляд — обычный C++ это баланс производительностью, удобством и простотой, с возможностью ручного ассемблера. А с move-семантикой теряется простота. Кроме того, вот я когда то достаточно написал программ на ассемблере, и мне с моим опытом не очевидно, как move-семантика реализована. Компилятор резервирует место на стеке, выходит из функции, а когда стек возвращается к передвинутой локальной переменной, пропускает этот кусок памяти? или как?