?

Log in

No account? Create an account

Previous Entry | Next Entry

Ответ на бнопню по C++

Код, который напрямую зовёт std::vector{std::move(foo)} на данных в ощущениях компиляторах (gcc, clang) будет медленнее, чем construct_vector(std::move(foo)), где:

std::vector construct_vector(Foo && foo) {
    std::vector vec;
    vec.emplace_back(std::move(foo));
    return vec;
}


Почему это так случается? Из-за отсутствия оптимизации std::initializer_list. Конструкция вектора через std::vector{} создаёт initializer_list, мувает в него один элемент foo, затем копирует из initializer_list внутрь вектора. К сожалению.

construct_vector же копированием foo не занимается, а делает move construction. Значение вектора попадает в место вызова без копирования, через RVO.

Ну вот так хреново пока работаем с std::initializer_list. В стандарте C14 про это вот что есть: "the underlying array is copy-initialized". Опаньки.

Типичный C++, что ни фича, то засада. JavaScript и то без копирования передавал бы всё :)

P.S. По поводу «почему C++» (mpd) — это было не моё решение. Нам и на Эрланге с сишными вставками неплохо работалось, правда, в сервис работал в десять раз медленнее. Но если у компании есть ресурсы и время на то, чтобы создать поддерживать в тонусе команду C++-програмистов, почему бы и нет? :)

Ключевой момент тут такой: если не заниматься байтодрочерством, C++ из-за подобных недофич (чуть что — копируем! ну или не смогли понять жизненный цикл — тоже на всякий случай скопируем) будет работать не сильно быстрее остальных дефолтных языков, а то и медленнее и/или глючнее. Только если действительно понимать, что происходит, можно выжрать нетривиальный буст по производительности, и, если повезёт, не сильно потерять в безопасности. Но это если такая производительность действительно нужна. На мобилке она, за редкими исключениями, вряд ли нужна. В датацентре (если это не cuda) — уже более интересное распределение. Разница между десятью нодами и сотней нод в плане управления — колоссальна. Между сотней и тысячью — уже речь встаёт о дешевизне датацентра по сравнению с рабочим временем программиста.

Если C++ на вашем продукте позволяет обеспечить эту разницу в 10x, есть средства на программистов и время на их реализацию, почему бы и нет? У нас в MZ — есть. Компания зарабатывает несколько миллионов долларов в день. А в вашем НИИГиТ наверняка нет ни таких средств, ни таких требований к производительности, которые бы требовали кластера из более чем десятка машин, а их оптимизация явно встанет зарплатой программистов дороже, чем выгода от их сокращения.

Comments

( 58 comments — Leave a comment )
spamsink
Oct. 4th, 2016 06:05 am (UTC)
На мобилке производительность очень даже нужна, потому что любая потеря в производительности - это потеря во времени жизни мобилки.
lionet
Oct. 4th, 2016 06:16 am (UTC)
Мобилка в основном тратит время, ожидая инпута, и жря батарейку на поджигание экрана или вещание через wifi. Количество циклов процессора, которое он тратит после того, как ты нажал пальцем на контрол, неважно. За исключением игр, ничего ты батарейке не сделаешь, оптимизируя свифт сиплюсплюсом.

Edited at 2016-10-04 06:16 am (UTC)
(no subject) - spamsink - Oct. 4th, 2016 06:27 am (UTC) - Expand
(no subject) - lionet - Oct. 4th, 2016 06:44 am (UTC) - Expand
(no subject) - spamsink - Oct. 4th, 2016 07:45 am (UTC) - Expand
(no subject) - lionet - Oct. 4th, 2016 08:02 am (UTC) - Expand
(no subject) - spamsink - Oct. 4th, 2016 08:07 am (UTC) - Expand
(no subject) - ostapru - Oct. 4th, 2016 02:25 pm (UTC) - Expand
(no subject) - vinslivins - Oct. 4th, 2016 03:31 pm (UTC) - Expand
(no subject) - vinslivins - Oct. 4th, 2016 03:34 pm (UTC) - Expand
(no subject) - yussouf - Oct. 6th, 2016 06:51 pm (UTC) - Expand
(no subject) - cd_riper - Oct. 4th, 2016 07:47 pm (UTC) - Expand
(no subject) - lionet - Oct. 4th, 2016 11:17 pm (UTC) - Expand
bik_top
Oct. 4th, 2016 06:34 am (UTC)
Жизненный цикл
> не смогли понять жизненный цикл — тоже на всякий случай скопируем

