Здравствуйте, Serginio1, Вы писали:
_>>Вроде бы весь набор операций, нужный для работы с sql имеется. Причём в полном соответствие с linq синтаксисом (одним из двух вариантов). А что ещё надо для ORM? ) S> Еще раз нет навигационных свойств. А в них весь смысл. Еще раз нет сравнения эффективности на сложных запросах. Как ты можешь утверждать без тестов. Это уже религия.
Не, ну если для тебя весь смысл ORM в этих самых "навигационных свойствах", то что тут можно ещё сказать...
Что касается эффективности. Т.к. время исполнения запросов в БД не зависит от вида ORM, то есть смысл сравнивать только накладные расходы вокруг запроса. Для linq версий они были озвучены (я приводил ссылку), причём не мною, а как раз реальным специалистом по C#. Что же касается sqlpp11, то в принципе можно считать, что там эти накладные расходы равны нулю (если рассматривать относительно случая ручного задания sql строки).
S> Еще раз твои утверждения голословны. Почему ты считаешь, что наколеночная реализация сделает оптимальный реализацию СКул запроса. Где тесты одинаковых запросов?
Эээ что? ) Оптимизацией запросов занимается человек, а не ORM. Хотя бы потому, что ORM просто физически не может сделать никакую внятную оптимизацию, т.к. не знает особенностей конкретной БД.
Здравствуйте, Serginio1, Вы писали:
_>>Вроде бы весь набор операций, нужный для работы с sql имеется. Причём в полном соответствие с linq синтаксисом (одним из двух вариантов). А что ещё надо для ORM? ) S> Еще раз без навигационных свойств снижает функциональность в разы. Поверь мне, так как знаю разницу. S>По быстродействию. Самая распространенная задача это когда есть некий отчет, где пользователь может наложить до 6 и более условий. S>Причем например для справочников эти условия могут быть как равны элементу либо входить в группу. Невыбранные параметры не участвуют в запросе. S>Смыла в статическом запросе никакого нет. Кроме того поддержка разных баз, провайдеров итд
Самая распространённая задача где? ) К примеру в веб'е (а я думаю можно не уточнять, что эта область намного больше любых ERP и т.п.?) такое надо ещё постараться найти. А вот как раз статические запросы вида GetUserById, GetProductById и т.п. выглядывают из-за каждого угла.
S> Но опять когда эта скорость нужна? Для клиента то он её просто незаметит. А например для Asp.Net то если сильнозагруженный сервер по 1000 запросов в секунду, то тогда стоит заморочится на скорость. Но таких задач ооочень мало.
Ну вообще то эффективный код позволяет экономить деньги на железе в любом случае, вне зависимости от нагруженности сервера. Просто в случае небольшого трафика это будут копейки, которые не окупают повышенную зарплату соответствующих специалистов. А вот в случае популярных сервисов оказывается уже выгоднее платить им деньги, но сократить количество серверов.
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, Serginio1, Вы писали:
_>>>Вроде бы весь набор операций, нужный для работы с sql имеется. Причём в полном соответствие с linq синтаксисом (одним из двух вариантов). А что ещё надо для ORM? ) S>> Еще раз нет навигационных свойств. А в них весь смысл. Еще раз нет сравнения эффективности на сложных запросах. Как ты можешь утверждать без тестов. Это уже религия.
_>Не, ну если для тебя весь смысл ORM в этих самых "навигационных свойствах", то что тут можно ещё сказать...
Вот имено. Как то некорректно сравнивать ООП с процедурным программированием. Слышали не раз.
_>Что касается эффективности. Т.к. время исполнения запросов в БД не зависит от вида ORM, то есть смысл сравнивать только накладные расходы вокруг запроса. Для linq версий они были озвучены (я приводил ссылку), причём не мною, а как раз реальным специалистом по C#. Что же касается sqlpp11, то в принципе можно считать, что там эти накладные расходы равны нулю (если рассматривать относительно случая ручного задания sql строки).
S>> Еще раз твои утверждения голословны. Почему ты считаешь, что наколеночная реализация сделает оптимальный реализацию СКул запроса. Где тесты одинаковых запросов?
_>Эээ что? ) Оптимизацией запросов занимается человек, а не ORM. Хотя бы потому, что ORM просто физически не может сделать никакую внятную оптимизацию, т.к. не знает особенностей конкретной БД.
Выдает то конечный текст SQL алгоритм. Причем для разных СУБД он будет свой. А сложность запросов бывает высокой, а не просто Select * From
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, Serginio1, Вы писали:
_>>>Вроде бы весь набор операций, нужный для работы с sql имеется. Причём в полном соответствие с linq синтаксисом (одним из двух вариантов). А что ещё надо для ORM? ) S>> Еще раз без навигационных свойств снижает функциональность в разы. Поверь мне, так как знаю разницу. S>>По быстродействию. Самая распространенная задача это когда есть некий отчет, где пользователь может наложить до 6 и более условий. S>>Причем например для справочников эти условия могут быть как равны элементу либо входить в группу. Невыбранные параметры не участвуют в запросе. S>>Смыла в статическом запросе никакого нет. Кроме того поддержка разных баз, провайдеров итд
_>Самая распространённая задача где? ) К примеру в веб'е (а я думаю можно не уточнять, что эта область намного больше любых ERP и т.п.?) такое надо ещё постараться найти. А вот как раз статические запросы вида GetUserById, GetProductById и т.п. выглядывают из-за каждого угла.
И в вэбе. Клиенту нужно получить данные о его заказах в разрезе заказа, заказов его покупателей, товаров привязанных к заказу без заказа, только готовые заказы итд.
Например 1С это тоже Вэб клиент. А таких отчетов почти каждый. У тебя просто опыта нет.
S>> Но опять когда эта скорость нужна? Для клиента то он её просто незаметит. А например для Asp.Net то если сильнозагруженный сервер по 1000 запросов в секунду, то тогда стоит заморочится на скорость. Но таких задач ооочень мало.
_>Ну вообще то эффективный код позволяет экономить деньги на железе в любом случае, вне зависимости от нагруженности сервера. Просто в случае небольшого трафика это будут копейки, которые не окупают повышенную зарплату соответствующих специалистов. А вот в случае популярных сервисов оказывается уже выгоднее платить им деньги, но сократить количество серверов.
Давай посчитаем. 1С справляется как минимум с сотней клиентов. При этом нагрузка на 1 SQL и 1 сервер приложений далека то 100 процентов.
Предприятий такого плана 80% как минимум. Мелкий и средний бизнесс
Сложность задач это миллионы строк. Один отчет может занимать десятки тысяч строк. И на 1С это может делать далеко не супер квалифицированный человек.
Если это делать на С++, то просто столько специалистов не найдется. При этом ЗП одного специалиста 1С сравнима с 1 сервером. Вот и считай, что выгодно.
Как правильно тут заметили, когда у тебя сотни и тысячи серверов то стоит задуматься и о скорости. Но понятно, что таких задач минимум, от реальных задач.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, A13x, Вы писали:
A>Я делал замеры — эквивалентный С++ код часто сравним, а иногда очень сильно отстает от эквивалентного кода на java (оверхед для generic хипа) — см. тему. A>Заранее оговорюсь — что в определенных задачах, конечно, С++ может показать сильный отрыв и по быстродействию и по потреблению памяти, хотя в прикладном программировании таких задач не так много. A>В то же время jvm может выполнять оптимизации принципиально недоступные для при статической компиляции.
На самом деле как раз наоборот. Это задач требующих подсчёт ссылок (говоря C++ языком) в прикладном программирование не так много.
A>Для желающих проверить на практике — предлагаю желающим реализовать простейший интерпретатор нетипизированного лямбда исчисления на С++ (ну то есть REPL который бы понимал что-то вроде такого) и сравнить его быстродейтвие с тем, что можно реализовать на яве (мой вариант меньше 500 строк и по быстродействию уделывает известные мне интерпретаторы scheme). Насколько я себе представляю возможные реализации — на стресс тестах будет большое количество виртуальных вызовов и большое количество выделений памяти под мелкие объекты. A>И да, согласен, что это тоже не типичная прикладная задача A>Eсли лень реализовывать — достаточно сравнить эти два варианта: на С++ и на Java — приближенные к тому, что пришлось бы иметь в коде интерпретатора.
Ну вообще то Евгений же ещё в той темке показал решений на C++, обгоняющее данный Java код. Единственное что тут стоит отметить, это наличие уже в C++, а не Java коде низкоуровневых кусков (кастомных аллокаторов) ради оптимизации. Ну так на то оно и редкая задачка.
Но в любом случае хочу поприветствовать это твоё выступление в данном обсуждение. Потому что это кажется первое и пока единственное реально аргументированное выступление на тему преимуществ управляемых языков.
Здравствуйте, ·, Вы писали:
_>>С чего это ты взял, что не могу? ) Да, и ты снова привёл не конкретный пример, а абстрактные рассуждения. Давай конкретную задачку и посмотрим могу или нет... ))) ·>Сможешь, конечно. Можно всё и на brainfuck написать, вопрос в том, что проще и на чём будет проще убедиться в работоспособности решения.
ОК, давай кроме факта возможности написания такого кода потребуем ещё и оценки его краткости, красоты и т.п. Ну так где пример задачки? )
_>>·>CAS, volatile, happens-before. _>>Если применять CAS не по делу (исключительно в специально предназначенных для этого алгоритмах), а везде вместо локов, то результат будет только ещё намного хуже чем с локами, т.к. в таком случае всё равно будет нечто типа лока, только при этом с полной загрузкой процессора. ·>Полная загрузка процессора в low latency как раз частенько используется — для того, чтобы операционка не вздумала вытеснить критичный тред. Ещё этот тред к одному ядру привязывается.
Это подходит только для простенькой задачки, в которой она единственная на системе и при этом сами вычисления не тяжёлые. Для более сложных случаев (например обработке видео в реальном времени) такие фокусы только помешают.
Здравствуйте, ·, Вы писали:
EP>>Понимать как работает железо обязательно нужно. Также нужно понимать как отображаются конструкции языка в железо — и вот с этим у Java проблемы, для быстрого кода приходится отказываться даже от элементарных абстракций и городить low-level код, который даже ниже уровень чем то что есть в языке C. ·>Да нет каких-то сверх-проблем. Да, нужно писать код определённым образом, реализовывать определённые решения, но это верно для любого оптимизируемого кода на любом языке. Java в этом плане ничуть ни лучше, ничуть не хуже, чем C++.
Намного хуже. Потому что платформа скрывает за собой значительную часть возможностей железа. Это касается в общем то всех языков, работающих в своей виртуальной машине. Хотя в том же C# с этим дела чуть лучше (правда только в unsafe режиме), но и то не сравнится с нативными языками. А в Java всё совсем печально.
Здравствуйте, ·, Вы писали:
·>Вот поэтому и не нужно считать константным, а тупо использовать иммутабельный тип (что при наличии деструкторов в языке сделать невозможно).
А какая вообще связь между константностью/иммутабельностью и наличием деструкторов?
Здравствуйте, Serginio1, Вы писали:
_>>Самая распространённая задача где? ) К примеру в веб'е (а я думаю можно не уточнять, что эта область намного больше любых ERP и т.п.?) такое надо ещё постараться найти. А вот как раз статические запросы вида GetUserById, GetProductById и т.п. выглядывают из-за каждого угла. S> И в вэбе. Клиенту нужно получить данные о его заказах в разрезе заказа, заказов его покупателей, товаров привязанных к заказу без заказа, только готовые заказы итд. S>Например 1С это тоже Вэб клиент. А таких отчетов почти каждый. У тебя просто опыта нет.
В 1C у меня точно нет опыта и не предвидится. ) А вот про веб я как раз вполне в курсе. ))) Да, и наличие у 1C веб-клиента ещё не делает его похожим на полноценный веб.
_>>Ну вообще то эффективный код позволяет экономить деньги на железе в любом случае, вне зависимости от нагруженности сервера. Просто в случае небольшого трафика это будут копейки, которые не окупают повышенную зарплату соответствующих специалистов. А вот в случае популярных сервисов оказывается уже выгоднее платить им деньги, но сократить количество серверов. S> Давай посчитаем. 1С справляется как минимум с сотней клиентов. При этом нагрузка на 1 SQL и 1 сервер приложений далека то 100 процентов. S>Предприятий такого плана 80% как минимум. Мелкий и средний бизнесс
Эээээ, как вообще можно указывать подобные цифры без точного описания железа? ) Как бы Atom с 1 GB RAM и 18-и ядерный Xeon с 256 GB RAM дают очень разную производительность и стоят очень разные деньги...
S>Сложность задач это миллионы строк. Один отчет может занимать десятки тысяч строк. И на 1С это может делать далеко не супер квалифицированный человек. S>Если это делать на С++, то просто столько специалистов не найдется. При этом ЗП одного специалиста 1С сравнима с 1 сервером. Вот и считай, что выгодно. S>Как правильно тут заметили, когда у тебя сотни и тысячи серверов то стоит задуматься и о скорости. Но понятно, что таких задач минимум, от реальных задач.
А что, тут кто-то предлагал писать бухгалтерские отчёты на C++? Естественно такое пишут на скриптовых языках (где-то это свой язык, как в 1C или SAP, а где-то и обычный, типа Python/JS) соответствующей платформы. А вот саму платформу пишут уже на C++, ну если конечно хочется хоть какого-то быстродействия. )))
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, Serginio1, Вы писали:
_>>>Самая распространённая задача где? ) К примеру в веб'е (а я думаю можно не уточнять, что эта область намного больше любых ERP и т.п.?) такое надо ещё постараться найти. А вот как раз статические запросы вида GetUserById, GetProductById и т.п. выглядывают из-за каждого угла. S>> И в вэбе. Клиенту нужно получить данные о его заказах в разрезе заказа, заказов его покупателей, товаров привязанных к заказу без заказа, только готовые заказы итд. S>>Например 1С это тоже Вэб клиент. А таких отчетов почти каждый. У тебя просто опыта нет.
_>В 1C у меня точно нет опыта и не предвидится. ) А вот про веб я как раз вполне в курсе. ))) Да, и наличие у 1C веб-клиента ещё не делает его похожим на полноценный веб.
Полноценный не полноценный но работает ведь. При этом основная то нагрузка на сервер о чем мы и говорим. При этом существующего железа хватает с головой для большинства задач.
_>>>Ну вообще то эффективный код позволяет экономить деньги на железе в любом случае, вне зависимости от нагруженности сервера. Просто в случае небольшого трафика это будут копейки, которые не окупают повышенную зарплату соответствующих специалистов. А вот в случае популярных сервисов оказывается уже выгоднее платить им деньги, но сократить количество серверов. S>> Давай посчитаем. 1С справляется как минимум с сотней клиентов. При этом нагрузка на 1 SQL и 1 сервер приложений далека то 100 процентов. S>>Предприятий такого плана 80% как минимум. Мелкий и средний бизнесс
_>Эээээ, как вообще можно указывать подобные цифры без точного описания железа? ) Как бы Atom с 1 GB RAM и 18-и ядерный Xeon с 256 GB RAM дают очень разную производительность и стоят очень разные деньги...
Ну я озвучил стоимость сервера равной ЗП программиста. Так что выбирай из этих условий.
S>>Сложность задач это миллионы строк. Один отчет может занимать десятки тысяч строк. И на 1С это может делать далеко не супер квалифицированный человек. S>>Если это делать на С++, то просто столько специалистов не найдется. При этом ЗП одного специалиста 1С сравнима с 1 сервером. Вот и считай, что выгодно. S>>Как правильно тут заметили, когда у тебя сотни и тысячи серверов то стоит задуматься и о скорости. Но понятно, что таких задач минимум, от реальных задач.
_>А что, тут кто-то предлагал писать бухгалтерские отчёты на C++? Естественно такое пишут на скриптовых языках (где-то это свой язык, как в 1C или SAP, а где-то и обычный, типа Python/JS) соответствующей платформы. А вот саму платформу пишут уже на C++, ну если конечно хочется хоть какого-то быстродействия. )))
Мы говорим о производительности. Так производительности скриптовых языков хватает в большинстве задач. А скорость .Net намного выше при этом дает динамическую типизацию через dynamic. Очень удобно при работе с неопределенными типами. http://habrahabr.ru/post/144330/
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, ·, Вы писали:
·>Тут в топике мне предлагают использовать голые указатели. Это правильное использование? А cyclic references тоже правильное?
Если ты знаешь хозяина (unique_ptr) и его время жизни — то да.
TB>>·>Меняешь чуток код и вдруг вылазишь за время жизни объекта. Упс, битый указатель. TB>>Как можно грохнуть объект, пока он ещё кем-то используется? По-моему, это косяк программиста куда более серьёзный, чем просто какой-то битый указатель. ·>В С++ — запросто. В java — никак.
Как страшно жить!
TB>>·>Можно, конечно. Но деструктор запретить-то нельзя. TB>>...но ГЦ и финализатор запретить нельзя... TB>>(я хз, к чему это, просто разговор поддержать) ·>Конечно нельзя. Но обратиться к объекту, попавшему ГЦ на растерзание — тоже нельзя.
И обратиться к объекту, который уничтожается — тоже нельзя, если программист понимает, что он делает. Если не понимает — то и жаба не поможет. В целом в С++ напортачить проще, из-за чего он и не стал популярнее жабы.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Здравствуйте, ·, Вы писали:
I>>Есть куча проектов, которые загнулись из за того, что так и не смогли сбороть этот GC. ·>А конкретнее? Ни одного С++ проекта не загнулась из-за сложности кода?
Джава приходит в реалтайм, трейдинг и тд и тд с большим опозданием. Во многих областях джавы и близко нет.
Собтсвенно, пытаются писать много, но взлетает далеко не все. Там где не взлетела джава, как правило уже лет 10 и больше С++ в полный рост.
I>> Потому для LMAX это вполне реальный риск и именно по этому они лезут из кожи вон, что бы обеспечить нужное время отклика. ·>Ещё раз. GC составляет O(1) проблем LL, самая жуть это железо и ОС. Глючный сетевой кабель — и 300мс задержка только в путь, такое GC и не снилось.
Это заблуждение. У тебя практически вся архитектура приложения нацелена на минимизацию проблем с GC. Ты или забыл про это, или еще не понял.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
I>>>>Это просто твоё мнение, ничем не аргументированое. EP>>>Это аргумент. Ты можешь быть согласен с ним или нет. I>>А противоположная формулировка, хочешь ты или нет, тоже аргумент или как ?
EP>А смысл просто так повторять противоположную формулировку? Скажи что не согласен потому-то и тому-то, или хотя бы попроси разъяснения — зачем кирпичом прикидываться?
Начни с себя. Ты ведь начал голословно вещать, что всё де миф и тд и тд.
EP>На C можно писать как с "контролем над временем", так и без него — это ортогональное свойство. Точно также и для C++. Поэтому контроль над временем ортогонален "как на Си". EP>Вот есть бы сказал что "как на блаб", при этом блаб бы использовался исключительно для задач контролем над временем — был бы другой разговор.
"Как на Си" это в первую очередь использования явных механизмов. Нет никаких скрытых фокусов, магии конструкторов-деструкторов-исключений и тд и тд и тд.
Контролировать легче именно потому, что все делается явно. Разумеется, при желании любую идею можно опаскудить.
I>>У твоей подстраховки один побочный эффект — время выполнения может быть недетерминированым. EP>Эта подстраховка никак не влияет на порядок вызова деструкторов, он остаётся таким же как было бы и без неё.
Я про количество и глубину, а не порядок вызова. EP>Я причём тут передёргивание? Ты не понимаешь важный для дискуссии аспект. В C++11 есть нововведение позволяющее существенно снизить количество ref inc/dec.
Киев, дядька, бузина.
I>>Я же сказал, что каскадная очистка это один из возможных вариантов реализации. Тебе её удобно делать деструкторами. Отсюда ясно, что хрен его знает, какое будет время работы.
EP>Нет, ты потерял контекст. Мы сейчас рассматриваем случай где использование ref-counting избыточно, то есть не продиктовано самой задачей, как в случае с разделяемым владением(а такие задачи сами по себе редки). В этом случае ref-counting никак не влияет на порядок вызова деструкторов.
Это ты хочешь понамекать, что якобы единтсвенная проблема это инкремент-декремент относительно общей массы. Я говорю совсем про другое.
Здравствуйте, T4r4sB, Вы писали:
TB>>>·>Можно, конечно. Но деструктор запретить-то нельзя. TB>>>...но ГЦ и финализатор запретить нельзя... TB>>>(я хз, к чему это, просто разговор поддержать) TB>·>Конечно нельзя. Но обратиться к объекту, попавшему ГЦ на растерзание — тоже нельзя. TB>И обратиться к объекту, который уничтожается — тоже нельзя, если программист понимает, что он делает. Если не понимает — то и жаба не поможет. В целом в С++ напортачить проще, из-за чего он и не стал популярнее жабы.
С++ не то что не стал популярнее Джавы, он лет 20 как утратил доминирование. В свое время С++ именно доминировал в разработке. С тех пор управляемые решения выдавили С++ в низкоуровневый функционал.
Здравствуйте, alex_public, Вы писали:
_>Намного хуже. Потому что платформа скрывает за собой значительную часть возможностей железа. Это касается в общем то всех языков, работающих в своей виртуальной машине. Хотя в том же C# с этим дела чуть лучше (правда только в unsafe режиме), но и то не сравнится с нативными языками. А в Java всё совсем печально.
Главное помнить о том, что нативные и управляемые решения за последние 20 лет практически поменялись местами, если смотреть долю рынка.
_>В 1C у меня точно нет опыта и не предвидится. ) А вот про веб я как раз вполне в курсе. ))) Да, и наличие у 1C веб-клиента ещё не делает его похожим на полноценный веб.
1) Если делать вызов пустого метода 1С-веб-сервиса (содержит только возврат строкового параметра), первый вызов отрабатывает около 1-3 секунд, последующие вызовы отрабатывают примерно 25-60 раз в секунду (с самого сервера, что логично, быстрее, с других машин медленнее). Т.е. пул работает.
2) Если такие вызовы запустить параллельно, то скорость каждого вызова падает незначительно, т.е. опять таки, похоже пул работает.
3) Но вот если сравнивать с аналогичным веб-сервисом на С#, расположенном на том же железе, сравнение сильно не в пользу 1С. Разница составляет от 8-10 и более (минимальное количество вызовов у этого сервиса — 250).
Грустно как-то. Может есть идеи, где затык? Или безнадежно, и лучшего чем 25-60 вызовов от 1С не получить?
И это просто пустого метода. Правда в 1С к каждому подключению идет инициализация юзера, но в этом тесте на пустой конфигурации. В Net это решается через токены авторизации, кэшировании клиента на сервере итд.
То есть в самом простом случае это 8-10 раз без вызова кода.
При этом сложность написания кода на C# не намного выше. Правда и возможностей выше. А вот скорость написания может быть даже выше за счт интеллисенсе и статическая проверка кода. Например многие используют TS вместо голого JS.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, PM, Вы писали:
PM>Да, да, "write once, run anywhere", Java завоюет мир... Когда-то читал про такое, лет 20 назад. По-моему ниша Java всё та же — корпоративные и банковские приложения. Может андроид слегка добавил, пока разработчики не выяснили, что писать мобильные приложения выгоднее с общим ядром на C++ и пользовательским интерфейсом под конкретную платформу.
Идея "write once, run anywhere" здохла. Тем не менее Джава с тех пор внятно пролезла и в микроконтроллеры, HPC, HFT, реалтайм, операционные системы, бортовая электроника и много куда еще.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>>>>>Пусть просто поставит в очередь, делов-то dot>>>>Поставит что? Сразу весь развесистый граф? А если надо только часть освободить? Ставить каждый самый мелкий объект? А очереди не поплохеет? EP>>>Не каждый объект, а те которые не успеваем освободить. dot>>А как мы будем выяснять — успеем или не успеем? EP>Замерами — например смотрим максимальное/среднее/etc время очистки одного узла. Причём тот же finalize есть и Java. EP>Если же речь идёт о hard real time — то там применяются совершенно другие приёмы.
Как эти замеры производить? Куда их вставлять? Как это повлияет на latency?
dot>>>>В low latency единственный ресурс обычно память. EP>>>Сильное утверждение. Да и это проблема ко всему относится, а не только к low latency. dot>>Что-то не понял. Которая проблема? EP>Задача работы с ресурсами.
А почему ты эту задачу привёл? К чему всё это? Управление ресурсами (кроме памяти) ничем не отличается между C++ и Java.
dot>>>>>>А для ресурсов в общем случае — наследники java.lang.ref.Reference. EP>>>>>Каким образом они обеспечат prompt finalization? dot>>>>А надо? EP>>>Надо, это задача. dot>>Какая именно задача? Ты не путаешь задачу со способом решения? EP>Задача — своевременное освобождение ресурсов.
Т.е. приходит к тебе клиент, кладёт на стол пачку денег и говорит: "Я бизнесмен, занимаюсь освобождением ресурсов. Напиши мне программу, которая это будет делать своевременно". А отдел маркетинга рисует очередной баннер: "Мы освобождаем ресурсы дёшево и своевременно!". Я правильно понимаю?
EP>Про эти костыли я в курсе, но ты покажи как будешь их применять в поставленной задаче. Или например как бороться с транзитивностью "быть ресурсом" при агрегировании.
Ресурсы отдельно, логика отдельно. Зачем агрегировать? В С++ — да, никуда не денешься, т.к. память — ресурс.
EP>>>Ту же самую, с потоками, при завершении последнего нужно освободить ресурс. dot>>Эээ.. Попробую сформулировать. Открыть файл, раздать открытый файл пачке тредов, которые могут так же кидаться файлами с другими тредами и закрыть, когда последний тред его обработает. Так? Собственно решение будет аналогично С++, взять какой-нибудь подходящий класс из java.lang.concurrent.* и реализовать контроль пользователей ресурса. EP>Как именно? Как ресурс будет передаваться в потоки? Кто и как будет решать что нужно удалить?
Представь решение на С++ и, скорее всего, в Java получится примерно так же.
dot>>Ещё раз, в java есть только один специально обрабатываемый ресурс — память. Не надо натягивать gc на контроль любых ресурсов, он только для памяти. EP>А я не натягиваю. Я предлагаю тебе решить, или хотя бы описать решение любым способом.
Дай конкретную задачу, дам конкретное решение.
dot>>Я понимаю откуда растёт это заблуждение. Деструктор в С++ может быть использован как для памяти, так и для любых других ресурсов. Не надо переносить это понимание в java. В java gc — только для памяти. Другие ресурсы — с помощью try-with-resources контролируются. EP>Про заблуждение это ты придумал. Я прекрасно знаю об этих всех костылях а-ля with/using/try-with-resources.
А зачем вообще эти ресурсы приплёл? Вроде о памяти разговаривали, и вдруг ресурсы вылезли.
EP>>>Потому что lock'и это не lockfree, принципиально. Смотри определение. Lockfree это прежде всего некоторые гарантии, а не например скорость — скорость вообще может быть меньше. EP>>>Да и кто сказал что время предсказуемо? Например GC заснул захватив lock, остальные ждут. Тут желательно хотя бы obstruction free dot>>lockfree это гарантии на уровне кода, а что там делает окружение — не важно. Скажем, если операционка вытесняет твой поток — по сути она лочит его — исполнение приостанавливается. А ещё и CPU может заснуть, скажем для экономии энергии или для регуляции тепловыделения. И что? lockfree и на C++ невозможен? EP>Прочитай определение lock-free.
Вооот. Хорошо, но уже лучше. А теперь перечисли, какие из гарантии lock-free нарушаются при наличии gc?
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>>>И не в покер, а в преферанс. И не выиграл, а проиграл. EP>>>И не ссылку, а сам объект. И не unique_ptr, а просто стэковый объект. dot>>Перенос объекта на стек это другая оптимизация. Может делаться только для маленьких оъбектов. Если у тебя выделяется 100мб массив и EA покажет, что ссылка на массив не убегает за пределы, то при выходе из стека объект грохнется. Т.е. по сути тот же unique_ptr. EP>То есть имелось в виду scoped_ptr — более ограниченная версия unique_ptr. Например unique_ptr можно возвращать из функции.
EA работает и с множеством функций. Сделай "byte[] func() {return new byte[100500];}"- ничего страшного.
EP> vector<Widget> values(N);
И молись что N не слишком большой и не получится stack overflow на пустом месте.
dot>>массив не убегает за пределы, то при выходе из стека объект грохнется EP>Каким образом грохнется? Речь только про некомпактифицируемые кучи?
Самое тривиальное — копирующим GC.
EP>>>Именно голые не владеющие указатели — владелец то переживёт всех. Вполне обычная/нормальная/стандартная практика EP>>>Smart-pointer'ы прежде всего помогают избавиться от голых владеющих указателей, а не от того что ты подумал. dot>>Бррр... Я уж надеялся, что голые указатели постепенно изничтожаются. EP>Ты что, они же есть в реальности данной нам в ощущениях железом. Это же например самый быстрый способ указать на конкретный элемент массива, или передать куда-нибудь его часть.
Железом нам даны адреса, а не указатели.
EP>>>Упёрлись в потолок, GC начинает очень долго освобождать за O(N), отбирая ресурсы у других потоков, общая пропускная способность снижается (забиты каналы памяти, и аллокации происходят медленней), извне приходят всё новые задачи для которых в свою очередь нужна всё новая память, в конце концов либо OOM либо DoS. dot>>Это же сценарий high throughput, а не low latency. В такой ситуации и C++ грохнется — он будет делать ту же работу, просто в рабочих тредах, а на в отдельных gc-тредах как java. EP>Не грохнется — у него нет зависимости O(N) от количества живых объектов.
new/malloc и delete/free работают не за O(1) внезапно.
Если у тебя gc работает в режиме, что у него есть зависимость O(N) (т.е. худший случай), то ты делаешь что-то не то. Как известно, gc работает хорошо при короткоживущих и длинноживущих объектах. А проверяет он по грязным регионам, а не по всем живым.
Quick-sort имеет сложность O(N*N), как и пузырьковая... но это ещё ничего не значит.
EP>>>Такой Array и другие контейнеры нужно делать для каждого типа данных. У тебя будут FooArray, BarArray, FooPriorityQueue, BarPriorityQueue и т.д. EP>>>Либо как вариант добавлять лишней динамичности, но от неё будут свои тормоза, причём как размеры заранее не известны. dot>>В LL не так уж и много разных структур. EP>Ты постоянно говоришь о каком-то одном use-case'ы. EP>Даже если и мало — всё равно придётся опускаться на очень низкий уровень, исключительно из-за самого языка.
Я и не изобретаю общую теорию всего, а решаю практические задачи.
dot>>И, как и в С++, и, скорее, всего будут поверх array. EP>Это ты о чём? EP>Например на C++ есть выгода от структур (в смысле хранения по значению) даже для вещей типа сбалансированных деревьев — так как уменьшает количество индерекций — само значение хранится в узле, а не указатель на значение.
Так храни так же и в Java, т.е. приведённый выше array, не вижу проблему. Данные и их хранение те же, а алгоритмы — варьируй в методах классов (хотя почему-то ты решил отменить классы).
Если ты про ссылочное дерево — то уже всё плохо, ибо оно не будет в памяти последовательно.
dot>>>>Да, выглядит некрасиво, но обычно составляет <0.1% кода и сложностей никаких не доставляет. EP>>>Это одна из главных причин тормозов в языках с превалирующей pointer semantics. Положил класс с несколькими полями-объектами в массив — уже на ровном месте выросло целое дерево индерекций и аллокаций. dot>>В C++ можно тоже кучу главных причин тормозов придумать. Скажем, передача by-value. Непонятно только к чему это. EP>Так тут есть простой выбор — by-value или by-reference. Это совершенно не тоже самое что и засучив рукава нарезать байт-буфера на структуры
by-value — и тут ВНЕЗАПНО появляется O(N) от числа живых объектов.
by-reference — и тут начинаются проблемы с временем жизни, засучив рукава начинаешь решать проблемы владения.
EP>>>Нет, не хуже, также как и обычный вариант. В реализации — да, код не самый простой, но она пишется один раз. EP>>>Да и это же Array of Structures, нужно не так часто. Речь же про то, что в Java же нет самых обычных структур — для быстрого кода это супер-критично, именно поэтому и нарезают вручную. dot>>Критически быстрого кода не так много. А значит "нужно не так часто". EP>Мы же быстрый код обсуждаем?
Быстрый hello world никому не нужен. Нужна большая и сложная система с быстрыми частями.
EP>>>Хуже, намного. Разве пример со структурами тебя не убедил? — это реально уровень ниже чем C, на ровном месте. Так это только один аспект. EP>>>Быстрый код на C++ можно писать на высоком уровне абстракции — не нужно отказываться ни от замыканий, ни от классов, ни от ФВП и полиморфизма — и при этом он будет давать точно такое же (либо практически такое же) быстродействие как и такой же код написанный на низком уровне вручную — в этом одна из главных фишек C++. dot>>Тут не фичи и уровни абстракции, а хранение и передача данных главное. И там и там об этом надо заботиться. В Яве — не создавать лишних индирекций, в плюса — не делать лишних копий и аккуратно заботиться о владении. Ведь тоже ничего хорошего в том, когда все эти уровни абстракции только и делают, что решают проблемы владения, тогда как в яве оно само, из коробки. EP>Это уже передёргивание. Да, работу с памятью GC упрощают (при этом не гарантируя отсутствие утечек).
Зато гарантируется отсутствие битых ссыслок.
EP>Да, на C++ нужно думать/помнить о владении (это не означает что каждый new на Java превращается в *_ptr). EP>Нет, уровни абстракции о которых я говорю решают далеко не только проблемы владения — они позволяют писать высокоуровневый И быстрый код.
Это мы переходим в другую плоскость — выразительность языка, а не собственно JVM/GC. Для JVM есть и другие языки — Scala, Ceylon, Kotlin и прочее, которые позволяют и многие твои любимые абстракции.
Выразительность языка с другой стороны стреляет отстутсвием нормальной IDE.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>>>Причём это происходит по вине самого GC. dot>>Ну подкрути параметры чуток, не проблема. EP>Это уберёт линейную сложность?
Да. Линейная сложность это худший случай, когда у тебя постоянно меняются указатели в большинтсве живых объектов и постоянно создаются новые. В такой ситуации С++ тоже не поздоровится — и фрагментация кучи, и возрастающая сложность malloc/free.
dot>>>>Не понимаю каким образом ты избежишь ООМ в таком случае в плюсах? EP>>>Нет линейной зависимости времени очистки от количества живых объектов. В случае же GC, на одной и той же скорости входящего потока он может либо успевать очищать, либо нет — и это сильно зависит от текущего количества живых объектов. dot>>Если ты в С++ заведёшь очередь для очистки — столкнёшься ровно с той же проблемой. Не вижу разницы. EP>В очереди объекты которые уже готовы для очистки. А вот сколько там живых reachable объектов — не важно, пусть хоть десять миллиардов.
Ты представляешь как поплохеет системе когда туча тредов будет пихать миллиарды объекты в одну единственную очередь, обрабатываемую одним несчастным потоком?
EP>>>Зачем? dot>>Определить граф-остаток. EP>Зачем его определять? Что это даст? EP>Пока не превысим бюджет времени — удаляем сами, как только времени осталось меньше чем требует max объект — ставим остаток в очередь.
Так как мы конкретно будем этот бюджет считать?
EP>>>Очередь может быть thread local. dot>>И кто из этой очереди будет обрабатывать элементы? Сам thread — не может отвлекаться, он LL, в любую наносекунду может прийти новый запрос. EP>От задачи зависит, может и сам thread. А может и отдельный thread, при этом contention с другими потоками всё равно не будет — так как очередь SPSC.
Мы вроде рассматриваем случай, когда sharedPtr.release может начаться из разных тредов. Как ты собираешься использовать single writer структуру?
dot>>Это тоже подзадача GC — решать сразу или отложить. EP>А ещё в подзадачах GC есть сложение целых.
Хорошо, не подзадача, а средство достижения заявленных характеристик.
EP>>>Разница в том, что написанная библиотека используется внутри самого host-языка. То есть эти gc_ptr — они используется не внутри какой-то виртуальной среды созданной библиотекой, а внутри вызывающего host-языка. dot>>Так и деструкторы и прочие С++ фишки можно реализовать в java, EP>Каким образом ты реализуешь деструкторы? Какое будет использование? Каким образом реализуешь например Expression Templates и прочие compile-time EDSL?
А зачем compile time? Я знаю, что C++ compile time — Turing Complete, но в общем-то и в Java можно сделать плугин для компилятора или load-time кодогенерацию.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай