Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Опять завалил собеседование
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyВася Уткин, Я привел пример для const& - стандартной идиоме для передачи объектов в функции. Просто & не годится для временных объектов. Значит стандартная идиома передачи (временных) объектов в функции - не правильная :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.02.2014, 20:09 |
|
||
|
Опять завалил собеседование
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyAnatoly MoskovskyПросто & не годится для временных объектов. А && не годится для невременных. && годится, главное варить правильно :) Вася УткинВ идеале бы universal reference: template<typename T> void add1(T&& s); Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.02.2014, 20:55 |
|
||
|
Опять завалил собеседование
|
|||
|---|---|---|---|
|
#18+
Вася Уткин, У шаблонов тоже есть ограничения, как например необходимость при инстанцировании иметь тела функций в той же единице трансляции. Это не всегда желательно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2014, 02:36 |
|
||
|
Опять завалил собеседование
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyВася Уткин, У шаблонов тоже есть ограничения, как например необходимость при инстанцировании иметь тела функций в той же единице трансляции. Это не всегда желательно. Это да. Хотя я честно не совсем понимаю, почему вариант void add2(value_t s); быстрее, ведь если add2() и gen_value() не inline функции, то почему отсутствует промежуточный этап копирования объекта из gen_value() в add2()? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2014, 03:05 |
|
||
|
Опять завалил собеседование
|
|||
|---|---|---|---|
|
#18+
Вася УткинХотя я честно не совсем понимаю, почему вариант void add2(value_t s); быстрее, ведь если add2() и gen_value() не inline функции, то почему отсутствует промежуточный этап копирования объекта из gen_value() в add2()? А почему вы думаете что они не inline? Из-за отсутствия ключевого слова inline? Так это уже давно не останавливает компиляторы (так же как и наличие inline не гарантирует ничего). Даже передача указателя на функцию аргументом ничего не гарантирует :) Впрочем в данном конкретном случае инлайнинга действительно скорее всего нет, а просто компилятор достаточно умен, чтобы передавать значения по указателю, а не копировать его. Это например внутри может выглядеть так (опуская детали) Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. Данная оптимизация передачи значения не зависит от наличия RVO или поддержки && (я их просто для полноты примера привел). Просто передаваемые параметры сохраняются в локальные переменные (или уже ими являются для очень многих случаев, как например в примере выше), и передается только адрес такой переменной. После выхода из функции значение такой переменной теряется. ЗЫ. На всякий случай еще раз говорю - это псевдокод, и причем один из многих возможных. Реальный код может быть другим. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2014, 08:36 |
|
||
|
Опять завалил собеседование
|
|||
|---|---|---|---|
|
#18+
Anatoly Moskovsky , ясно, просто тогда гарантировано ли будет происходить эта оптимизация если gen_value() и add2() будут в разных единицах трансляции? Сможет ли компилятор соптимизировать на уровне линковщика? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2014, 13:49 |
|
||
|
Опять завалил собеседование
|
|||
|---|---|---|---|
|
#18+
Вася Уткинясно, просто тогда гарантировано ли будет происходить эта оптимизация если gen_value() и add2() будут в разных единицах трансляции? Сможет ли компилятор соптимизировать на уровне линковщика? Способ передачи параметров by-value - это часть ABI компилятора, так что это не должно зависить от того в каком модуле определения функций. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2014, 15:25 |
|
||
|
Опять завалил собеседование
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyА еще бывает что для оптимизации ты специально везде писал Код: plaintext 1. а потом в 2011 году оказалось что Код: plaintext 1. все равно быстрее. что за ересь вы тут написали? не может быть такого! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2014, 17:08 |
|
||
|
Опять завалил собеседование
|
|||
|---|---|---|---|
|
#18+
cucaracha2014что за ересь вы тут написали? не может быть такого! Вы наверно не читатель, а писатель. Иначе вы бы увидели, что я еще и код привел в качестве доказательства :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2014, 17:25 |
|
||
|
Опять завалил собеседование
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyMasterZivв отдельном топике. лень :) alex_kпочему? Потому что, если нам надо сохранить строку, то имея const std::string& мы ее можем только скопировать, а имея std::string мы можем перенести ее содержимое без копирования. Для строк это не сильно заметно, т.к. многие реализации строк имеют copy-on-write(COW). А например с объектами, где нет COW, ускорение при отказе от конст. ссылок может быть в разы. Но естественно, будет ли ускорение зависит от алгоритма. Во многих случаях конст. ссылки быстрее. Но суть в том что эта зависимость неочевидна, т.к. опирается на многие факторы, такие как инлайн-функции, выведение типов, RVO, rvalue-ссылки, std::move. жжоте, однако :) всё гораздо проще: есть встроенные типы (int,char,...) которые компилятор умеет оптимизировать(быстрое копирование) и есть все остальные ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2014, 17:29 |
|
||
|
Опять завалил собеседование
|
|||
|---|---|---|---|
|
#18+
Anatoly Moskovskycucaracha2014что за ересь вы тут написали? не может быть такого! Вы наверно не читатель, а писатель. Иначе вы бы увидели, что я еще и код привел в качестве доказательства :) в случае со stringом ваш тест опровергнет ваше утверждение ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2014, 17:31 |
|
||
|
Опять завалил собеседование
|
|||
|---|---|---|---|
|
#18+
cucaracha2014, Идите дальше читайте книгу про оптимизацию. У вас пока не получается :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2014, 17:39 |
|
||
|
Опять завалил собеседование
|
|||
|---|---|---|---|
|
#18+
Да, забыл написать Для std::string результаты такие: 00:00:01.786493 00:00:01.544935 00:00:01.732854 00:00:01.542740 Не в полтора раза конечно, но достаточно чтобы cucaracha2014 опять не прошел собеседование ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2014, 17:48 |
|
||
|
Опять завалил собеседование
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyДа, забыл написать Для std::string результаты такие: 00:00:01.786493 00:00:01.544935 00:00:01.732854 00:00:01.542740 Не в полтора раза конечно, но достаточно чтобы cucaracha2014 опять не прошел собеседование что это за магичесие числа? выкладывайте код ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2014, 18:01 |
|
||
|
Опять завалил собеседование
|
|||
|---|---|---|---|
|
#18+
cucaracha2014, Я так понимаю, что специалистам по разработке архитектуры и ООП не положено знать как заменить один typedef и получить код для нового типа. :) Держите. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. ЗЫ. Подправил код, чтобы не было расхода памяти при большом числе итераций. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2014, 18:18 |
|
||
|
Опять завалил собеседование
|
|||
|---|---|---|---|
|
#18+
Anatoly Moskovsky, для чистоты эксперимента уберите std::move и результаты в студию! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2014, 18:49 |
|
||
|
Опять завалил собеседование
|
|||
|---|---|---|---|
|
#18+
cucaracha2014для чистоты эксперимента уберите std::move и результаты в студию! С какой стати? Для чистоты эксперимента достаточно чтобы прототипы функций совпалали с тем что я утверждал. Код: plaintext 1. 2. А про тела функций я никаких утверждений, требующих доказательств не приводил. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2014, 19:01 |
|
||
|
Опять завалил собеседование
|
|||
|---|---|---|---|
|
#18+
Anatoly Moskovsky, этот "прикол" работает только потому, что в новом стандарте появились movable types и movable constructors (etc...) что STL переработана с учётом movable-семантики что в вашем тесте используется вызов fn(gen_value()), т.е. есть неявная временная переменная В результате в fn(gen_value()) вызов gen_value() возвращает неименованную временную переменную, которая принимается movable-конструктором контейнера. Далее, за счёт инструкции std::move этот элемент "воруется" в новый контейнер. При этом std::move - это просто приведение типа, не более того (подробнее - http://www.aristeia.com/videos/Gn13ScottMeyersAnEffectiveCPP_high.mp4 ). Само оно ничего не перемещает. В случае с передачей по константной ссылке "своровать" вы явно запрещаете модификатором const - константность означает неизменяемость объекта, а вы его меняете. Почему не происходит ошибки при попытке применить move к const-объекту? Это вопрос к стандарту. В приведении типов const побеждает. И, да. Появление "перемещаемых" объектов - это появление новой парадигмы, которая существенно меняет стилистику написания кода. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2014, 20:59 |
|
||
|
Опять завалил собеседование
|
|||
|---|---|---|---|
|
#18+
BagaBagaэтот "прикол" работает только потому, что в новом стандарте появились movable types и movable constructors (etc...) что STL переработана с учётом movable-семантики Я вообще-то изначально так и сказал, что это появилось в С++ в 11 году. BagaBagaПри этом std::move - это просто приведение типа, не более того ...Само оно ничего не перемещает Это да. BagaBagaВ случае с передачей по константной ссылке "своровать" вы явно запрещаете модификатором const - константность означает неизменяемость объекта, а вы его меняете А тут непонятно, почему вы решили что move изменяет объект, если вы только что выше написали что он ничего не меняет? :) Рекомендую в таких случаях читать доку и узнавать что на самом деле должно происходить. В частности, для константных объектов move возвращает const&& а для неконстантных - &&. Первый вариант передается в конструктор копирования (поскольку обычно отсутствует отдельный конструктор для const&&), а второй - в конструктор перемещения. Вот и все дела. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2014, 21:38 |
|
||
|
Опять завалил собеседование
|
|||
|---|---|---|---|
|
#18+
MasterZivДобавлю, что я ТОЖЕ не люблю возиться с оптимизацией. И не нужно этим вообще заниматься, нужно сразу пытаться писать код с оглядкой на производительность. Только это не заключается в подсчёте IF-ов и WHILE-ов, а в знании стоимостей операций. +10. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2014, 21:48 |
|
||
|
Опять завалил собеседование
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyBagaBagaВ случае с передачей по константной ссылке "своровать" вы явно запрещаете модификатором const - константность означает неизменяемость объекта, а вы его меняете А тут непонятно, почему вы решили что move изменяет объект, если вы только что выше написали что он ничего не меняет? :) Рекомендую в таких случаях читать доку... Хм. move - подсказка компилятору, не более того (т.к. просто приведение типа). Теперь "про меняет - не меняет". vector<int> a(10,1); vector<int> b; b = move(a); Что мы здесь имеем? Мы изменяем вектор a. Как? Мы "воруем" у него элементы для вектора b (точнее, мы даём подсказку компилятору, что - если возможно, - нужно "своровать содержимое" вектора a для вектора b). Что будет храниться в векторе a, после того как из него "утянули содержимое" в вектор b? Стандарт говорит, что объект, "у которого украли", может былить в unspecified состоянии, а его дальнейшее использование может приводить к undefined behavior. Но это в общем случае. Для вектора гарантируется, что объект будет находится в консистентном состоянии (нулевой вектор, и использовать его можно). Не помню, есть ли такая гарантия для string. Итого - move "сам по себе" ничего не меняет, т.к. является просто приведением типа. Использование move семантически несёт в себе "смысл" изменения исходного объекта путем "переноса" данных в приёмник. Правда, в ряде случаев (например, источника с квалификатором const), это "технически" реализуется посредством копирования... А стандарт... да, нужно читать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2014, 22:22 |
|
||
|
Опять завалил собеседование
|
|||
|---|---|---|---|
|
#18+
вот так обьявлен мов: Код: plaintext 1. 2. 3. 4. 5. 6. 7. Не очень понимаю как можно сделать typename для функции. Кто-нибудь може мне обьяснить? Это просто приведение к T&& что ли? Мне кажется, что это просто приводят обьект к lvalue То есть фактически, начего нового не происходит, и вся эта с++11 и прирост производительности основан на магии внутри vector, которую можно было бы спокойно сделать и без с++11, невыдумывая это все. или я не понимаю чего-то. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.02.2014, 01:48 |
|
||
|
Опять завалил собеседование
|
|||
|---|---|---|---|
|
#18+
chabapoktemplate< class T > typename std::remove_reference<T>::type&& move( T&& t ); Не очень понимаю как можно сделать typename для функции. Кто-нибудь може мне обьяснить? typename -- ключевое слово, которое говорит компилятору, что далее по тексту, следующей лексемой идёт тип данных, а не что-то другое. Функция с типом возврата и сигнатурой параметра является в С++ (и С) типом данных, таким же (почти) как и другие типы. Функция как тип данных может определять только один производный тип -- это указатель на такую функцию. Собственно, тип функции и тип указателя на функцию -- это одно и то же. Собственно, не понятно, в чём проблема ввести тип фукнции через typename. Ну и тут typename относится не к функции, а к "std::remove_reference<T>::type&& " , и говорит, что это -- тип данных, а не ещё какой-то элемент языка. Всё вместе объявляет прототип функции `move' c параметром T&& t , которая возвращает std::remove_reference<T>::type&& ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.02.2014, 02:17 |
|
||
|
Опять завалил собеседование
|
|||
|---|---|---|---|
|
#18+
chabapokМне кажется, что это просто приводят обьект к lvalue Вот я не понимаю, зачем гадать, когда можно просто прочитать в доке по move () в два клика? В С++11 то, что возвращает move, называется xvalue (expiring value) - значение, дальнейшая судьба которого программиста уже не интересует. Кстати в большинстве случаев явный move() не нужен, т.к. компилятор сам способен понять, что если переменная например выходит из области видимости, то ей можно автоматически делать move. chabapokТо есть фактически, начего нового не происходит, и вся эта с++11 и прирост производительности основан на магии внутри vector, которую можно было бы спокойно сделать и без с++11, невыдумывая это все. Нет, хоть это частично и было возможно через явное использование swap (см. выше код Уткина для С++03), но во-первых это приводило к громоздкому и малопонятному коду, и что важнее, например перемещающие конструкторы или присвоения не были возможны, т.к. программист имея константную ссылку как параметр не мог гарантировать, что там временная переменная, а не просто константный алиас на объект, который еще понадобится. Только в С++11 появились ссылки &&, которые соответствуют именно временным (и вообще любым xvalue) объектам и позволяют создавать отдельные перегрузки. И переделанный с учетом этого STL, автоматически ускорил (не везде конечно) существующий С++03 код, который про && и move вообще не в курсе. chabapokили я не понимаю чего-то. Да. Или. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.02.2014, 03:48 |
|
||
|
Опять завалил собеседование
|
|||
|---|---|---|---|
|
#18+
Anatoly Moskovskycucaracha2014для чистоты эксперимента уберите std::move и результаты в студию! С какой стати? Для чистоты эксперимента достаточно чтобы прототипы функций совпалали с тем что я утверждал. Код: plaintext 1. 2. А про тела функций я никаких утверждений, требующих доказательств не приводил. Подразумевалось, что тела функций - одинаковые. Иначе какой смысл замерять время выполнения? Тот факт, что в вашем примере выглядят одинаково при различной работе - это скорее исключение, чем правило, причём это только благодаря извращениям в новом стандарте, который почти никто до сих пор не использует(и правильно). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.02.2014, 12:18 |
|
||
|
|

start [/forum/topic.php?fid=57&msg=38547796&tid=2019710]: |
0ms |
get settings: |
9ms |
get forum list: |
13ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
170ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
55ms |
get tp. blocked users: |
1ms |
| others: | 13ms |
| total: | 278ms |

| 0 / 0 |