А что насчёт Rust?

> Типичный C++, что ни фича, то засада.

Type Inference is awesome.
lionet
Oct. 4th, 2016 06:46 am (UTC)
Re: Жизненный цикл
> А что насчёт Rust?

1. Я не настоящий сварщик.
2. Rust популярен в узких кругах, но мертв чуть менее, чем D.

> Type Inference is awesome.

Расскажите это Хиндли или Милнеру.
Re: Жизненный цикл - lionet - Oct. 4th, 2016 07:05 am (UTC) - Expand
Re: Жизненный цикл - mpd - Oct. 4th, 2016 07:44 am (UTC) - Expand
(no subject) - levgem - Oct. 4th, 2016 07:24 am (UTC) - Expand
(no subject) - enternet - Oct. 4th, 2016 11:57 am (UTC) - Expand
(no subject) - w0land - Oct. 9th, 2016 10:16 pm (UTC) - Expand
(no subject) - enternet - Oct. 10th, 2016 07:36 am (UTC) - Expand
Re: Жизненный цикл - mopexod - Oct. 4th, 2016 04:29 pm (UTC) - Expand
decltype(auto) - bik_top - Oct. 4th, 2016 06:03 pm (UTC) - Expand
dmzlj
Oct. 4th, 2016 07:05 am (UTC)
Но почему тогда не Си? В нём понимать надо значительно меньше.

Edited at 2016-10-04 07:05 am (UTC)
lionet
Oct. 4th, 2016 07:07 am (UTC)
1. Инлайнинга больше. Поэтому потенциал для ускорения гораздо больше. Ведь весь современный C++ происходит в заголовках, и инлайнится друг с другом, без стыда и зазрения.

2. Абстракции можно накрутить довольно приятные..
(no subject) - dmzlj - Oct. 4th, 2016 07:14 am (UTC) - Expand
levgem
Oct. 4th, 2016 07:25 am (UTC)
Ты какую-то бизнес-логику пишешь или обвязку? Как часто дедлоки или ливлоки хватаешь?
lionet
Oct. 4th, 2016 08:00 am (UTC)
Всё пишу (пишем). Практически никогда не хватаем дедлоков, потому что однотредовое: по треду на ядро. Минимум синхронизации.
mpd
Oct. 4th, 2016 08:34 am (UTC)
Re: «почему C++» (mpd) — это было не моё решение
Большое спасибо за отдельный ответ! Я уже думал, что - сознательно игнорируешь.

> Только если действительно понимать, что происходит

Вот, зря ты так говоришь!!!
Это же можно понять так, что ты популяризируешь идею что не надо ничего понимать, среда-компилятор-утилиты - всё за тебя решат! (и это говорит человек, который отключает подсветку в редакторе, чтобы держать всё в голове!!!)

Например, я - не знаю Erlang, Вики - это не всегда хорошо, но даже там пишут, что бездумно писать на этом языке - не совсем хорошо:

Эффективность

Как и многие другие языки программирования, Erlang имеет свои секреты написания эффективного кода. Совершенствование языка делает некоторые из трюков устаревшими, поэтому документация является лучшим руководством в вопросах оптимизации, в совокупности с профилированием и стресс-тестированием.

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

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

Или - ява, там есть сборка мусора. У меня есть друг, который умудрялся так писать сервлеты, что обслуживающий его сервер БД Оракл - замирал через пару часов после вывода веб-сайта с этими сервлетами в он-лайн. А отчего? Ну, он-то думал: ну, открою соединение при обработки страницы, обработка закончится - всё почиститься. Угу, как же! Соединение были такими "лёгкими" на стороне веб-сервера, что они скапливались, держа на стороне БД очень даже нехилые ресурсы... Думать надо!!!

