Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Это типичное заблуждение Java/C# программиста, мол там где у него new и владеющие указатели, то в C++ обязательно будет какой-нибудь умный/обычный указатель. Этот феномен даже Страуструп высмеивал — https://youtu.be/OB-bdWKwXsU?t=1984 EP>По факту же в большинстве кода не нужны никакие владеющие указатели.
Та да. Я как-то давал уже статистику, что в довольно большом проекте из более 250 прикладных типов, встречалось всего 17 (!!!) операций new.
В С++ типы чаще всего агрегируются по значению, если посмотреть на иерархию владения. По new обычно выделяются объекты из самого верха иерархии и то, далеко не всегда. ))
Здравствуйте, gandjustas, Вы писали:
V>>А что изменилось после C++11 в этом плане? G>После C++ умные указатели вошли в стандарт и стали основным способом работы. Это, кстати, позволяет намного сократить количество ошибок, но путем повышения тормозов. Если писать по старинке, через голые указатели, то очень много ошибок обращений к освобожденной памяти возникает, и довольно часто возникают утечки.
Расскажите мне про тормоза умных указателей. Я не понимаю.
Может быть потому, что я не фигачу шареды направо и налево, потому что обычно я знаю, кто у ресурса хозяин, и мне хватает уника, у которого тормозить вообще нечему.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Здравствуйте, Evgeny.Panasyuk, Вы писали:
V>>Когда твоя джава получит указатель на объект "откуда-то еще", никакой девиртуализации при вызове не происходит, оно происходит аккурат в аналогичном приведенному сценарии.
EP>Справедливости ради, в некоторых из таких случаев девиртуализацию может сделать JIT
Справделивости ради — нет. ))
Если JIT "не видел", откуда получен объект, то никакой девиртуализации не будет. А если видел — то это он всего-лишь проинлайнил тот самый вызов, в котором встретилось new для целевого объекта. Дык, возможности инлайна в С++ на порядки больше.
EP>Кстати, тут недавно был синтетический бенчмарк, в котором как раз был сделан сильный упор на JIT/девиртуализацию и GC, буквально задача на которой они раскрываются во всей красе — так даже и его получилось забороть
подсчётом ссылок и изначально меньшей виртуальностью (примерно то о чём ты говорил).
Синтетические бечмарки фтопку. Реально. Потому что они заставляют на С++ писать АНАЛОГИЧНЫЙ управляемому код исключительно с целью бенчмарка. ))
А в реальной жизни на С++ пишут нифига не аналогичный код, бо система типов такова, что там, где на Джаве или дотнете всё разруливается через интерфейсы и виртуальные вызовы (и только через них, родимых), на С++ всё разруливается на шаблонах еще на этапе компиляции.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, Serginio1, Вы писали:
EP>>>Это типичное заблуждение Java/C# программиста, мол там где у него new и владеющие указатели, то в C++ обязательно будет какой-нибудь умный/обычный указатель. Этот феномен даже Страуструп высмеивал — https://youtu.be/OB-bdWKwXsU?t=1984 EP>>>По факту же в большинстве кода не нужны никакие владеющие указатели. S>> Так в итоге C#, Java, JS в топку? Все на С++?
EP>Не, не в топку. Я сам частенько использую Python. И по секрету скажу, недавно даже на C# написал несколько сотен строк — правда это был пример использования C++ библиотеки, но тем не менее. EP>А вообще непонятно как ты сделал вывод про "в топку"
Да в том, что считать нужно не тики, а удобство языков для решения определенных задач. Я уже приводил, ссылку что самые востребованные программисты это 1С овцы. А никто в здравом уме не станет сравнивать по скорости С++ и 1С. Порядок и так известен. На самом деле большую часть нагрузки это SQL базы, и доля вычислений на 1С не такая большая. Для вэб,HTTP сервисов сайтов во главе угла удобство использования библиотек и распараллеливания кода. Await ооочень удобен.
Все больше построение DOM выносится на клиента, где уже востребованы TS, AngularJS, JQuery итд.
Я к тому, что для каждого языка свои задачи. А порядок скоростей давно известен. И многие задачи решаются за счет оптимального подбора алгоритмов.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, vdimas, Вы писали:
V>Синтетические бечмарки фтопку. Реально. Потому что они заставляют на С++ писать АНАЛОГИЧНЫЙ управляемому код исключительно с целью бенчмарка. ))
И наоборот тоже.
V>А в реальной жизни на С++ пишут нифига не аналогичный код, бо система типов такова, что там, где на Джаве или дотнете всё разруливается через интерфейсы и виртуальные вызовы (и только через них, родимых), на С++ всё разруливается на шаблонах еще на этапе компиляции.
Во! Именно по этой причине я нахожу практически бессмысленным сравнивать скорость работы одинакового кода в разных языках. Разве что из любопытства. Сравнивать имеет смысл время решения одинаковой задачи, независимо от того, какими средствами она была решена.
Здравствуйте, vdimas, Вы писали:
V>>>Когда твоя джава получит указатель на объект "откуда-то еще", никакой девиртуализации при вызове не происходит, оно происходит аккурат в аналогичном приведенному сценарии. EP>>Справедливости ради, в некоторых из таких случаев девиртуализацию может сделать JIT V>Справделивости ради — нет. )) V>Если JIT "не видел", откуда получен объект, то никакой девиртуализации не будет. А если видел — то это он всего-лишь проинлайнил тот самый вызов, в котором встретилось new для целевого объекта. Дык, возможности инлайна в С++ на порядки больше.
Трассирующий JIT может заинлайнить виртуальные вызовы внутри цикла. Грубо говоря вынести проверку наружу цикла.
EP>>Кстати, тут недавно был синтетический бенчмарк, в котором как раз был сделан сильный упор на JIT/девиртуализацию и GC, буквально задача на которой они раскрываются во всей красе — так даже и его получилось забороть
подсчётом ссылок и изначально меньшей виртуальностью (примерно то о чём ты говорил). V>Синтетические бечмарки фтопку. Реально. Потому что они заставляют на С++ писать АНАЛОГИЧНЫЙ управляемому код исключительно с целью бенчмарка. )) V>А в реальной жизни на С++ пишут нифига не аналогичный код, бо система типов такова, что там, где на Джаве или дотнете всё разруливается через интерфейсы и виртуальные вызовы (и только через них, родимых), на С++ всё разруливается на шаблонах еще на этапе компиляции.
Так там по ссылке разный код, но решающий одну задачу. Абсолютно всё разрулить на этапе компиляции не получится, так как есть runtime условия. Частично — да, возможно, отчасти поэтому там и получилось обогнать JIT.
Здравствуйте, alexzz, Вы писали:
V>>А в реальной жизни на С++ пишут нифига не аналогичный код, бо система типов такова, что там, где на Джаве или дотнете всё разруливается через интерфейсы и виртуальные вызовы (и только через них, родимых), на С++ всё разруливается на шаблонах еще на этапе компиляции. A>Во! Именно по этой причине я нахожу практически бессмысленным сравнивать скорость работы одинакового кода в разных языках. Разве что из любопытства.
Смысл есть. Например выше сравнили скорость работы высокоуровневого кода — вполне полезный тест
A>Сравнивать имеет смысл время решения одинаковой задачи, независимо от того, какими средствами она была решена.
на Java потратили намного больше времени, потому что пришлось писать низкоуровневую лапшу (из-за того что высокоуровневый код там бы многократно тормозил), причём в самом характерном низкоуровневом месте которой выполз баг (у высокоуровневого C++ кода нет места для такой ошибки)
Здравствуйте, Evgeny.Panasyuk, Вы писали:
A>>Во! Именно по этой причине я нахожу практически бессмысленным сравнивать скорость работы одинакового кода в разных языках. Разве что из любопытства. EP>Смысл есть. Например выше сравнили скорость работы высокоуровневого кода — вполне полезный тест
Я не вижу практического смысла. Пишу, допустим, я программу на языке А. Вижу, что в одном месте тормозит. Беру и оптимизирую в рамках, допускаемых языком А. На язык Б я начну смотреть, только когда предел оптимизации достигнут, а всё равно тормозит, и точно понятно, что можно сделать быстрее. Но к этому времени никакого высокоуровнего кода уже не останется ― нечего сравнивать.
A>>Сравнивать имеет смысл время решения одинаковой задачи, независимо от того, какими средствами она была решена.
EP>Ха, как раз в этой теме
на Java потратили намного больше времени, потому что пришлось писать низкоуровневую лапшу (из-за того что высокоуровневый код там бы многократно тормозил), причём в самом характерном низкоуровневом месте которой выполз баг (у высокоуровневого C++ кода нет места для такой ошибки)
Пардон, я двусмысленно написал. Под «временем решения» я имел ввиду время, за которое написанная программа решает поставленную задачу.
На счёт ошибок – был бы программист, а место для ошибок всегда найдётся.
Здравствуйте, alexzz, Вы писали:
A>>>Во! Именно по этой причине я нахожу практически бессмысленным сравнивать скорость работы одинакового кода в разных языках. Разве что из любопытства. EP>>Смысл есть. Например выше сравнили скорость работы высокоуровневого кода — вполне полезный тест A>Я не вижу практического смысла. Пишу, допустим, я программу на языке А. Вижу, что в одном месте тормозит. Беру и оптимизирую в рамках, допускаемых языком А. На язык Б я начну смотреть, только когда предел оптимизации достигнут, а всё равно тормозит, и точно понятно, что можно сделать быстрее.
Так я и не говорю что нужно сразу бежать на другой язык. Где-то да, вполне уместно остаться в рамках одного языка, пусть и напедалив error-prone boilerplate низкоуровневого кода
A>Но к этому времени никакого высокоуровнего кода уже не останется ― нечего сравнивать.
В каком смысле?
A>Пардон, я двусмысленно написал. Под «временем решения» я имел ввиду время, за которое написанная программа решает поставленную задачу.
Так я же говорю, что если брать теоретически-сферический потолок по скорости который можно достигнуть, то Java/C# от C++ будут отставать не сильно, я даже не настаиваю на ударах ниже пояса типа автовекторизации.
Но это при том что на Java/C# придётся писать error-prone boilerplate low-level код, отказываясь от удобств и абстракций.
A>На счёт ошибок – был бы программист, а место для ошибок всегда найдётся.
Это понятно, если бы ошибка была в каком-то другом месте, я бы даже не обратил внимания — все ошибаются. Но в этом случае она как раз в том месте, которое появилось из-за спускания на низкий уровень.
На высоком уровне там две отдельных простых операции: std::transform и перемножение двух отдельных комплексных чисел:
Перейдя на низкий уровень ему пришлось делать одну толстую рукопашную операцию: перемножение комплексных чисел в двух массивах. И в результате он допустил ошибку как раз в месте склейки этих двух операций:
for ( int i = 0; i < u_ar.length / 2; ++i ) {
v.re(i, u.re(i) * v.re(i) - u.im(i) * v.im(i) );
v.im(i, u.re(i)*v.im(i) + u.im(i)*v.re(i));
}
Здравствуйте, Serginio1, Вы писали:
EP>>Не, не в топку. Я сам частенько использую Python. И по секрету скажу, недавно даже на C# написал несколько сотен строк — правда это был пример использования C++ библиотеки, но тем не менее. EP>>А вообще непонятно как ты сделал вывод про "в топку" S> Да в том, что считать нужно не тики, а удобство языков для решения определенных задач.
Так я же и говорю, одно из основных/главных преимуществ C++ в том, что быстрый код на нём получается удобнее чем на других языках
S>Я уже приводил, ссылку что самые востребованные программисты это 1С овцы.
Водители ещё более востребованы, и что из этого?
S>А никто в здравом уме не станет сравнивать по скорости С++ и 1С. Порядок и так известен. На самом деле большую часть нагрузки это SQL базы, и доля вычислений на 1С не такая большая. Для вэб,HTTP сервисов сайтов во главе угла удобство использования библиотек и распараллеливания кода. Await ооочень удобен.
await есть и в C++
S>Все больше построение DOM выносится на клиента, где уже востребованы TS, AngularJS, JQuery итд.
EP>Перейдя на низкий уровень ему пришлось делать одну толстую рукопашную операцию: перемножение комплексных чисел в двух массивах. И в результате он допустил ошибку как раз в месте склейки этих двух операций: EP>
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, vdimas, Вы писали:
EP>>>Например? Дороже по какому параметру? V>>По операции поиска места для вставки. Эта операция одинаково сложная для случая, когда надо поменять пару соседних или не соседних элементов.
EP>Приведи пример.
Сортировка вставкой обнаружит 5 после 6 и начнёт искать для 5 место перед 6. Сам поиск может быть как линейный (с самого начала), так и двоичный, золотого сечения и т.д.
EP>После swap'а пузырёк будет делать ещё проход.
Не будет. Простой пузырёк протягивает флаг наличия несортированных элементов, а модифицированный вместо этого протягивает границы несортированной области (индекс начала и индекс конца) и работает в оба направления туда-сюда, сужая к центру (обычно) несортированную область.
Здравствуйте, vdimas, Вы писали:
EP>>После swap'а пузырёк будет делать ещё проход.
V>Не будет. Простой пузырёк протягивает флаг наличия несортированных элементов, а модифицированный вместо этого протягивает границы несортированной области (индекс начала и индекс конца) и работает в оба направления туда-сюда, сужая к центру (обычно) несортированную область.
Ах эта сверхманевренность. Так тупо съехать с пузырька на шейкер — верх мастерства.
S>> Да в том, что считать нужно не тики, а удобство языков для решения определенных задач.
EP>Так я же и говорю, одно из основных/главных преимуществ C++ в том, что быстрый код на нём получается удобнее чем на других языках
А вот это как раз и нужно сравнивать. Например типичные задачи Asp.Net на C# и C++
S>>Я уже приводил, ссылку что самые востребованные программисты это 1С овцы.
EP>Водители ещё более востребованы, и что из этого?
А разве водители это программисты?
S>>А никто в здравом уме не станет сравнивать по скорости С++ и 1С. Порядок и так известен. На самом деле большую часть нагрузки это SQL базы, и доля вычислений на 1С не такая большая. Для вэб,HTTP сервисов сайтов во главе угла удобство использования библиотек и распараллеливания кода. Await ооочень удобен.
EP>await есть и в C++
Очень рад за вас.
S>>Все больше построение DOM выносится на клиента, где уже востребованы TS, AngularJS, JQuery итд.
EP>А ещё туда внезапно проникает C++
И каково соотношение?
S>> Я к тому, что для каждого языка свои задачи.
EP>А я разве говорил обратное?
S>>А порядок скоростей давно известен.
EP>Видимо не всем — иначе не было бы этого топика
Это было известно лет 10 назад после выхода Net 2.0 с дженериками.
S>>И многие задачи решаются за счет оптимального подбора алгоритмов.
EP>Я не предлагаю сравнивать решения с разными алгоритмами.
Так давай сравнивать реальную предметную область, а не сортировки
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, vdimas, Вы писали:
EP>>>>Например? Дороже по какому параметру? V>>>По операции поиска места для вставки. Эта операция одинаково сложная для случая, когда надо поменять пару соседних или не соседних элементов. EP>>Приведи пример. V>1 2 3 46 5 7 8 9 V>Сортировка вставкой обнаружит 5 после 6 и начнёт искать для 5 место перед 6. Сам поиск может быть как линейный (с самого начала),
Линейный поиск обычно идёт с конца, а не сначала. То есть 5 сравнится напрямую только с 6 и 4.
EP>>После swap'а пузырёк будет делать ещё проход. V>Не будет. Простой пузырёк протягивает флаг наличия несортированных элементов, а модифицированный вместо этого протягивает границы несортированной области (индекс начала и индекс конца) и работает в оба направления туда-сюда, сужая к центру (обычно) несортированную область.
Даже с этими модификациями получается больше сравнений — дойдёт до 6, сделает swap, дойдёт до конца, а потом ещё сделает проход от 5 до 1.
Здравствуйте, PM, Вы писали:
PM>В заголовок новости не поместилась информация о том, что они: PM>
PM> оптимизировали работу с памятью (а память по факту уже давно является многоуровневой системой кэшей) PM> запустили user-space TCP/IP стек для определенного вида сетевых карт PM> и пока не полностью реализовали все функции PM>PM>У меня есть сомнения, что первые 2 пункта легко реализуемы в управляемых средах (не знаю, добавили ли уже в Java value types)
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>>>Смысл есть. Например выше сравнили скорость работы высокоуровневого кода — вполне полезный тест A>>Я не вижу практического смысла. Пишу, допустим, я программу на языке А. Вижу, что в одном месте тормозит. Беру и оптимизирую в рамках, допускаемых языком А. На язык Б я начну смотреть, только когда предел оптимизации достигнут, а всё равно тормозит, и точно понятно, что можно сделать быстрее. EP>Так я и не говорю что нужно сразу бежать на другой язык. Где-то да, вполне уместно остаться в рамках одного языка, пусть и напедалив error-prone boilerplate низкоуровневого кода
A>>Но к этому времени никакого высокоуровнего кода уже не останется ― нечего сравнивать. EP>В каком смысле?
Смотри, допустим, есть метод на C#, который принимает ICollection<T>, как-то сложно её анализирует и даёт на выходе IDictionary<TKey, TValue>. И при этом тормозит. Допустим, кто-нибудь пишет аналог этого метода на C++ и указывает, что он работает в сто раз быстрее. Что это знание даёт практически?
Я ведь не смогу из C# передать в C++ ICollection<T> и получить IDictionary<TKey, TValue>.
— либо код на C++ должен будет понимать детали реализации типов в .Net, и получится уже не высокоуровневый код;
— либо передавать и возвращать придётся не абстрактные коллекции абстрактных типов, а какие-нибудь банальные массивы с числами или указатели на блоки памяти с числами, и снова получится не высокоуровневый код.
Логичный вариант ― не смотреть на другие языки, а сначала убрать лишние абстракции и чё-нибудь оптимизировать в коде на исходном языке. Стало достаточно быстро ― замечательно. Не стало ― смотрим в сторону С++, пробуем написать на нём аналог и сравниваем скорость. При этом сравниваем, естественно, с оптимизированной низкоуровневой версией. Ведь обогнать теперь нужно именно её.