Похоже, за это действительно стоит платить работникам, что они могут себе представить в голове задачу и понять, что они делают, даже если за них среда-компилятор-утилиты - решают (что решают, почему).
lionet
Oct. 4th, 2016 04:08 pm (UTC)
Re: «почему C++» (mpd) — это было не моё решение
Если не понимать, что происходит, в эрланге, часто получается просто немного медленнее, и, реже, подглючивает для какого-то юскейса.

Если не понимать, что происходит, в C++, получаются периодические краши (факап для всех клиентов сразу) и дырки в безопасности.

Qualitatively, конечно.
vit_r
Oct. 4th, 2016 10:38 am (UTC)
Магия сильно ухудшает надёжность. А си с крестами требует её всё больше и больше. То из серьёзного, что я видел с С++, использует его сильно обрезанным.

Не то, чтобы я критиковал решение, просто интересно, что из кода получится лет через десять.
thedeemon
Oct. 4th, 2016 11:22 am (UTC)
К тому времени в язык введут еще 8 видов указателей и 14 видов конструкторов, для простоты и удобства. Так что этот код еще эволюционирует, станет еще краше.
(no subject) - madf - Oct. 4th, 2016 12:00 pm (UTC) - Expand
(no subject) - vit_r - Oct. 4th, 2016 01:32 pm (UTC) - Expand
(no subject) - madf - Oct. 4th, 2016 03:50 pm (UTC) - Expand
(no subject) - vit_r - Oct. 4th, 2016 04:54 pm (UTC) - Expand
w - hayate_ - Oct. 4th, 2016 08:45 pm (UTC) - Expand
Re: w - vit_r - Oct. 4th, 2016 09:54 pm (UTC) - Expand
Re: w - lionet - Oct. 4th, 2016 11:17 pm (UTC) - Expand
Re: w - hayate_ - Oct. 5th, 2016 12:43 am (UTC) - Expand
Re: w - lionet - Oct. 5th, 2016 06:47 am (UTC) - Expand
Re: w - hayate_ - Oct. 7th, 2016 07:05 pm (UTC) - Expand
Re: w - lionet - Oct. 11th, 2016 05:37 am (UTC) - Expand
amarao_san
Oct. 4th, 2016 11:53 am (UTC)
Не о том говоришь. Самое дорогое в коде - его сопровождение. То есть читаемость этого кода другими сотрудниками. Кода, который бы годами работал без модификации я знаю, но он весь идёт из дистрибутива. Свой код постоянно меняется.
lionet
Oct. 4th, 2016 04:09 pm (UTC)
Если в конторе есть деньги, будут оплачивать сопровождение. Что тут поделать.
(no subject) - amarao_san - Oct. 4th, 2016 04:40 pm (UTC) - Expand
(no subject) - lionet - Oct. 4th, 2016 04:46 pm (UTC) - Expand
(no subject) - amarao_san - Oct. 4th, 2016 04:47 pm (UTC) - Expand
(no subject) - lionet - Oct. 4th, 2016 04:49 pm (UTC) - Expand
cd_riper
Oct. 4th, 2016 07:44 pm (UTC)
> Значение вектора попадает в место вызова без копирования, через RVO.

а не через move??

зы. мысли вслух -- никто тяжелые объекты по значению в векторе не хранит. если они действительно тяжелые.
nponeccop
Oct. 4th, 2016 08:41 pm (UTC)
В наше время™ хранение по ссылке чревато pointer chasing overhead, т.е. хранение по значению позволяет использовать префетчер. Т.е. если у них много объектов в пределах пары-тройки строк кеша, может оказаться, что оно оправдано.
(no subject) - sleepy_drago - Oct. 4th, 2016 09:16 pm (UTC) - Expand
(no subject) - cd_riper - Oct. 5th, 2016 03:48 am (UTC) - Expand
Павел Кидонов
Nov. 28th, 2016 01:43 pm (UTC)
Читал твой пост о RSI, как у тебя сейчас?
Артем Жарков
Dec. 15th, 2016 10:34 am (UTC)
Вы все еще программируете в Эрланге?
( 58 comments — Leave a comment )