Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Arsen.Shnurkov  
Дата: 05.08.16 14:28
Оценка: :))) :)
Собственно, сборка мусора в Rust есть (опционально), а такого мощного статического анализатора в C# нет.
Re: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Arsen.Shnurkov  
Дата: 05.08.16 15:53
Оценка: :))) :))
Sinix — ну вот что ты улыбаешься? Сам же присылал ссылки на статьи, где сказано, что сборщик мусора от MS неприемлем для Web-проектов. А в расте такие проблемы можно избежать.
Десктоп умер, теперь облака и мобильники. И там и там — дорога расту. (На мобильниках — Redox, Robigalia )
Re: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: velkin Земля  
Дата: 05.08.16 16:15
Оценка: +8 :))
Здравствуйте, Arsen.Shnurkov, Вы писали:

AS>Собственно, сборка мусора в Rust есть (опционально), а такого мощного статического анализатора в C# нет.


Всё будет убито сиплюсплюсом.
Re: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: vsb Казахстан  
Дата: 05.08.16 16:16
Оценка: +1 -1
Rust слишком сложный язык, чтобы занять сколь-нибудь значимую долю на рынке, не говоря уже о том, чтобы убить Java.
Re[2]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Arsen.Shnurkov  
Дата: 05.08.16 16:20
Оценка: -3
V>Всё будет убито сиплюсплюсом.

Это ненадолго. Да сейчас есть небольшой прогресс с Qt, но поскольку десктоп умирает целиком, то Qt умрёт вместе с WPF.

JavaScript поверх Rust в Web, JavaScript вместо bash на серверах — вот наше будущее. А Rust выдавит .Net вместе с питоном.
Re[3]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: velkin Земля  
Дата: 05.08.16 16:24
Оценка:
Здравствуйте, Arsen.Shnurkov, Вы писали:

AS>Это ненадолго. Да сейчас есть небольшой прогресс с Qt, но поскольку десктоп умирает целиком, то Qt умрёт вместе с WPF.


Я говорю всё будет убито сиплюсплюсом, а кьют это лишь одна из библиотек в парадигме ООП.
Отредактировано 05.08.2016 16:25 velkin . Предыдущая версия .
Re[4]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Arsen.Shnurkov  
Дата: 05.08.16 16:39
Оценка: -2 :)
V> а кьют это лишь одна из библиотек

А больше C++ ни для чего не используется. Во всех остальных местах python и web.
Это как фортран/кобол — остались редкие штучные специалисты вроде тебя,
а новые программисты C++ учить уже не будут.
Re[5]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: velkin Земля  
Дата: 05.08.16 18:24
Оценка: 3 (1) +3
Здравствуйте, Arsen.Shnurkov, Вы писали:

V>> а кьют это лишь одна из библиотек


AS>А больше C++ ни для чего не используется. Во всех остальных местах python и web.


Как говаривал Страуструп, что он не будет заострять внимание на Си, так как те кто знают C++ легче переходят на него, чем наоборот. Имея связку C/C++ мы получаем абсолютно подавляющее превосходство над всеми языками. В наличии доступно четыре парадигмы:

1)с процедурное программирование
2)и функциональное программирование
3)+ объектно-ориентированное программирование
4)+ обобщённое программирование (шаблоны C++)


В итоге C/C++ это драйвера, серверы, прикладные приложения, игры, CAD и многое другое. Взять тот же web, на чём он базируется? А базируется он на серверах. На чём написаны сервера? На C/C++.

Причём не смотря на использование Си, парадигма обобщённого программирования C++ способна его полностью заменить без какой-либо потери быстродействия. Живучесть C/C++ банальна и основывается на том, что так уж получилось, что эти языки стали основой для всего остального.

Я, кстати, не агитирую всё бросать и срочно начинать учить C++, мне и самому лень. Но вот чисто для примера:

1) базы данных
SQLite Си
MySQL C/C++
PostgreSQL Си

2) веб-сервера
Apache Си
Nginx Си
Lighttpd Си
IIS C++

И так куда ни кинь, ну пусть:

3) прикладные приложения
Qt C++
GTK+ Си
WxWidgets C++

Можно очень долго перечислять, начиная с библиотек и заканчивая огромным множеством программ. Чтобы убить C/C++ придётся разрушить фундамент на котором строится современное ПО, так как это и есть сам фундамент. Скажу даже более, если стереть все программы, которые используют C/C++ компьютеры вообще не будут работать, просто потому, что там нечему и не на чем будет работать. А если стереть какой-нибудь python, java, php и прочее, то ситуация будет хоть и крайне неприятной, но не столь плачевной.

AS>Это как фортран/кобол — остались редкие штучные специалисты вроде тебя,


Было бы хорошо, если бы я действительно был специалистом в C++. Но к слову не вижу программ на фортране и коболе, а на C/C++ их просто море. Причём те которые на Си для меня не сказал бы что особо отличимы от тех, которые на C++. Я скорее вижу различие парадигм и элементы, которые есть только в C++, но нет в Си.

AS>а новые программисты C++ учить уже не будут.


Это их дело, вон некоторые уже давно утверждают, что в будущем компьютеры будут сами себя программировать, а программисты станут не нужны.
Re[2]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Sinix  
Дата: 05.08.16 19:25
Оценка: 2 (1) +1
Здравствуйте, Arsen.Shnurkov, Вы писали:

AS>Sinix — ну вот что ты улыбаешься?

Глубине анализа и неопровержимости аргументов

AS>Сам же присылал ссылки на статьи, где сказано, что сборщик мусора от MS неприемлем для Web-проектов.

Эмм??? А можно ссылочку?

Что-то не припоминаю ничего. Может быть, про войну с GC в kestrel? Которая следствие решения сделать критичную часть API поверх генерик-интерфейсов коллекций (IDictionary который). И вылезает оно при не совсем типичных нагрузках, в районе 10e6 RPS.

Если не считать правильный способ — просто использовать свою коллекцию с структурой-итератором — то решений для этой экзотики есть как минимум четыре.
* stackalloc (идеальное по затраты / выигрыш).
* soft-realtime GC (в недрах MS research похоронены как минимум три реализации (а всего CIL-совместимых реализаций GC, по слухам, несколько десятков), ссылки на исследовательские pdf-ки, если надо, поищу).
* hot-path recompilation с агрессивным инлайнингом (заготовки тоже можно позаимствовать у JS team всё того же MS research).
* .net native, который по производительности сможет вплотную приблизиться к плюсам (и по времени компиляции — тоже).


AS>Десктоп умер, теперь облака и мобильники. И там и там — дорога расту. (На мобильниках — Redox, Robigalia )

Ребят, вам не надоедает? Буквально каждые три-четыре месяца кто-то торжественно объявляет новый закапыватель для %подставить_язык%. На практике, правда, про закапывателя уже через год никто не вспоминает, даже сами агитаторы за.

Единственное, что с натяжкой можно назвать выстрелившим за последние лет десять — TypeScript. И то только потому, что необходимость подобной штуки была очевидна, а конкуренты как-то умудрились забить на совместимость с JS.
Re[6]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: r.kamenskiy Россия  
Дата: 05.08.16 20:20
Оценка: +2 -2 :)))
Здравствуйте, velkin, Вы писали:

V>Я, кстати, не агитирую всё бросать и срочно начинать учить C++, мне и самому лень. Но вот чисто для примера:


А есть примеры приложений написаных не во времена, когда и выбора то особо не было?
Ну серьезно. mysql — 21 год, postgresql — 20 лет.

Не вижу причин сейчас начинать новый проект на C++
Re[7]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Arsen.Shnurkov  
Дата: 05.08.16 20:36
Оценка: :)
RK> Не вижу причин сейчас начинать новый проект на C++

да! Rust рождён для GPU ! Именно с переносом на GPU рендеринга HTML удалось разогнать браузерный движок рендеринга Servo.
Re[7]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: so5team https://stiffstream.com
Дата: 06.08.16 12:59
Оценка: +1
Здравствуйте, r.kamenskiy, Вы писали:

RK>А есть примеры приложений написаных не во времена, когда и выбора то особо не было?


MongoDB, RethinkDB, ScyllaDB, ClickHouse

RK>Не вижу причин сейчас начинать новый проект на C++


Ну т.е. совсем никаких причин вне зависимости от предметной области, требований, сроков, бюджетов, имеющихся наработок и пр. сопутствующих условий?
Re[8]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: r.kamenskiy Россия  
Дата: 06.08.16 13:29
Оценка:
Здравствуйте, so5team, Вы писали:

S>Ну т.е. совсем никаких причин вне зависимости от предметной области, требований, сроков, бюджетов, имеющихся наработок и пр. сопутствующих условий?


Ну понятно, что если других вариантов нет, кроме плюсов — то выбирать не придется. Здесь же подразумевалось, что если есть выбор, то выбран будет не с++
Re[9]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: so5team https://stiffstream.com
Дата: 06.08.16 13:41
Оценка: +2
Здравствуйте, r.kamenskiy, Вы писали:

S>>Ну т.е. совсем никаких причин вне зависимости от предметной области, требований, сроков, бюджетов, имеющихся наработок и пр. сопутствующих условий?


RK>Ну понятно, что если других вариантов нет, кроме плюсов — то выбирать не придется. Здесь же подразумевалось, что если есть выбор, то выбран будет не с++


Началось все с "Не вижу причин сейчас начинать новый проект на C++", а пришло к "если других вариантов нет, кроме плюсов — то выбирать не придется".

Давайте сделаем еще одну попытку: когда лично вы сделаете для себя вывод о том, что "других вариантов" нет? По каким критериям вы определяете "Ну понятно"?
Re[10]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: r.kamenskiy Россия  
Дата: 06.08.16 14:26
Оценка:
Здравствуйте, so5team, Вы писали:

S>Началось все с "Не вижу причин сейчас начинать новый проект на C++", а пришло к "если других вариантов нет, кроме плюсов — то выбирать не придется".


Ну вроде очевидно, что если выбора нет — то его просто нет. Бывает, что нет выбора и писать нужно на Fortran. И это не отменяет того, что в общем случае я не вижу причин начинать новый проект на Fortran

S>Давайте сделаем еще одну попытку: когда лично вы сделаете для себя вывод о том, что "других вариантов" нет? По каким критериям вы определяете "Ну понятно"?


— embedded
— драйвера

Здесь обычно выбор между ассембелом и C/C++
Re[11]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: so5team https://stiffstream.com
Дата: 06.08.16 14:37
Оценка: +2
Здравствуйте, r.kamenskiy, Вы писали:

RK>Ну вроде очевидно, что если выбора нет — то его просто нет.


По-моему, очевидно, что отсутствие выбора -- это вполне себе причина. Вы эту причину одновременно и признаете, и не видите. Как так?

S>>Давайте сделаем еще одну попытку: когда лично вы сделаете для себя вывод о том, что "других вариантов" нет? По каким критериям вы определяете "Ну понятно"?


RK>- embedded

RK>- драйвера

RK>Здесь обычно выбор между ассембелом и C/C++


Выше по ветке были приведены примеры приложений, разработанных на C++, которые ни в коем разе не относятся ни к embedded, ни к драйверам. Тем не менее, выбор C++ для них выглядит более адекватным, чем выбор каких-то других языков.
Re[8]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 06.08.16 15:36
Оценка: +2
Здравствуйте, so5team, Вы писали:

RK>>А есть примеры приложений написаных не во времена, когда и выбора то особо не было?

S>MongoDB, RethinkDB, ScyllaDB, ClickHouse

Пример из другой области — Facebook Moments:


There are many alternatives for sharing code between mobile platforms. We wanted to optimize for fast iteration, app performance, and native look and feel. After weighing the alternatives, we chose to write the UI in platform-specific code and the business logic in shared code using C++. Traditionally, C++ is known for providing high performance while lacking easy memory management and higher-level abstractions. However, using modern C++11 features such as std::shared_ptr reference counting, lambda functions, and auto variable declarations, we were able to quickly implement highly performant, memory-safe code.

Цитата из недр того же Facebook:

"The going word at Facebook is that 'reasonably written C++ code just runs fast,' which underscores the enormous effort spent at optimizing PHP and Java code. Paradoxically, C++ code is more difficult to write than in other languages, but efficient code is a lot easier [to write in C++ than in other languages]." – Herb Sutter at //build/, quoting Andrei Alexandrescu

Re: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: SI_16  
Дата: 06.08.16 20:05
Оценка: +2
Здравствуйте, Arsen.Shnurkov, Вы писали:

AS>сборка мусора в Rust есть (опционально)

Нет, такой опции на сегодняшний день нет.
Re[7]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Denwer Россия  
Дата: 07.08.16 15:08
Оценка: 6 (4) +2
Здравствуйте, r.kamenskiy, Вы писали:

RK>Не вижу причин сейчас начинать новый проект на C++


Мы свой проект сделали на С++(использовали Qt), конкуренты на Java. Теперь клиенты плюются на их софт, тормозной и жрущий память. А времени и денег влито уже очень много, что бы взять и переписать заново на с++. Причем они то думали что на жабе у них реальная кросплатформенность получится, а как оказалось нужен мощный комп и про всякие планшеты можно забыть. А у нас без проблем на слабом железе не просто работает, а летает.
Re: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: DreamMaker  
Дата: 07.08.16 18:09
Оценка:
Здравствуйте, Arsen.Shnurkov, Вы писали:


а не заржавеет?


AS>Собственно, сборка мусора в Rust есть (опционально), а такого мощного статического анализатора в C# нет.



суперстатический анализатор — даешь код, а он говорит: "ваш код — говно!", и он прав...
In P=NP we trust.
Re[8]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: DreamMaker  
Дата: 07.08.16 18:12
Оценка:
Здравствуйте, Denwer, Вы писали:

D>Мы свой проект сделали на С++(использовали Qt), конкуренты на Java. Теперь клиенты плюются на их софт, тормозной и жрущий память.


а что за проект, ну, примерно?

производительность в основном зависит от используемых алгоритмов.. по-настоящему талантливый быдлокодер хоть на асме напишет так, что безбожно тормозить будет.
ну раза в полтора разницу я могу еще поверить что с++ за счет нативности поимел, но не более того.
In P=NP we trust.
Re[11]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: CreatorCray  
Дата: 07.08.16 18:25
Оценка:
Здравствуйте, r.kamenskiy, Вы писали:

RK>Здесь обычно выбор между ассембелом и C/C++

Я бы вычекнул ассемблер. Уже давно для всех вменяемых платформ есть как минимум С.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[9]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 07.08.16 19:41
Оценка: 2 (2) +1 -1 :)))
Здравствуйте, DreamMaker, Вы писали:

DM>производительность в основном зависит от используемых алгоритмов.. по-настоящему талантливый быдлокодер хоть на асме напишет так, что безбожно тормозить будет.


Да, да, да, "всё в базу упираются", "мы вас на алгоритмах заборем", "сделаем быстрее на 2000%" — старые песни о главном

DM>ну раза в полтора разницу я могу еще поверить что с++ за счет нативности поимел, но не более того.


Как ты тогда объяснишь факт того, что C++ скомпилированный в ненативный JavaScript (в веб-браузере, Карл!) оказался практически в два раза быстрее кода на C#? (1
Автор: Evgeny.Panasyuk
Дата: 07.06.15
, 2
Автор: Evgeny.Panasyuk
Дата: 20.06.15
)

C++ быстрый не от того что нативный, а от того что даёт бесплатные, либо крайне дешёвые абстракции.
Если на C#/Java писать код без абстракций, то по скорости он будет близок к аналогу на C++ — но такого кода будет намного больше, либо придётся писать кодогенераторы по сути эмулирующие работу компиляторов C++. Собственно подобной хренью
Автор: Evgeny.Panasyuk
Дата: 23.03.16
и приходится заниматься на управляемых языках
Re[10]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 07.08.16 20:56
Оценка:
Sinix, а что смешного? Ты же сам намерял >8x
Автор: Sinix
Дата: 16.07.16
abstraction penalty на C#.
Re: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: kochetkov.vladimir Россия https://kochetkov.github.io
Дата: 07.08.16 21:55
Оценка:
Здравствуйте, Arsen.Shnurkov, Вы писали:

AS>Собственно, сборка мусора в Rust есть (опционально), а такого мощного статического анализатора в C# нет.


А где можно почитать про мощный статанализатор Rust?
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>

[Интервью] .NET Security — это просто
Автор: kochetkov.vladimir
Дата: 07.11.17
Re[10]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Ночной Смотрящий Россия  
Дата: 07.08.16 22:38
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Собственно подобной хренью
Автор: Evgeny.Panasyuk
Дата: 23.03.16
и приходится заниматься на управляемых языках


Тебя, похоже, окончательно заклинило.
Re[11]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 07.08.16 22:53
Оценка: :))
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Тебя, похоже, окончательно заклинило.


Ты, похоже, помимо того что врун
Автор: Evgeny.Panasyuk
Дата: 06.07.16
, так ещё и хамло
Re[9]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: so5team https://stiffstream.com
Дата: 08.08.16 06:26
Оценка:
Здравствуйте, DreamMaker, Вы писали:

DM>ну раза в полтора разницу я могу еще поверить


Т.е. вы можете поверить, что только из-за использования C++ вместо Java видеофайл обрабатывается за 60 минут вместо 90 минут, нода держит 150K коннектов вместо 100K, время отклика составляет 100ms вместо 150ms... Но вот поверить в то, что просадка по производительности в 1.5 раза может кем-то восприниматься как тормознутость, уже не можете?
Re[2]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 08.08.16 07:01
Оценка:
Здравствуйте, kochetkov.vladimir, Вы писали:

AS>>Собственно, сборка мусора в Rust есть (опционально), а такого мощного статического анализатора в C# нет.

KV>А где можно почитать про мощный статанализатор Rust?

Предполагаю что имелись в виду разнообразные статические ограничения, borrow checker, lifetime inference и т.п.
Re[11]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Sinix  
Дата: 08.08.16 07:30
Оценка: +3
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Sinix, а что смешного? Ты же сам намерял >8x
Автор: Sinix
Дата: 16.07.16
abstraction penalty на C#.


Ну как сказать... вот первоначальная цитата:

Вот тут C++ код скомпированный в JavaScript и запущенный в Firefox показывает скорость близкую к native'у — 75ms, на native C++ было 60ms, на C# — 69ms.
Если на C# использовать не низкоуровневый цикл, а transform и лямбду (как было на C++) — то получается 141ms.


Она у тебя магией превращается в

C++ скомпилированный в ненативный JavaScript (в веб-браузере, Карл!) оказался практически в два раза быстрее кода на C#?


Ну да блин, _внезапно_ шарп не инлайнит делегаты, не использует автоматом simd, не выполняет автовекторизацию и не делает ещё кучу плюшек (что, в принципе, может быть поправлено в .net native, но явно не в ближайшем будущем). Ну так про это и надо писать, а не передёргивать.

Попробую намекнуть: в том же топике тот же самый код, скормленный компилятору 2013й студии выполнялся с Elapsed = 189.011 ms. Собсно вопрос: как я буду выглядеть, если из топика в топик буду рассказывать, что шарп быстрей плюсов в три раза (куча восклицательных знаков, му-ха-ха по выбору)?


UPD
EP>Ты же сам намерял >8x
Автор: Sinix
Дата: 16.07.16
abstraction penalty на C#.


Ну так снова то же самое — сравниваем вариант с вызовом делегата и без делегата внутри tight loop при очень дешёвом делегате. Для боль-менее тяжёлого кода (см результаты для сравнения строк) разницы не видно, для критичных мест можно не полениться и расписать вручную. Хотя правильный вариант, разумеется, пересмотреть алгоритм. Потому что утыкаться в "мы миллионы раз в секунду ищем элемент с минимальным значением поля"... Тут точно надо консерваторию править.
Отредактировано 08.08.2016 7:41 Sinix . Предыдущая версия .
Re[12]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 08.08.16 07:58
Оценка: +1
Здравствуйте, Sinix, Вы писали:

EP>>Sinix, а что смешного? Ты же сам намерял >8x
Автор: Sinix
Дата: 16.07.16
abstraction penalty на C#.

S>Ну как сказать... вот первоначальная цитата:
S>

S>Вот тут C++ код скомпированный в JavaScript и запущенный в Firefox показывает скорость близкую к native'у — 75ms, на native C++ было 60ms, на C# — 69ms.
S>Если на C# использовать не низкоуровневый цикл, а transform и лямбду (как было на C++) — то получается 141ms.

S>Она у тебя магией превращается в
S>

S>C++ скомпилированный в ненативный JavaScript (в веб-браузере, Карл!) оказался практически в два раза быстрее кода на C#?

S>Ну да блин, _внезапно_ шарп не инлайнит делегаты, не использует автоматом simd, не выполняет автовекторизацию и не делает ещё кучу плюшек (что, в принципе, может быть поправлено в .net native, но явно не в ближайшем будущем). Ну так про это и надо писать, а не передёргивать.

Я не передёргиваю, это же как раз отличная иллюстрация тому что я написал в том же сообщении:

EP>C++ быстрый не от того что нативный, а от того что даёт бесплатные, либо крайне дешёвые абстракции.
EP>Если на C#/Java писать код без абстракций, то по скорости он будет близок к аналогу на C++ — но такого кода будет намного больше

Или ты не дочитал до этого места?
То есть код на одинаковом уровне абстракций оказался медленнее почти в два раза (медленнее чем в веб-браузере, Карл!)
А вот код на C# написанный на более низком уровне, уже приблизился к высокоуровнему коду C++ по скорости. О чём и речь — на C# можно написать быстрый код, но это будет низкоуровневая лапша, на Java ситуация ещё хуже из-за отсутствия структур

S>не использует автоматом simd, не выполняет автовекторизацию и не делает ещё кучу плюшек (что, в принципе, может быть поправлено в .net native, но явно не в ближайшем будущем).


Думаешь JavaScript там сделал автовекторизацию и заиспользовал SIMD?

S>UPD

EP>>Ты же сам намерял >8x
Автор: Sinix
Дата: 16.07.16
abstraction penalty на C#.

S>Ну так снова то же самое — сравниваем вариант с вызовом делегата и без делегата внутри tight loop при очень дешёвом делегате.

Так это abstraction penalty и есть, которой нет на C++. И чем больше уровней абстрации — тем больше penalty, это были всё примеры с примитивнейшими абстракциями.

S>для критичных мест можно не полениться и расписать вручную


Так а я о чём — на C# для быстрого кода "нельзя лениться" и приходится раскорячиваться

EP>Если на C#/Java писать код без абстракций, то по скорости он будет близок к аналогу на C++ — но такого кода будет намного больше

Отредактировано 08.08.2016 8:30 Evgeny.Panasyuk . Предыдущая версия . Еще …
Отредактировано 08.08.2016 8:30 Evgeny.Panasyuk . Предыдущая версия .
Re[13]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 08.08.16 09:32
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>То есть код на одинаковом уровне абстракций оказался медленнее почти в два раза (медленнее чем в веб-браузере, Карл!)
Так, а за что тогда я извинялся за 2 раза?
Ну вот в .Net Native и будут инлайнить как в C++. Про, что тебе Sinix и говорит.
и солнце б утром не вставало, когда бы не было меня
Re[12]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: koandrew Канада http://thingselectronic.blogspot.ca/
Дата: 08.08.16 15:32
Оценка:
Здравствуйте, CreatorCray, Вы писали:

CC>Я бы вычекнул ассемблер. Уже давно для всех вменяемых платформ есть как минимум С.


Однако даже там крайне полезно хотя бы в общих чертах знать ассемблер этой платформы, дабы быть в состоянии разобраться, чего там такого накомпилировал компилер, что нифига не работает
[КУ] оккупировала армия.
Re[14]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 08.08.16 15:47
Оценка:
Здравствуйте, Serginio1, Вы писали:

EP>>То есть код на одинаковом уровне абстракций оказался медленнее почти в два раза (медленнее чем в веб-браузере, Карл!)

S> Так, а за что тогда я извинялся за 2 раза?
S> Ну вот в .Net Native и будут инлайнить как в C++. Про, что тебе Sinix и говорит.

Как начнут инлайнить, так и сравним. Напоминаю что ветка началась с рассуждений о том что актуально использовать сейчас.
А в сферическом будущем могут например и для Python сделать супер оптимизатор без abstraction penalty.
Также выше был высказан очередной миф — мол C++ быстрее за счёт нативности "но не более того". Пример с компилированием C++ -> JavaScript и сравнением с аналогом на C# развеивает этот миф
Re[13]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: CreatorCray  
Дата: 08.08.16 17:23
Оценка: +1
Здравствуйте, koandrew, Вы писали:

K>Однако даже там крайне полезно хотя бы в общих чертах знать ассемблер этой платформы

Знать — обязательно, тут даже вопроса стоять не должно.
Но писать на нём не придётся ничего в 99% случаев.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[15]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 09.08.16 08:22
Оценка: -1
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здравствуйте, Serginio1, Вы писали:


EP>>>То есть код на одинаковом уровне абстракций оказался медленнее почти в два раза (медленнее чем в веб-браузере, Карл!)

S>> Так, а за что тогда я извинялся за 2 раза?
S>> Ну вот в .Net Native и будут инлайнить как в C++. Про, что тебе Sinix и говорит.

EP>Как начнут инлайнить, так и сравним. Напоминаю что ветка началась с рассуждений о том что актуально использовать сейчас.

EP>А в сферическом будущем могут например и для Python сделать супер оптимизатор без abstraction penalty.
EP>Также выше был высказан очередной миф — мол C++ быстрее за счёт нативности "но не более того". Пример с компилированием C++ -> JavaScript и сравнением с аналогом на C# развеивает этот миф

Еще раз С++ выигрывает за счет инлайнинга это известно всем. Шаблоны в отличие от дженериков по сути раскручиваются в исходный код с инлайнингом методов.
Вот и вся магия. Это же раскручивание можно сделать и для дженериков. Большой то разницы нет. Просто в .Net еще большие тормоза из-за рефлексии, так как при оптимизации кода нужно предоставить доступ для отображения. Поэтому в .Net Native рефлексию сильно ограничили вплоть до полного отказа.
А насчет питона, то он уже стал статически типизированным? https://habrahabr.ru/company/mailru/blog/242305/
Но на самом деле мало это кому нужно. Числодробилками мало кто занимается, а во главе угла скорость разработки.
Но возможность приблизить скорость выполнения .Net код к C++ это просто небольшой плюсик не более, что бы убрать у С++ ников их главный козырь.
и солнце б утром не вставало, когда бы не было меня
Re[16]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: CreatorCray  
Дата: 09.08.16 09:13
Оценка:
Здравствуйте, Serginio1, Вы писали:

S> Но на самом деле мало это кому нужно. Числодробилками мало кто занимается, а во главе угла скорость разработки.

На скорость разработки сильно влияют наличие готовых панельных бетонных блоков — универсальных библиотек, из которых можно быстро склепать многоэтажку.
Весь этот инструментарий, который позволяет хреначить не приходя в сознание как раз для "хренак, хренак и в продакшен" подходит очень даже хорошо.
Но вот проблема в том, что generic решения все построены на компромиссах, например "универсальность в ущерб производительности". Зато каждую панельку можно найти поимённо и посмотреть какие отчества у каждого камушка в ней.
Но когда возведение 18го этажа подходит к концу и вдруг выясняется что лифт на него едет сутки то тогда весь выигрыш в скорости клепания может быть съеден временем, потраченным на обтачивание уже выстроенных плит надфилями, чтоб лифт таки ехал быстрее.
Не, ну если надо нафигачить панельку из 5 этажей, где лифт не предусмотрен (юзеры пешкарусом дойдут!), или этажей в 10 где и на верхние этажи лифт едет всего то час (потерпят!), то тогда ок.
Порой народ вынужден вспоминать старые добрые техники из unmanaged, доставать надфили, распиливать ими панели на кирпичики и собирать из этих кирпичиков полупостроенный дом заново.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[17]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 09.08.16 10:50
Оценка:
Здравствуйте, CreatorCray, Вы писали:


CC>Но когда возведение 18го этажа подходит к концу и вдруг выясняется что лифт на него едет сутки то тогда весь выигрыш в скорости клепания может быть съеден временем, потраченным на обтачивание уже выстроенных плит надфилями, чтоб лифт таки ехал быстрее.

CC>Не, ну если надо нафигачить панельку из 5 этажей, где лифт не предусмотрен (юзеры пешкарусом дойдут!), или этажей в 10 где и на верхние этажи лифт едет всего то час (потерпят!), то тогда ок.
CC>Порой народ вынужден вспоминать старые добрые техники из unmanaged, доставать надфили, распиливать ими панели на кирпичики и собирать из этих кирпичиков полупостроенный дом заново.

Тогда зачем нужен будет C++. А так, MS и разрабатывает .Net Native, где в дженериках будут инлайнится переданные делегаты (функторы,лямбды). Вот с интерфейсами уже можно и в рантайме разбираться.
Все как в С++, такм тот же компилятор.
https://msdn.microsoft.com/ru-ru/library/dn584397(v=vs.110).aspx


.NET Native использует то же сервер, что и компилятор C++, который оптимизирован для статических сценариев предварительной компиляции.

.NET Native способна обеспечить повышение производительности для C++ разработчиков управляемого кода, так как она использует такие же или аналогичные средства, что и C++ за кулисами, как показано в следующей таблице.

и солнце б утром не вставало, когда бы не было меня
Re[18]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Sinix  
Дата: 09.08.16 11:41
Оценка: 3 (1) +1
Здравствуйте, Serginio1, Вы писали:

S> Тогда зачем нужен будет C++.

Троллинг же.


S> А так, MS и разрабатывает .Net Native, где в дженериках будут инлайнится переданные делегаты (функторы,лямбды).


Одна проблема: если не будет ничего меняться, то это дело _очень_ неблизкое, не следующего за текущим релиза — точно. Пока .native находится в стадии "мы пробуем" — нестабильно всё.
Начиная от пайплайна который крайне своеобразен, т.к. достался в наследство от исследовательского проекта и затем использовался в cloud compiling в wp8 и в предке .native — project N.
И заканчивая собственно бэкендом — старый backend msvc, новый, плюс "беспроигрышный" вариант с RyuJIT AOT + llvm для максимального охвата платформ...

В общем речь сейчас идёт не про "перфоманс любой ценой", а о том, чтобы вылезти из песочницы winRT. Вот как оно состоится — можно будет начинать предметно обсуждать, что можно сделать с производительностью.
Re[16]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: chaotic-kotik  
Дата: 09.08.16 12:49
Оценка:
Здравствуйте, Serginio1, Вы писали:

S> Еще раз С++ выигрывает за счет инлайнинга это известно всем. Шаблоны в отличие от дженериков по сути раскручиваются в исходный код с инлайнингом методов.

S>Вот и вся магия. Это же раскручивание можно сделать и для дженериков. Большой то разницы нет. Просто в .Net еще большие тормоза из-за рефлексии, так как при оптимизации кода нужно предоставить доступ для отображения. Поэтому в .Net Native рефлексию сильно ограничили вплоть до полного отказа.

MS не может добить оптимизатор VC++ до уровня gcc четырехлетней давности (нет нормальной векторизации и девиртуализации). Как можно от них ждать чего-то интересного в .net native?
Re[17]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 09.08.16 13:02
Оценка:
Здравствуйте, chaotic-kotik, Вы писали:

CK>Здравствуйте, Serginio1, Вы писали:


S>> Еще раз С++ выигрывает за счет инлайнинга это известно всем. Шаблоны в отличие от дженериков по сути раскручиваются в исходный код с инлайнингом методов.

S>>Вот и вся магия. Это же раскручивание можно сделать и для дженериков. Большой то разницы нет. Просто в .Net еще большие тормоза из-за рефлексии, так как при оптимизации кода нужно предоставить доступ для отображения. Поэтому в .Net Native рефлексию сильно ограничили вплоть до полного отказа.

CK>MS не может добить оптимизатор VC++ до уровня gcc четырехлетней давности (нет нормальной векторизации и девиртуализации). Как можно от них ждать чего-то интересного в .net native?

Ну если доведут до .net native до gcc четырехлетней давности будет тоже неплохо
Посмотрим. Время покажет. Во всяком случае движение есть.
и солнце б утром не вставало, когда бы не было меня
Re[16]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 09.08.16 13:20
Оценка: +1
Здравствуйте, Serginio1, Вы писали:

S> Еще раз С++ выигрывает за счет инлайнинга это известно всем. Шаблоны в отличие от дженериков по сути раскручиваются в исходный код с инлайнингом методов.

S>Вот и вся магия. Это же раскручивание можно сделать и для дженериков. Большой то разницы нет.

Вообще-то разница огромная.
Например замыкания в C++ можно принимать в ФВП по конкретному типу, то есть без всякого динамического полиморфизма — такое элементарно инлайнится. А вот косвенные вызовы на объектах произвольного размера инлайнить на порядки труднее.
Более того, инлайнинг это не единственный плюс относительно производительности — помимо этого например превалирующая value семантика.

S> А насчет питона, то он уже стал статически типизированным?


А он и не собирался
Я говорю что если брать сферические рассуждения о гипотетической возможности оптимизировать код с тормозных языков до уровня C++ — то да, теоретически это вполне возможно, даже для динамически типизированных

S>Но возможность приблизить скорость выполнения .Net код к C++ это просто небольшой плюсик не более, что бы убрать у С++ ников их главный козырь.


1. Дело-то не в .NET, а в C# — сам язык, его семантика и идиомы не способствуют производительности.
2. Приблизить, то есть убрать некоторые из тормозов — да, возможно. Но выйти на одинаковый уровень — в обозримом будущем маловероятно.
3. Производительность это не единственный козырь C++, помимо этого например кроссплатформенность, и гибкость языка.
  пример
Вот например, на Python можно сделать так (будет работать для любых типов имеющих соответствующие операторы):
def add(x, y):
    return x + y

def sub(x, y):
    return x - y

def apply(f, *args):
    return f(*args)

print(apply(apply, apply, apply, add, 1, 2))
print(apply(apply, apply, sub, 11, 2))

Аналог на C++:
auto add = [](auto x, auto y)
{
    return x + y;
};
auto sub = [](auto x, auto y)
{
    return x - y;
};
auto apply = [](auto f, auto... args)
{
    return f(args...);
};

print(apply(apply, apply, apply, add, 1, 2));
print(apply(apply, apply, sub, 11, 2));

На C# будет облом.
Отредактировано 09.08.2016 13:22 Evgeny.Panasyuk . Предыдущая версия .
Re[17]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 09.08.16 13:51
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здравствуйте, Serginio1, Вы писали:


S>> Еще раз С++ выигрывает за счет инлайнинга это известно всем. Шаблоны в отличие от дженериков по сути раскручиваются в исходный код с инлайнингом методов.

S>>Вот и вся магия. Это же раскручивание можно сделать и для дженериков. Большой то разницы нет.

EP>Вообще-то разница огромная.

EP>Например замыкания в C++ можно принимать в ФВП по конкретному типу, то есть без всякого динамического полиморфизма — такое элементарно инлайнится. А вот косвенные вызовы на объектах произвольного размера инлайнить на порядки труднее.
EP>Более того, инлайнинг это не единственный плюс относительно производительности — помимо этого например превалирующая value семантика.
Так и в C# тоже можно. Так же статически можно определить передаваемый тип. Другое дело, когда в динамике принимается интерфейс.
Отсутствие инлайна основная проблема. Для оптимизации никто не запрещает использовать структуры. Да проблема с массивами на стеке (в классе), но это уже мелочи.

S>> А насчет питона, то он уже стал статически типизированным?


EP>А он и не собирался

EP>Я говорю что если брать сферические рассуждения о гипотетической возможности оптимизировать код с тормозных языков до уровня C++ — то да, теоретически это вполне возможно, даже для динамически типизированных

Ну MS то собирается и делает определенные шаги.
S>>Но возможность приблизить скорость выполнения .Net код к C++ это просто небольшой плюсик не более, что бы убрать у С++ ников их главный козырь.

EP>1. Дело-то не в .NET, а в C# — сам язык, его семантика и идиомы не способствуют производительности.

EP>2. Приблизить, то есть убрать некоторые из тормозов — да, возможно. Но выйти на одинаковый — в обозримом будущем маловероятно.
EP>3. Производительность это не единственный козырь C++, помимо этого например кроссплатформенность, и гибкость языка.
EP>
  пример
EP>Вот например, на Python можно сделать так (будет работать для любых типов имеющих соответствующие операторы):
EP>
EP>def add(x, y):
EP>    return x + y

EP>def sub(x, y):
EP>    return x - y

EP>def apply(f, *args):
EP>    return f(*args)

EP>print(apply(apply, apply, apply, add, 1, 2))
EP>print(apply(apply, apply, sub, 11, 2))
EP>

EP>Аналог на C++:
EP>
EP>auto add = [](auto x, auto y)
EP>{
EP>    return x + y;
EP>};
EP>auto sub = [](auto x, auto y)
EP>{
EP>    return x - y;
EP>};
EP>auto apply = [](auto f, auto... args)
EP>{
EP>    return f(args...);
EP>};

EP>print(apply(apply, apply, apply, add, 1, 2));
EP>print(apply(apply, apply, sub, 11, 2));
EP>

EP>На C# будет облом.


Это все шаблоны. В дженериках можно ввести ограничения. Дп будет не так красиво,

В C# нужно делать контракты, что то типа

T <T>add(T x, T y):where where T : IAdd
  { return x.add(y)}


Но во время компиляции при известном типе x.add(y) будут инлайняться.

Можно по аналогии с расширениями так же добавить аналог утиной типизации.

public static class <int>Extension:IAdd
{
 int add(int y){this+y}
 static int add(int x,y){x+y}

}


В С++ тебе все равно делать перегрузки для +,++ итд.
Аналогично можно сделать и для C#. Просто когда они озаботятся инлайнингом думаю появятся и новые конструкции.
Во всяком случае VladD2 еще на Видби показывал варианты и с инлайнингом где интерфейс реализовывался на структуре
и солнце б утром не вставало, когда бы не было меня
Re[14]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: amater  
Дата: 09.08.16 14:18
Оценка:
Здравствуйте, CreatorCray, Вы писали:

CC>Здравствуйте, koandrew, Вы писали:


K>>Однако даже там крайне полезно хотя бы в общих чертах знать ассемблер этой платформы

CC>Знать — обязательно, тут даже вопроса стоять не должно.
CC>Но писать на нём не придётся ничего в 99% случаев.

Для меня С++ светлое будующее. Пока приходится обходится C. Причем приделываю и объектные подходы как в древнии времена. Но на ассемблере уже несколько лет ничего не делал, и не собираюсь.
Re[18]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 09.08.16 14:26
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>>> Еще раз С++ выигрывает за счет инлайнинга это известно всем. Шаблоны в отличие от дженериков по сути раскручиваются в исходный код с инлайнингом методов.

S>>>Вот и вся магия. Это же раскручивание можно сделать и для дженериков. Большой то разницы нет.
EP>>Вообще-то разница огромная.
EP>>Например замыкания в C++ можно принимать в ФВП по конкретному типу, то есть без всякого динамического полиморфизма — такое элементарно инлайнится. А вот косвенные вызовы на объектах произвольного размера инлайнить на порядки труднее.
EP>>Более того, инлайнинг это не единственный плюс относительно производительности — помимо этого например превалирующая value семантика.
S> Так и в C# тоже можно. Так же статически можно определить передаваемый тип.

C++:
template<typename F>
auto foo(F f)
{
    return f();
}

int main()
{
    auto x = 0;
    return foo([=]{ return x; });
}
Здесь внутри foo, ещё до всяких оптимизаторов, известен и конкретный тип замыкания F, и его размер, и конкретный вызываемый метод.
Аналог на C# в студию.
Re[18]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: chaotic-kotik  
Дата: 09.08.16 14:33
Оценка: +2
Здравствуйте, Serginio1, Вы писали:

S>Отсутствие инлайна основная проблема. Для оптимизации никто не запрещает использовать структуры. Да проблема с массивами на стеке (в классе), но это уже мелочи.


Чтобы работал GC компилятор дотнета вставляет дополнительный код (барьеры). Чтобы проверять на выход за границу массива компилятор дотнета генерирует кучу проверок. Помнится, несколько лет назад, JIT в дотнете не мог очень простой цикл развернуть. А вы тут ждете каких-то чудес производительности от инлайна делегатов. Чтобы приблизиться к С++ по производительности нужно не только компилятор исправить, но и например переписать полностью стандартную библиотеку таким образом, чтобы она не выделяла память на каждый чих без лишней необходимости и чтобы работа на низком уровне абстракции (работа с памятью напрямую) не выглядела так, как она выглядит сейчас. На С++ ведь реально код на порядок проще получается, если нужно писать что-то близкое к железу и производительное.
Re[19]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 09.08.16 14:40
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здравствуйте, Serginio1, Вы писали:


S>>>> Еще раз С++ выигрывает за счет инлайнинга это известно всем. Шаблоны в отличие от дженериков по сути раскручиваются в исходный код с инлайнингом методов.

S>>>>Вот и вся магия. Это же раскручивание можно сделать и для дженериков. Большой то разницы нет.
EP>>>Вообще-то разница огромная.
EP>>>Например замыкания в C++ можно принимать в ФВП по конкретному типу, то есть без всякого динамического полиморфизма — такое элементарно инлайнится. А вот косвенные вызовы на объектах произвольного размера инлайнить на порядки труднее.
EP>>>Более того, инлайнинг это не единственный плюс относительно производительности — помимо этого например превалирующая value семантика.
S>> Так и в C# тоже можно. Так же статически можно определить передаваемый тип.

EP>C++:

EP>
EP>template<typename F>
EP>auto foo(F f)
EP>{
EP>    return f();
EP>}

EP>int main()
EP>{
EP>    auto x = 0;
EP>    return foo([=]{ return x; });
EP>}
EP>
Здесь внутри foo, ещё до всяких оптимизаторов, известен и конкретный тип замыкания F, и его размер, и конкретный вызываемый метод.

EP>Аналог на C# в студию.


 T foo<T>(Func<T> f)
{
  return f();
}

int main()
{
    var x = 0;
    return foo<int>(=>{ return x; });
}


Не знаю может ли вывести тип дженерика, но по идее и так должно работать.
Я например в своей компоненте вывожу тип в рантайме.
и солнце б утром не вставало, когда бы не было меня
Отредактировано 09.08.2016 14:45 Serginio1 . Предыдущая версия .
Re[20]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 09.08.16 14:49
Оценка:
Здравствуйте, Serginio1, Вы писали:

EP>>Здесь внутри foo, ещё до всяких оптимизаторов, известен и конкретный тип замыкания F, и его размер, и конкретный вызываемый метод.

EP>>Аналог на C# в студию
S>
S> T foo<T>(Func<T> f)
S>{
S>  return f();
S>}
S>


О чём и речь — у тебя внутри foo один тип для разных замыканий с одинаковой сигнатурой — а значит динамический полиморфизм и прочие индерекции, которые на порядок сложнее оптимизировать
Re[19]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 09.08.16 14:53
Оценка:
Здравствуйте, chaotic-kotik, Вы писали:

CK>Здравствуйте, Serginio1, Вы писали:


S>>Отсутствие инлайна основная проблема. Для оптимизации никто не запрещает использовать структуры. Да проблема с массивами на стеке (в классе), но это уже мелочи.


CK>Чтобы работал GC компилятор дотнета вставляет дополнительный код (барьеры). Чтобы проверять на выход за границу массива компилятор дотнета генерирует кучу проверок. Помнится, несколько лет назад, JIT в дотнете не мог очень простой цикл развернуть. А вы тут ждете каких-то чудес производительности от инлайна делегатов. Чтобы приблизиться к С++ по производительности нужно не только компилятор исправить, но и например переписать полностью стандартную библиотеку таким образом, чтобы она не выделяла память на каждый чих без лишней необходимости и чтобы работа на низком уровне абстракции (работа с памятью напрямую) не выглядела так, как она выглядит сейчас. На С++ ведь реально код на порядок проще получается, если нужно писать что-то близкое к железу и производительное.


Еще раз повторю. Время идет и все меняется. Те же циклы типа
for(int i=0;i<ar.Length,i++)
    var a=ar[i];

Никаких проверок не будет. А для работы с матрицами есть SIMD.
Речь, не идет о замене C++. Речь идет о увеличении производительности .Net кода.
Большинству не нужна скорость выполнения, а нужна скорость разработки. Я 1С ник, и в большей степени у нас упирается в БД. А вот легкость создания клиент-серверного имеет большее значение
и солнце б утром не вставало, когда бы не было меня
Re[21]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 09.08.16 15:00
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здравствуйте, Serginio1, Вы писали:


EP>>>Здесь внутри foo, ещё до всяких оптимизаторов, известен и конкретный тип замыкания F, и его размер, и конкретный вызываемый метод.

EP>>>Аналог на C# в студию
S>>
S>> T foo<T>(Func<T> f)
S>>{
S>>  return f();
S>>}
S>>


EP>О чём и речь — у тебя внутри foo один тип для разных замыканий с одинаковой сигнатурой — а значит динамический полиморфизм и прочие индерекции, которые на порядок сложнее оптимизировать


На данном этапе да.
Но мы то говорим о компиляторе в стиле C++. А там
return x>>
проинлайнить не проблема на уровне исходников. Хотя можно делать некую промежуточный вариант куда будет вставляться IL код.
Главное, что контракт соблюден.
и солнце б утром не вставало, когда бы не было меня
Re[22]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 09.08.16 15:23
Оценка:
Здравствуйте, Serginio1, Вы писали:

EP>>>>Здесь внутри foo, ещё до всяких оптимизаторов, известен и конкретный тип замыкания F, и его размер, и конкретный вызываемый метод.

EP>>>>Аналог на C# в студию
S>>>
S>>> T foo<T>(Func<T> f)
S>>>{
S>>>  return f();
S>>>}
S>>>

EP>>О чём и речь — у тебя внутри foo один тип для разных замыканий с одинаковой сигнатурой — а значит динамический полиморфизм и прочие индерекции, которые на порядок сложнее оптимизировать
S> На данном этапе да.
S>Но мы то говорим о компиляторе в стиле C++. А там
return x>>
проинлайнить не проблема на уровне исходников.


Подобные штуки (динамический полиморфизм) и компиляторы C++ инлайнят только в простейших вариантах — если же добавить простую аллокацию на пути или что-то подобное, то это становится серьёзным барьером для инлайнинга (тут разве что помогает PGO, да и то частично).
То есть ещё раз, код C# чисто по построению намного труднее оптимизировать — для оптимизаций до уровней аналогичных C++ нужно либо язык модифицировать, либо делать оптимизаторы намного более мощные чем оптимизаторы C++
Re[20]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: chaotic-kotik  
Дата: 09.08.16 15:42
Оценка:
Здравствуйте, Serginio1, Вы писали:

S> Еще раз повторю. Время идет и все меняется. Те же циклы типа

S>
S>for(int i=0;i<ar.Length,i++)
S>    var a=ar[i];
S>

S>Никаких проверок не будет. А для работы с матрицами есть SIMD.

Компилятор С++ вообще этот цикл вырежет, так как он ничего не делает. Либо векторизует, если `a` дальше используется в вычислениях, причем вкорячит туда такой код, который сможет работать даже в случае если массив не выровнен. Ну а компилятор сишарпа даже проверки сможет вырезать только в простых случаях (линейно бежим по массиву). Если есть inderection (вычисляем значение i по таблице, например) — то он не вырежет ничего и будет каждый индекс проверять.
Re[21]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: · Великобритания  
Дата: 09.08.16 15:52
Оценка:
Здравствуйте, chaotic-kotik, Вы писали:

CK>Компилятор С++ вообще этот цикл вырежет, так как он ничего не делает. Либо векторизует, если `a` дальше используется в вычислениях, причем вкорячит туда такой код, который сможет работать даже в случае если массив не выровнен. Ну а компилятор сишарпа даже проверки сможет вырезать только в простых случаях (линейно бежим по массиву). Если есть inderection (вычисляем значение i по таблице, например) — то он не вырежет ничего и будет каждый индекс проверять.

В С++ — другая крайность. Индекс вообще проверяться не будет (вычислили значение i по таблице неправильно и бабах).
А если захочешь безопасностьи то вместо vect[i] будешь использовать vect.at(i) и компилятор С++ столкнётся с той же бедой, что и сишарп.
По-моему, в подавляющем большинстве случаев важнее не бабахать, чем вырезать.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[22]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 09.08.16 16:11
Оценка:
Здравствуйте, ·, Вы писали:

·>В С++ — другая крайность. Индекс вообще проверяться не будет (вычислили значение i по таблице неправильно и бабах).

·>А если захочешь безопасностьи то вместо vect[i] будешь использовать vect.at(i) и компилятор С++ столкнётся с той же бедой, что и сишарп.

Есть третий вариант: во время разработки и тестирования включаются asserts, checked iterators и прочий defensive programming, которые помогают отлавливать подобные проблемы
http://coliru.stacked-crooked.com/a/b70a433c52e5b336
#include <vector>

int main()
{
    std::vector<int> xs;
    xs[5];
}

/usr/local/include/c++/6.1.0/debug/vector:415:
Error: attempt to subscript container with out-of-bounds index 5, but 
container only holds 0 elements.

Objects involved in the operation:
    sequence "this" @ 0x0x7fff719fd1d0 {
      type = std::__debug::vector<int, std::allocator<int> >;
    }
bash: line 7: 14850 Aborted                 (core dumped) ./a.out
Re[23]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: · Великобритания  
Дата: 09.08.16 16:27
Оценка: +5 :)
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>·>В С++ — другая крайность. Индекс вообще проверяться не будет (вычислили значение i по таблице неправильно и бабах).

EP>·>А если захочешь безопасностьи то вместо vect[i] будешь использовать vect.at(i) и компилятор С++ столкнётся с той же бедой, что и сишарп.
EP>Есть третий вариант: во время разработки и тестирования включаются asserts, checked iterators и прочий defensive programming,
А во время эксплуатации что делать? Молитву о здравии заказывать? Довольно рисково иметь разный код в дебаге и релизе.
assert вот как-то не прижился в managed языках...

EP>которые помогают отлавливать подобные проблемы

Мало они помогают. Переносят проблемы с плеч компилятора на плечи программиста. Угадай — кто чаще ошибается?
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[17]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: CreatorCray  
Дата: 09.08.16 17:02
Оценка:
Здравствуйте, chaotic-kotik, Вы писали:

CK>MS не может добить оптимизатор VC++ до уровня gcc четырехлетней давности (нет нормальной векторизации и девиртуализации).


А тот же gcc всё никак не допрыгнет до intel compiler по качеству генерируемого кода.
Я периодически смотрю в assembler output от гнуса и очень часто там печалька. В частности почему то он очень любит сливать в память тогда как полно свободных регистров.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[24]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 09.08.16 17:25
Оценка: :)
Здравствуйте, ·, Вы писали:

EP>>·>В С++ — другая крайность. Индекс вообще проверяться не будет (вычислили значение i по таблице неправильно и бабах).

EP>>·>А если захочешь безопасностьи то вместо vect[i] будешь использовать vect.at(i) и компилятор С++ столкнётся с той же бедой, что и сишарп.
EP>>Есть третий вариант: во время разработки и тестирования включаются asserts, checked iterators и прочий defensive programming,
·>А во время эксплуатации что делать? Молитву о здравии заказывать?

Тестировать код — это нужно в любом случае. Все эти defensive примочки от багов не исцеляют, а лишь смягчают последствия фейла.

·>Довольно рисково иметь разный код в дебаге и релизе.


Тестируй и debug и release если есть какие-то сомнения в отсутсвии side-effect'ов у assert'ов.

·>assert вот как-то не прижился в managed языках...


ЕМНИП Sinix рассказывал что использует их во всю как раз в managed языке.

EP>>которые помогают отлавливать подобные проблемы

·>Мало они помогают. Переносят проблемы с плеч компилятора на плечи программиста. Угадай — кто чаще ошибается?

Задача писать корректный код лежит на плечах программиста, и никакие defensive штуки не превратят некорректный код в корректный. Максимум в чём они помогают — это раннее определение уже свершившегося бага, да и то в рантайме
Отредактировано 09.08.2016 17:28 Evgeny.Panasyuk . Предыдущая версия .
Re: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: a_g_99 США http://www.hooli.xyz/
Дата: 09.08.16 19:59
Оценка: :)
AS>Собственно, сборка мусора в Rust есть (опционально), а такого мощного статического анализатора в C# нет.

Зарплата Senior Staff Engineer (Java/JavaScript) в Google ~ 250k в год
Зарплата Senior Engineer (Java/JavaScript) в Netflix ~ 350k в год

Зарплата Senior .Net Engineer в Microsoft ~ 80k в год

Как вы полагаете какие люди идут в си шарп? Правильно он сначала был велоинструктором 10 лет, потом программистом Шарепоинта на дельфи. Потом он еще 10 лет познавал гит (как некоторые эксперты си шарп на рсдн, до сих пор отсмеяться не могу).
Отредактировано 11.08.2016 15:47 a_g_99 . Предыдущая версия .
Re[23]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 09.08.16 21:22
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>То есть ещё раз, код C# чисто по построению намного труднее оптимизировать — для оптимизаций до уровней аналогичных C++ нужно либо язык модифицировать, либо делать оптимизаторы намного более мощные чем оптимизаторы C++


Язык тут не при чем. Машинный код генерируется из IL. В нем все указанные тобой оптимизации делаются элементарно.
Но у JIT нет столько времени на пребразования, как у компилятора C++. Поэтому оптимизации оставляют желать лучшего. В теории могли бы делать омтипизации в ngen, но посчитали что одинаковый выхлоп ngen и jit важнее, чем пару мсек скорости.

В Java и JS пошли по пути "HotSpot" — повторная компиляция кусков кода на основе профиля использования.
Для .NET придумали другой способ — генерировать C++ код и потом его компилировать (.NET Native).
Re[24]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 09.08.16 21:40
Оценка:
Здравствуйте, gandjustas, Вы писали:

EP>>То есть ещё раз, код C# чисто по построению намного труднее оптимизировать — для оптимизаций до уровней аналогичных C++ нужно либо язык модифицировать, либо делать оптимизаторы намного более мощные чем оптимизаторы C++

G>Язык тут не при чем.

Именно язык тут и при чём. Если писать на C++ в стиле C# — динамические замыкания, динамический IEnumerable, множество индерекций по памяти — то получим примерно такие же тормоза

G>Машинный код генерируется из IL. В нем все указанные тобой оптимизации делаются элементарно.

G>Но у JIT нет столько времени на пребразования, как у компилятора C++.

Что мешает сразу генерировать оптимизированный IL?
Я выше привёл пример с трансляцией C++ -> JS. JS ещё "хуже" IL, но тем не менее он работает быстро. Можно взять этот JS выхлоп и перевести на C# — и он там тоже будет работать быстро, несмотря ни на какой IL
Re[2]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: antropolog  
Дата: 09.08.16 23:22
Оценка: 2 (1) :)
Здравствуйте, velkin, Вы писали:

V>Всё будет убито сиплюсплюсом.


именно так. кремний перестал расти в частотах, на десктопах давно, на мобилках недавно. Выжать максимум из платформы можно будет только переходя на C++. В соотношении абстракция/циклы процессора всем остальным языкам до него как раком до пекина.
Re[23]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 10.08.16 07:31
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здравствуйте, Serginio1, Вы писали:


EP>>>>>Здесь внутри foo, ещё до всяких оптимизаторов, известен и конкретный тип замыкания F, и его размер, и конкретный вызываемый метод.

EP>>>>>Аналог на C# в студию
S>>>>
S>>>> T foo<T>(Func<T> f)
S>>>>{
S>>>>  return f();
S>>>>}
S>>>>

EP>>>О чём и речь — у тебя внутри foo один тип для разных замыканий с одинаковой сигнатурой — а значит динамический полиморфизм и прочие индерекции, которые на порядок сложнее оптимизировать
S>> На данном этапе да.
S>>Но мы то говорим о компиляторе в стиле C++. А там
return x>>
проинлайнить не проблема на уровне исходников.


EP>Подобные штуки (динамический полиморфизм) и компиляторы C++ инлайнят только в простейших вариантах — если же добавить простую аллокацию на пути или что-то подобное, то это становится серьёзным барьером для инлайнинга (тут разве что помогает PGO, да и то частично).

EP>То есть ещё раз, код C# чисто по построению намного труднее оптимизировать — для оптимизаций до уровней аналогичных C++ нужно либо язык модифицировать, либо делать оптимизаторы намного более мощные чем оптимизаторы C++

А можно поподробнее чем

 T foo<T>(Func<T> f)
  {
  return f();
  }

Принципиально отличается

template<typename F>
auto foo(F f)
{
    return f();
}


И почему для C++ проще занматься оптимизацией? T4 работают, а создать генератор кода на дженериках тоже не огромная проблема. Да для кое где нужно что то добавить в язык для более удобного использования ограничений. Но это небольшие нововведения.
и солнце б утром не вставало, когда бы не было меня
Re[21]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 10.08.16 07:33
Оценка:
Здравствуйте, chaotic-kotik, Вы писали:

CK>Здравствуйте, Serginio1, Вы писали:


S>> Еще раз повторю. Время идет и все меняется. Те же циклы типа

S>>
S>>for(int i=0;i<ar.Length,i++)
S>>    var a=ar[i];
S>>

S>>Никаких проверок не будет. А для работы с матрицами есть SIMD.

CK>Компилятор С++ вообще этот цикл вырежет, так как он ничего не делает. Либо векторизует, если `a` дальше используется в вычислениях, причем вкорячит туда такой код, который сможет работать даже в случае если массив не выровнен. Ну а компилятор сишарпа даже проверки сможет вырезать только в простых случаях (линейно бежим по массиву). Если есть inderection (вычисляем значение i по таблице, например) — то он не вырежет ничего и будет каждый индекс проверять.


Еще раз. MS задумали сделать нативный компилятор для C# по аналогии с C++. Плюс сборка мусора. Как получится не знаю, но движение есть.
и солнце б утром не вставало, когда бы не было меня
Re[25]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: · Великобритания  
Дата: 10.08.16 09:12
Оценка: +1
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>>>Есть третий вариант: во время разработки и тестирования включаются asserts, checked iterators и прочий defensive programming,

EP>·>А во время эксплуатации что делать? Молитву о здравии заказывать?
EP>Тестировать код — это нужно в любом случае. Все эти defensive примочки от багов не исцеляют, а лишь смягчают последствия фейла.
Они фейл делают фейлом, а не UB.

EP>·>Довольно рисково иметь разный код в дебаге и релизе.

EP>Тестируй и debug и release если есть какие-то сомнения в отсутсвии side-effect'ов у assert'ов.
Тут не в сомнениях дело. А сам факт того, что если условие ассерта не сработает в релизе — то угадать что будет — невозможно.

EP>·>assert вот как-то не прижился в managed языках...

EP>ЕМНИП Sinix рассказывал что использует их во всю как раз в managed языке.
Можно, конечно. Но непонятно зачем. А где он об этом писал?

EP>·>Мало они помогают. Переносят проблемы с плеч компилятора на плечи программиста. Угадай — кто чаще ошибается?

EP>Задача писать корректный код лежит на плечах программиста, и никакие defensive штуки не превратят некорректный код в корректный. Максимум в чём они помогают — это раннее определение уже свершившегося бага, да и то в рантайме
Они позволяют избежать UB. Грубо говоря некий такой wysiwyg — как код написан, так он и исполняется. А не так, что вышли за границы массива или обратились к неинициализированной памяти — и последствия совершенно непредсказуемы.
Даже вон JMM придумали, чтобы для многопоточного кода всё было предсказуемо.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[22]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: chaotic-kotik  
Дата: 10.08.16 09:16
Оценка: +1
Здравствуйте, ·, Вы писали:


·>В С++ — другая крайность. Индекс вообще проверяться не будет (вычислили значение i по таблице неправильно и бабах).

·>А если захочешь безопасностьи то вместо vect[i] будешь использовать vect.at(i) и компилятор С++ столкнётся с той же бедой, что и сишарп.
·>По-моему, в подавляющем большинстве случаев важнее не бабахать, чем вырезать.

Ноуп.
В с++ есть диапазоны (boost.range). Там инвариант цикла проверяется один раз и потом уже никаких накладных расходов нет. Помимо этого, выход за границы массива — так себе проблема, я нехочу платить за ее решение в рантайме, если можно этого не делать. Я могу сделать так что индекс не выйдет за границы массива by design. Для этого люди учатся программированию все таки. Нужно уметь рассуждать об инвариантах циклов и подобных вещах. Не думать о корректности и надеяться непонятно на что — не дело.
Re[23]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: · Великобритания  
Дата: 10.08.16 09:36
Оценка:
Здравствуйте, chaotic-kotik, Вы писали:

CK>·>В С++ — другая крайность. Индекс вообще проверяться не будет (вычислили значение i по таблице неправильно и бабах).

CK>·>А если захочешь безопасностьи то вместо vect[i] будешь использовать vect.at(i) и компилятор С++ столкнётся с той же бедой, что и сишарп.
CK>·>По-моему, в подавляющем большинстве случаев важнее не бабахать, чем вырезать.
CK>Ноуп.
CK>В с++ есть диапазоны (boost.range). Там инвариант цикла проверяется один раз и потом уже никаких накладных расходов нет.
CK>Помимо этого, выход за границы массива — так себе проблема, я нехочу платить за ее решение в рантайме, если можно этого не делать. Я могу сделать так что индекс не выйдет за границы массива by design. Для этого люди учатся программированию все таки. Нужно уметь рассуждать об инвариантах циклов и подобных вещах. Не думать о корректности и надеяться непонятно на что — не дело.
Так Bounds-checking elimination это тоже умеет делать, конечно, в простых случаях только (как и типичный программист), зато гарантированно не ошибается.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[25]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.08.16 10:50
Оценка: 1 (1)
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здравствуйте, gandjustas, Вы писали:


EP>>>То есть ещё раз, код C# чисто по построению намного труднее оптимизировать — для оптимизаций до уровней аналогичных C++ нужно либо язык модифицировать, либо делать оптимизаторы намного более мощные чем оптимизаторы C++

G>>Язык тут не при чем.

EP>Именно язык тут и при чём. Если писать на C++ в стиле C# — динамические замыкания, динамический IEnumerable, множество индерекций по памяти — то получим примерно такие же тормоза

Что такое "данимические замыкания" ? В IL замыкания превращаются просто в классы.
Что такое "динамический IEnumerable"?
Это в смысле IEnumerable не по массивам? Зачем его использовать в performance-critical коде? А IEnumerable (foreach) с массивами действительно тормозит (накладные расходы на Enumerator оказываются больше, чем затратры на тело цикла). Как раз из-за недостатка инлайнинга, в C++ foreach нилайнится.
Или ты имеешь ввиду использование ФВП для обхода массивов? Оно действительно и в C++, и в C# плохо работает. И в C++ и в C# такой код вручную оптимизируется.


G>>Машинный код генерируется из IL. В нем все указанные тобой оптимизации делаются элементарно.

G>>Но у JIT нет столько времени на пребразования, как у компилятора C++.
EP>Что мешает сразу генерировать оптимизированный IL?
IL — высокоуровневый язык. Он и так достаточно оптимален на своем уровне. Кроме того IL еще и метаинформацию хранить должен.

EP>Я выше привёл пример с трансляцией C++ -> JS. JS ещё "хуже" IL, но тем не менее он работает быстро.

Что "хуже" ?
Работает быстро за счет "hotspot". Большинство движков JS перекомпилируют код на основании профиля использования. Кроме того "работает быстро" — это когда не используются ФВП.


EP>Можно взять этот JS выхлоп и перевести на C# — и он там тоже будет работать быстро, несмотря ни на какой IL

Если не используются ФВП, то да. Вообще при небольших усилиях скорость C# аналогична C++. Даже статью на эту тему писал https://habrahabr.ru/post/266373/
Re[24]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 10.08.16 11:29
Оценка:
Здравствуйте, Serginio1, Вы писали:

EP>>То есть ещё раз, код C# чисто по построению намного труднее оптимизировать — для оптимизаций до уровней аналогичных C++ нужно либо язык модифицировать, либо делать оптимизаторы намного более мощные чем оптимизаторы C++

S> А можно поподробнее чем
S>
S> T foo<T>(Func<T> f)
S>  {
S>  return f();
S>  }
S>

S>Принципиально отличается
S>
S>template<typename F>
S>auto foo(F f)
S>{
S>    return f();
S>}
S>


Тем что на C# после всех подстановок схематически получается:
class AbstractF 
{
public:
    virtual int virtual_call() = 0;
};

int foo(AbstractF *f)
{
    return f->virtual_call();
}
А на C++:
struct ConcreteF 
{
    int x;
    int concrete_call()
    {
        return x;
    }
};

int foo(ConcreteF f)
{
    return f.concrete_call();
}


S> И почему для C++ проще занматься оптимизацией?


В этом примере — на C++ вызов конкретного метода, известен размер замыкания и стэковая аллокация. На C# виртуальный вызов, неизвестен размер замыкания и аллокация в куче.
Виртуальный вызов и прочее можно соптимизировать, но это очевидно более сложная задача чем заинлайнить простой вызов конкретного метода

S>T4 работают,


Причём тут T4?
Re[25]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 10.08.16 11:40
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здравствуйте, Serginio1, Вы писали:


EP>>>То есть ещё раз, код C# чисто по построению намного труднее оптимизировать — для оптимизаций до уровней аналогичных C++ нужно либо язык модифицировать, либо делать оптимизаторы намного более мощные чем оптимизаторы C++

S>> А можно поподробнее чем
S>>
S>> T foo<T>(Func<T> f)
S>>  {
S>>  return f();
S>>  }
S>>

S>>Принципиально отличается
S>>
S>>template<typename F>
S>>auto foo(F f)
S>>{
S>>    return f();
S>>}
S>>


EP>Тем что на C# после всех подстановок схематически получается:

EP>
EP>class AbstractF 
EP>{
EP>public:
EP>    virtual int virtual_call() = 0;
EP>};

EP>int foo(AbstractF *f)
EP>{
EP>    return f->virtual_call();
EP>}
EP>
А на C++:

EP>
EP>struct ConcreteF 
EP>{
EP>    int x;
EP>    int concrete_call()
EP>    {
EP>        return x;
EP>    }
EP>};

EP>int foo(ConcreteF f)
EP>{
EP>    return f.concrete_call();
EP>}
EP>


S>> И почему для C++ проще занматься оптимизацией?


EP>В этом примере — на C++ вызов конкретного метода, известен размер замыкания и стэковая аллокация. На C# виртуальный вызов, неизвестен размер замыкания и аллокация в куче.

EP>Виртуальный вызов и прочее можно соптимизировать, но это очевидно более сложная задача чем заинлайнить простой вызов конкретного метода

S>>T4 работают,


EP>Причём тут T4?

А при том, что можно сначала разворачивать исходный код дженериков в код на C# с инлайнингом по типу. Самый простой вариант.
Еще раз мы говорим не использовании дженериков из MSIL. А специализацию дженериков по переданному типу, лямды. Это можно сделать как на уровне исходников. Чем вобщем то и занимаются специализации шаблонов. Я много слышал, что в С++ хотели делать бинарную форму хранения. Что то подобное можно делать и для дженериков.

Я не вижу принципиальной разницы между шаблонами и дженериками. Наоборот дженерики даже проще, так как предоставляют ограничения.
и солнце б утром не вставало, когда бы не было меня
Re[25]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.08.16 11:44
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>В этом примере — на C++ вызов конкретного метода, известен размер замыкания и стэковая аллокация. На C# виртуальный вызов, неизвестен размер замыкания и аллокация в куче.

Что за бред? Размер замыкания известен всегда. Аллокация на куче для .NET на порядок дешевле аллокации на куче для C++.
Даже с учетом сборки мусора амортизированная стоимость аллокации невелика.


EP>Виртуальный вызов и прочее можно соптимизировать, но это очевидно более сложная задача чем заинлайнить простой вызов конкретного метода

JIT занимается девиртуализацией вызовов, причем успешно.

Но в примере не будет виртуального вызова, там будет вызов делегата, который сделали офигеть каким медленным из-за того, что поддержку ФВП в C# и VB не планировали изначально.
В F# даже придумали вместо делегатов классы генерировать для ФВП.
Re[3]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Mihas  
Дата: 10.08.16 11:44
Оценка:
Здравствуйте, antropolog, Вы писали:

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

Да ну??
А вот тут до 16 ГГц выжимают.

  --
шутка, конечно же
Re[26]: {@Sinix} Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 10.08.16 12:02
Оценка:
Здравствуйте, ·, Вы писали:

EP>>·>Довольно рисково иметь разный код в дебаге и релизе.

EP>>Тестируй и debug и release если есть какие-то сомнения в отсутсвии side-effect'ов у assert'ов.
·>Тут не в сомнениях дело. А сам факт того, что если условие ассерта не сработает в релизе — то угадать что будет — невозможно.

assert'ы применяются намного шире чем простейший bounds checking — для проверки пред/пост-условий, для проверки инвариантов и вариантов циклов, для проверки инвариантов классов и т.п.
И да, если твой вариант цикла неверный, а assert'ы либо выключены, либо вообще не написаны, либо бывает что их вообще невозможно выразить в коде — то действительно угадать что будет невозможно, это типичный баг в программе
Вопрос к тебе — когда ты написал последний assert/проверку для варианта цикла? Если ты не пишешь проверку каких-то свойств корректности программы, это не значит что их нет, и да — здесь применим весь твой пессимизм "угадать что будет — невозможно"
С другой стороны, выключение части из проверок в runtime'е, ровно как и отсутствии часть проверок вообще — не делает программу некорректной.

EP>>·>assert вот как-то не прижился в managed языках...

EP>>ЕМНИП Sinix рассказывал что использует их во всю как раз в managed языке.
·>Можно, конечно. Но непонятно зачем. А где он об этом писал?

Много где, можем попробовать его призвать сюда. Например в CodeJam сделали компонент Assertions.
В целом не пойму почему ты проводишь разделение managed/не managed относительно assert'ов.

EP>>·>Мало они помогают. Переносят проблемы с плеч компилятора на плечи программиста. Угадай — кто чаще ошибается?

EP>>Задача писать корректный код лежит на плечах программиста, и никакие defensive штуки не превратят некорректный код в корректный. Максимум в чём они помогают — это раннее определение уже свершившегося бага, да и то в рантайме
·>Они позволяют избежать UB. Грубо говоря некий такой wysiwyg — как код написан, так он и исполняется. А не так, что вышли за границы массива или обратились к неинициализированной памяти — и последствия совершенно непредсказуемы.

Это лишь только для мизерной части утверждений корректности программы. Если ты не расписал все утверждения корректности, то никакого "WYSIWYG" — очевидно нет

P.S. Ничто не мешает оставить часть assert'ов включенных в Release. Для этого их обычно разбивают на классы "быстрые", "медленные", "очень медленные" — и уже пользователь библиотеки решает что попадёт в Release.
Re[26]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 10.08.16 12:20
Оценка:
Здравствуйте, gandjustas, Вы писали:

EP>>В этом примере — на C++ вызов конкретного метода, известен размер замыкания и стэковая аллокация. На C# виртуальный вызов, неизвестен размер замыкания и аллокация в куче.

G>Что за бред? Размер замыкания известен всегда.

Ты не понимаешь о чём речь, речь о том что видно внутри шаблона/дженерика после всех подстановок. В C++ размер замыкания известен внутри foo во время компиляции:
int foo(ConcreteF f)
{
    static_assert(sizeof(ConcreteF) == sizeof(int))
    return f.concrete_call();
}

В C# же у тебя будет Func<...> одинакового размера для всех вариантов замыканий, независимо от их оригинального размера..

G>Аллокация на куче для .NET на порядок дешевле аллокации на куче для C++.


1. Она всё равно дороже чем отсутствие аллокации в куче. На C++ может не быть и даже стэковой аллокаций — всё передастся через регистры, либо и вовсе не будет никакой передачи, а лишь подстановка константы.
2. Речь даже не столько про стоимость аллокации, а про то что она сильно мешает последующему инлайнингу.

G>Даже с учетом сборки мусора амортизированная стоимость аллокации невелика.


Она огромна по сравнению с отсуствием аллокаций

EP>>Виртуальный вызов и прочее можно соптимизировать, но это очевидно более сложная задача чем заинлайнить простой вызов конкретного метода

G>JIT занимается девиртуализацией вызовов, причем успешно.

Ты читать не умеешь? "это очевидно более сложная задача"
А так не только JIT инлайнит виртуальные вызовы, но и обычный статический компилятор, даже без всяких PGO — но работает это далеко не всегда.

G>Но в примере не будет виртуального вызова, там будет вызов делегата, который сделали офигеть каким медленным из-за того, что поддержку ФВП в C# и VB не планировали изначально.

G>В F# даже придумали вместо делегатов классы генерировать для ФВП.

В любом случае это будет медленная динамическая хрень, против обычного вызова невиртуальной функции. И эту хрень намного тяжелее оптимизировать, простым преобразования C# -> C++ не отделаешься
Re[27]: {@Sinix} Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Sinix  
Дата: 10.08.16 12:25
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:


EP>Много где, можем попробовать его призвать сюда. Например в CodeJam сделали компонент Assertions.

EP>В целом не пойму почему ты проводишь разделение managed/не managed относительно assert'ов.

Ну призвать-то призвал, дальше чего? Я не сильно слежу за веткой, так что пока не понимаю чего обсуждаем.
И тем более не соображу, при чём здесь ассерты bounds checking и прочая мелочёвка — эт всё-таки ответственность компилятора / рантайма / библиотеки типов, но никак не разработчика. Иначе получается вообще замечательное комбо: ручного труда куча, эффект нулевой.

P.S. По хорошему ещё бы и проверки на null на рантайм / компилятор спихнуть, но это года через два будет.
Re[28]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 10.08.16 12:40
Оценка: +1
Здравствуйте, Sinix, Вы писали:

EP>>Много где, можем попробовать его призвать сюда. Например в CodeJam сделали компонент Assertions.

EP>>В целом не пойму почему ты проводишь разделение managed/не managed относительно assert'ов.
S>Ну призвать-то призвал, дальше чего? Я не сильно слежу за веткой, так что пока не понимаю чего обсуждаем.
S>И тем более не соображу, при чём здесь ассерты bounds checking и прочая мелочёвка — эт всё-таки ответственность компилятора / рантайма / библиотеки типов, но никак не разработчика. Иначе получается вообще замечательное комбо: ручного труда куча, эффект нулевой.

Речи о том чтобы делать везде вручную проверки bounds — нет. Она реализуется один раз внутри vector::operator[]. Точнее уже реализована, её нужно только включить флагом.

Вопрос же к тебе более общий — практика использования assert'ов в managed языках. Насколько я помню ты много раз писал на эту тему.
Re[27]: {@Sinix} Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: · Великобритания  
Дата: 10.08.16 12:44
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>·>Тут не в сомнениях дело. А сам факт того, что если условие ассерта не сработает в релизе — то угадать что будет — невозможно.

EP>assert'ы применяются намного шире чем простейший bounds checking — для проверки пред/пост-условий, для проверки инвариантов и вариантов циклов, для проверки инвариантов классов и т.п.
А что они дают-то? Почему вместо assert x просто нельзя if(!x) throw Boom()? Если медленно — это уже проблема алгоритма. При хорошем покрытии тестами ценность ассертов падает до нуля.

EP>И да, если твой вариант цикла неверный, а assert'ы либо выключены, либо вообще не написаны, либо бывает что их вообще невозможно выразить в коде — то действительно угадать что будет невозможно, это типичный баг в программе

EP>Вопрос к тебе — когда ты написал последний assert/проверку для варианта цикла? Если ты не пишешь проверку каких-то свойств корректности программы, это не значит что их нет, и да — здесь применим весь твой пессимизм "угадать что будет — невозможно"
Никогда не писал.

EP>С другой стороны, выключение части из проверок в runtime'е, ровно как и отсутствии часть проверок вообще — не делает программу некорректной.

Но только если ассерты расставлены корректно.

EP>>>ЕМНИП Sinix рассказывал что использует их во всю как раз в managed языке.

EP>·>Можно, конечно. Но непонятно зачем. А где он об этом писал?
EP>Много где, можем попробовать его призвать сюда. Например в CodeJam сделали компонент Assertions.
Я что-то не понял что это. Судя по if (!condition)throw это не ассерты в понимании С++.

EP>В целом не пойму почему ты проводишь разделение managed/не managed относительно assert'ов.

Это в ответ на то, что в С++ "включаются asserts, checked iterators и прочий defensive programming". Ассерты тут как частный случай скорее.
Т.е. в managed у тебя всегда работает правильно, а когда может — работает быстро. В unmanaged наоборот: когда может — работает правильно, и всегда быстро.

EP>>>Задача писать корректный код лежит на плечах программиста, и никакие defensive штуки не превратят некорректный код в корректный. Максимум в чём они помогают — это раннее определение уже свершившегося бага, да и то в рантайме

EP>·>Они позволяют избежать UB. Грубо говоря некий такой wysiwyg — как код написан, так он и исполняется. А не так, что вышли за границы массива или обратились к неинициализированной памяти — и последствия совершенно непредсказуемы.
EP>Это лишь только для мизерной части утверждений корректности программы. Если ты не расписал все утверждения корректности, то никакого "WYSIWYG" — очевидно нет
Есть конечно. Я говорю о корректности самого кода, а не логических ошибок в алгоритме. Т.е. в С++ если видишь, что у тебя в коде написано a = b + c то при известных значениях b==1 и c==2 может случиться, что a!=3 т.к. где-то что-то стрельнуло по памяти из другого треда. В managed — a==3 всегда, доказано верификатором.

EP>P.S. Ничто не мешает оставить часть assert'ов включенных в Release. Для этого их обычно разбивают на классы "быстрые", "медленные", "очень медленные" — и уже пользователь библиотеки решает что попадёт в Release.

По-моему излишнее усложнение. Собственно на основании чего пользователь будет принимать решение?
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[27]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.08.16 13:02
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здравствуйте, gandjustas, Вы писали:


EP>>>В этом примере — на C++ вызов конкретного метода, известен размер замыкания и стэковая аллокация. На C# виртуальный вызов, неизвестен размер замыкания и аллокация в куче.

G>>Что за бред? Размер замыкания известен всегда.

EP>Ты не понимаешь о чём речь, речь о том что видно внутри шаблона/дженерика после всех подстановок. В C++ размер замыкания известен внутри foo во время компиляции:

Это ты не понимаешь о чем пишешь. В C# для замыканий генерируется класс, размер которого тоже известен во время компиляции.

EP>В C# же у тебя будет Func<...> одинакового размера для всех вариантов замыканий, независимо от их оригинального размера..

Ты наверное что-то другое хочешь сказать, но не можешь это словами выразить.


G>>Аллокация на куче для .NET на порядок дешевле аллокации на куче для C++.


EP>1. Она всё равно дороже чем отсутствие аллокации в куче. На C++ может не быть и даже стэковой аллокаций — всё передастся через регистры, либо и вовсе не будет никакой передачи, а лишь подстановка константы.

Это если вызов "делегата" будет заинлайнен, но в .NET такого не происходит. Дело вовсе не в языке, а в том, как и в каких условиях работает JIT.

EP>2. Речь даже не столько про стоимость аллокации, а про то что она сильно мешает последующему инлайнингу.

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

G>>Даже с учетом сборки мусора амортизированная стоимость аллокации невелика.

EP>Она огромна по сравнению с отсуствием аллокаций
В реальной программе аллокаций будет дофига в любом случае.

EP>>>Виртуальный вызов и прочее можно соптимизировать, но это очевидно более сложная задача чем заинлайнить простой вызов конкретного метода

G>>JIT занимается девиртуализацией вызовов, причем успешно.
EP>Ты читать не умеешь? "это очевидно более сложная задача"
С чего ты взял что она сложная? Почти примитивная оптимизация.


G>>Но в примере не будет виртуального вызова, там будет вызов делегата, который сделали офигеть каким медленным из-за того, что поддержку ФВП в C# и VB не планировали изначально.

G>>В F# даже придумали вместо делегатов классы генерировать для ФВП.
EP>В любом случае это будет медленная динамическая хрень, против обычного вызова невиртуальной функции. И эту хрень намного тяжелее оптимизировать, простым преобразования C# -> C++ не отделаешься
Это надо проверить.
Re[29]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Sinix  
Дата: 10.08.16 13:18
Оценка: 2 (1)
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Вопрос же к тебе более общий — практика использования assert'ов в managed языках. Насколько я помню ты много раз писал на эту тему.


А чего там обсуждать-то?

Абсолютно стандартная практика: закладываешься на какой-то факт — напиши ассерт. Закладываешься, но считаешь, что "такого не может быть никогда" — напиши отладочный ассерт, сюрприз будет

Дальше ещё проще. Сработал ассерт — останавливаемся и разбираемся в обязательном порядке. Или правим баг в коде (с edit-n-continue можно править код, не прерывая отладки), или убеждаемся, что у нас косяк в дизайне, ставим временный костыль и заводим тикет на исправление.

Не сработал — тож замечательно. Потом сработает. Потому что ассерты работают всегда, а не только один раз в виде конкретного юнит-теста, и, соответственно, шансы словить ошибку у них на порядок больше. На порядок — эт не преувеличение, в том же CodeJam.PerfTests в основном ошибки ловились или интеграционными тестами, или ассертами (хотя их там мало довольно емнип). Простые юнит-тесты главным образом работали как способ обнаружения регрессий и после падения такого теста приходилось ещё разбираться, что именно пошло не так.

Такой подход экономит кучу времени, т.к. для сложного кода можно не раздербанивать кишки на кучу отдельных тестов, а просто прогнать интеграционные тесты для основных сценариев и проследить (через code coverage), что все потенциально проблемные места покрыты.


Вся инструментальная часть требует ровно двух вещей:
* возможность прервать выполнение при нарушении ассерта.
* при подключенном отладчике — немедленно остановиться в месте, где ассерт сломался.

Собственно всё, никакой managed-специфики тут нет.
Re[28]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 10.08.16 13:19
Оценка: -1 :)
Здравствуйте, gandjustas, Вы писали:

EP>>>>В этом примере — на C++ вызов конкретного метода, известен размер замыкания и стэковая аллокация. На C# виртуальный вызов, неизвестен размер замыкания и аллокация в куче.

G>>>Что за бред? Размер замыкания известен всегда.
EP>>Ты не понимаешь о чём речь, речь о том что видно внутри шаблона/дженерика после всех подстановок. В C++ размер замыкания известен внутри foo во время компиляции:
G>Это ты не понимаешь о чем пишешь. В C# для замыканий генерируется класс, размер которого тоже известен во время компиляции.

И всё же ты не понимаешь. Класс да, генерируется, да размер на стороне вызова известен, но вот внутри дженерика размер стёрт, даже после всех подстановок, в C++ же его размер внутри шаблона известен во время компиляции.
Перечитай десять раз, посмотри примеры выше, обрати внимание на static_assert — если не дойдёт, то задавай конкретный вопрос.

EP>>В C# же у тебя будет Func<...> одинакового размера для всех вариантов замыканий, независимо от их оригинального размера..

G>Ты наверное что-то другое хочешь сказать, но не можешь это словами выразить.

Я уже выразил, и пример привёл. Но ты, из-за своего неконструктивного настроя, не можешь это понять.

EP>>2. Речь даже не столько про стоимость аллокации, а про то что она сильно мешает последующему инлайнингу.

G>Ты причину и следствие путаешь.

Не путаю.

G>Убрать аллокацию для замыкания можно, если вызов делегата можно заинлайнить по месту вызова. Но это не значит что наличие аллокации мешает инлайну.


Именно мешает. Я смотрел генерируемый код C++ компиляторами — простые виртуальные вызовы инлайнятся, если же вставить динамическую аллокацию (при прочих равных), то инлайна не происходит.

G>>>Даже с учетом сборки мусора амортизированная стоимость аллокации невелика.

EP>>Она огромна по сравнению с отсуствием аллокаций
G>В реальной программе аллокаций будет дофига в любом случае.

Это на C# дофига аллокаций, на C++ их на порядки меньше, так как многое хранится по значению. Вектор объектов класса — это минимум одна аллокация, на C# — минимум N+1 аллокаций.
И в любом случае 100*дофига намного больше чем просто дофига

EP>>>>Виртуальный вызов и прочее можно соптимизировать, но это очевидно более сложная задача чем заинлайнить простой вызов конкретного метода

G>>>JIT занимается девиртуализацией вызовов, причем успешно.
EP>>Ты читать не умеешь? "это очевидно более сложная задача"
G>С чего ты взял что она сложная? Почти примитивная оптимизация.

И всё таки ты читать не умеешь "более сложная"

EP>>В любом случае это будет медленная динамическая хрень, против обычного вызова невиртуальной функции. И эту хрень намного тяжелее оптимизировать, простым преобразования C# -> C++ не отделаешься

G>Это надо проверить.

Что конкретно?
Re[30]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 10.08.16 13:36
Оценка: 2 (1) +1
Здравствуйте, Sinix, Вы писали:

EP>>Вопрос же к тебе более общий — практика использования assert'ов в managed языках. Насколько я помню ты много раз писал на эту тему.

S>А чего там обсуждать-то?

Вот это:

·>>>assert вот как-то не прижился в managed языках...
EP>>ЕМНИП Sinix рассказывал что использует их во всю как раз в managed языке.
·>Можно, конечно. Но непонятно зачем. А где он об этом писал?


S>Не сработал — тож замечательно. Потом сработает. Потому что ассерты работают всегда, а не только один раз в виде конкретного юнит-теста, и, соответственно, шансы словить ошибку у них на порядок больше.


Да, это преимущество. Но с другой стороны в юнит тестами намного проще перевести код в состояние всех edge-case'ов (в которых в том числе могут выстрелить assert'ы) по сравнению с интеграционными тестами.

S>Такой подход экономит кучу времени, т.к. для сложного кода можно не раздербанивать кишки на кучу отдельных тестов, а просто прогнать интеграционные тесты для основных сценариев и проследить (через code coverage), что все потенциально проблемные места покрыты.


100% code coverage не даёт гарантии попадания во все edge cases.
Re[26]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 10.08.16 13:57
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>>>T4 работают,

EP>>Причём тут T4?
S> А при том, что можно сначала разворачивать исходный код дженериков в код на C# с инлайнингом по типу. Самый простой вариант.

Ты предлагаешь брать на себя работу компилятора и разворачивать через кодогенерацию дженерики во всех комбинациях?
Так об этом и речь — для быстрого кода на C# приходится отказываться от встроенных абстракций и писать вручную низкоуровневый код, либо генерировать его внешними утилитами
Re[27]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 10.08.16 14:33
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

S>> А при том, что можно сначала разворачивать исходный код дженериков в код на C# с инлайнингом по типу. Самый простой вариант.


EP>Ты предлагаешь брать на себя работу компилятора и разворачивать через кодогенерацию дженерики во всех комбинациях?

EP>Так об этом и речь — для быстрого кода на C# приходится отказываться от встроенных абстракций и писать вручную низкоуровневый код, либо генерировать его внешними утилитами
Я предлагаю заниматься этим компилятору. Ничего сложного. Кроме того куча тулз которые из MSIL кода генерят C# код.
Ни от чего не нужно отказываться. Другое дело, что для лучшей работы как я тебе показывал можно ввести расширения имплементации интерфейсов для типов.
При этом можно в том числе реализовывать и статический SQL из Linq при привязке провайдера.
и солнце б утром не вставало, когда бы не было меня
Отредактировано 10.08.2016 14:55 Serginio1 . Предыдущая версия . Еще …
Отредактировано 10.08.2016 14:50 Serginio1 . Предыдущая версия .
Re[28]: {@Sinix} Да ну и фиг с этой Java-ой. .Net будет убит
От: Evgeny.Panasyuk Россия  
Дата: 10.08.16 14:59
Оценка:
Здравствуйте, ·, Вы писали:

EP>>·>Тут не в сомнениях дело. А сам факт того, что если условие ассерта не сработает в релизе — то угадать что будет — невозможно.

EP>>assert'ы применяются намного шире чем простейший bounds checking — для проверки пред/пост-условий, для проверки инвариантов и вариантов циклов, для проверки инвариантов классов и т.п.
·>А что они дают-то? Почему вместо assert x просто нельзя if(!x) throw Boom()?

Почему нельзя? — Можно (есть конечно случаи где нужен именно no-throw код, иначе в процессе раскрутки поломаются другие инварианты, но это отдельная тема, не особо влияющая на суть данной дискуссии).
Отличительная черта assert'ов — в том что они могут быть опционально отключены, более того — для формально верифицированного кода они не нужны.

·>Если медленно — это уже проблема алгоритма.


Это ещё почему?

·>При хорошем покрытии тестами ценность ассертов падает до нуля.


Точно также как и ценность других defensive примочек, а-ля bounds checking

EP>>С другой стороны, выключение части из проверок в runtime'е, ровно как и отсутствии часть проверок вообще — не делает программу некорректной.

·>Но только если ассерты расставлены корректно.

Что ты имеешь в виду? То что проверка внутри assert'а может иметь side-effect?

EP>>>>ЕМНИП Sinix рассказывал что использует их во всю как раз в managed языке.

EP>>·>Можно, конечно. Но непонятно зачем. А где он об этом писал?
EP>>Много где, можем попробовать его призвать сюда. Например в CodeJam сделали компонент Assertions.
·>Я что-то не понял что это. Судя по if (!condition)throw это не ассерты в понимании С++.

Там некоторые из них опциональные, и не попадают в Release.

EP>>В целом не пойму почему ты проводишь разделение managed/не managed относительно assert'ов.

·>Это в ответ на то, что в С++ "включаются asserts, checked iterators и прочий defensive programming". Ассерты тут как частный случай скорее.
·>Т.е. в managed у тебя всегда работает правильно, а когда может — работает быстро.

Ты как-то перекручиваешь слова. Не "правильно", а раннее обнаружение бага, что вовсе не означает "правильно" — твой код уже пришёл в состояние в котором он быть не должен был, и неизвестно как он туда попал, и что уже натворил по пути.

·>В unmanaged наоборот: когда может — работает правильно, и всегда быстро.


Не всегда быстро, только когда assert'ы отключены.

EP>>·>Они позволяют избежать UB. Грубо говоря некий такой wysiwyg — как код написан, так он и исполняется. А не так, что вышли за границы массива или обратились к неинициализированной памяти — и последствия совершенно непредсказуемы.

EP>>Это лишь только для мизерной части утверждений корректности программы. Если ты не расписал все утверждения корректности, то никакого "WYSIWYG" — очевидно нет
·>Есть конечно. Я говорю о корректности самого кода, а не логических ошибок в алгоритме.

В чём ты видишь отличие? Выход за пределы bounds это есть логическая ошибка, которой в корректном коде нет

·>Т.е. в С++ если видишь, что у тебя в коде написано a = b + c то при известных значениях b==1 и c==2 может случиться, что a!=3 т.к. где-то что-то стрельнуло по памяти из другого треда. В managed — a==3 всегда, доказано верификатором.


Не доказано — ибо точно также используется не-managed код, точно также есть компилятор в котором могут быть баги, и даже железо может сбоить

EP>>P.S. Ничто не мешает оставить часть assert'ов включенных в Release. Для этого их обычно разбивают на классы "быстрые", "медленные", "очень медленные" — и уже пользователь библиотеки решает что попадёт в Release.

·>По-моему излишнее усложнение. Собственно на основании чего пользователь будет принимать решение?

1. На основании того какое быстродействие его устраивает
2. На основании того насколько корректен его код (здесь речь идёт про библиотеку и пользовательский код, ассерты внутри библиотеки могут ловить ошибки в пользовательском коде).

  Скрытый текст
https://www.youtube.com/watch?v=1QhtXRMp3Hg
https://www.youtube.com/watch?v=tz2khnjnUx8
Отредактировано 10.08.2016 16:44 Evgeny.Panasyuk . Предыдущая версия .
Re[28]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 10.08.16 15:00
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>>>>>T4 работают,

EP>>>>Причём тут T4?
S>>> А при том, что можно сначала разворачивать исходный код дженериков в код на C# с инлайнингом по типу. Самый простой вариант.
EP>>Ты предлагаешь брать на себя работу компилятора и разворачивать через кодогенерацию дженерики во всех комбинациях?
EP>>Так об этом и речь — для быстрого кода на C# приходится отказываться от встроенных абстракций и писать вручную низкоуровневый код, либо генерировать его внешними утилитами
S> Я предлагаю заниматься этим компилятору. Ничего сложного.

И причём тут тогда T4?!
Re[29]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 10.08.16 15:05
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:


EP>>>Так об этом и речь — для быстрого кода на C# приходится отказываться от встроенных абстракций и писать вручную низкоуровневый код, либо генерировать его внешними утилитами

S>> Я предлагаю заниматься этим компилятору. Ничего сложного.

EP>И причём тут тогда T4?!

Я просто привел аналог раскрутки шаблонов. Можно вспомнить про макросы Немерле. Да и в C++ макросы оочень часто используются
https://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%B5%D0%BF%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81%D0%BE%D1%80_%D0%A1%D0%B8
и солнце б утром не вставало, когда бы не было меня
Отредактировано 10.08.2016 15:07 Serginio1 . Предыдущая версия .
Re[30]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 10.08.16 15:23
Оценка:
Здравствуйте, Serginio1, Вы писали:

EP>>>>Так об этом и речь — для быстрого кода на C# приходится отказываться от встроенных абстракций и писать вручную низкоуровневый код, либо генерировать его внешними утилитами

S>>> Я предлагаю заниматься этим компилятору. Ничего сложного.
EP>>И причём тут тогда T4?!
S> Я просто привел аналог раскрутки шаблонов.

Зачем? Никто же не спорит с тем что можно делать вручную то что делают компиляторы C++

S>Можно вспомнить про макросы Немерле.


T4 очень далеко до макросов Nemerle.

S>Да и в C++ макросы оочень часто используются


Во-первых не часто.
Во-вторых изначально Страуструп пытался использовать макросы для обобщённого программирования — это очень неудобно, собственно поэтому мы и имеем шаблоны. Ты же предлагаешь воспроизводить грабли тридцатилетней давности посредством текстовых макросов
Re[25]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.08.16 15:57
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здравствуйте, Serginio1, Вы писали:


EP>>>То есть ещё раз, код C# чисто по построению намного труднее оптимизировать — для оптимизаций до уровней аналогичных C++ нужно либо язык модифицировать, либо делать оптимизаторы намного более мощные чем оптимизаторы C++

S>> А можно поподробнее чем
S>>
S>> T foo<T>(Func<T> f)
S>>  {
S>>  return f();
S>>  }
S>>

S>>Принципиально отличается
S>>
S>>template<typename F>
S>>auto foo(F f)
S>>{
S>>    return f();
S>>}
S>>


EP>Тем что на C# после всех подстановок схематически получается:

EP>
EP>class AbstractF 
EP>{
EP>public:
EP>    virtual int virtual_call() = 0;
EP>};

EP>int foo(AbstractF *f)
EP>{
EP>    return f->virtual_call();
EP>}
EP>
А на C++:

EP>
EP>struct ConcreteF 
EP>{
EP>    int x;
EP>    int concrete_call()
EP>    {
EP>        return x;
EP>    }
EP>};

EP>int foo(ConcreteF f)
EP>{
EP>    return f.concrete_call();
EP>}
EP>


Эмм. Это будет иметь значение только в том случае, если мы рассматриваем инлайнинг f. А надо рассматривать инлайнинг foo — потому что после него код приобретает вид
class ConcreteF
{
  int x;
  int callee() { return x;}
}
var cf = new ConcreteF(0);
return cf.callee();

Это возможно на обоих языках, т.к. foo у нас невиртуальная и маленького размера. После этого нам доступны дополнительные оптимизации:
1. Девиртуализация вызова cf.callee() делается на раз-два, мы же знаем точный тип cf независимо от того, как он объявлен. Это частный случай constant propagation.
2. После девиртуализации мы инлайним callee(), но не внутри foo, что сложно сделать (и в C++ это возможно исключительно благодаря поставке foo в исходниках. Стоит перенести определение foo из .h в .cpp, как он окажется на равных с С#), а внутри main, где нам всё известно.
3. повторяем constant propagation и получаем int main() { return 0; }.

То, что это не делается в C#/CIL/JIT — не ограничение языка C#. Это ограничение JIT/ngen. Нет принципиальных причин так не делать.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[26]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 10.08.16 16:24
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Эмм. Это будет иметь значение только в том случае, если мы рассматриваем инлайнинг f. А надо рассматривать инлайнинг foo — потому что после него код приобретает вид

S>
S>class ConcreteF
S>{
S>  int x;
S>  int callee() { return x;}
S>}
S>var cf = new ConcreteF(0);
S>return cf.callee();
S>


Не верно, так как непосредственно после инлайнинга получаем:
class ConcreteF
{
  int x;
  int callee() { return x;}
}
Func<...> cf = new ConcreteF(0);
return cf.callee();


И это простейший случай. В более сложных вариантах замыкания могут не просто передаваться через параметры, а встраиваться в другие объекты, либо другие замыкания — например композиция двух замыкания.

S>Это возможно на обоих языках, т.к. foo у нас невиртуальная и маленького размера. После этого нам доступны дополнительные оптимизации:

S>1. Девиртуализация вызова cf.callee() делается на раз-два, мы же знаем точный тип cf независимо от того, как он объявлен. Это частный случай constant propagation.

Так вот я и говорю, что даже C++ компиляторы делают подобную оптимизацию только для простых случаев
Автор: Evgeny.Panasyuk
Дата: 26.02.15
, если же вставить аллокацию — то всё облом
Автор: Evgeny.Panasyuk
Дата: 24.02.15
. И это причём GCC, а не отстающий MS.
Такая оптимизация сложнее простого инлайнинга невирутальных функций, о чём собственно я и говорю, и требует больше уровней инлайнинга.

S>(и в C++ это возможно исключительно благодаря поставке foo в исходниках. Стоит перенести определение foo из .h в .cpp, как он окажется на равных с С#)


1. Для этого есть Link-Time Code Generation / Link Time Optimization
2. Замыкания, ФВП и прочее в большинстве случаев именно в исходниках и поставляются.

S>То, что это не делается в C#/CIL/JIT — не ограничение языка C#.


Именно из ограничений языка и вытекают дополнительные сложности оптимизации.
Re[29]: {@Sinix} Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: · Великобритания  
Дата: 10.08.16 16:51
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>>>assert'ы применяются намного шире чем простейший bounds checking — для проверки пред/пост-условий, для проверки инвариантов и вариантов циклов, для проверки инвариантов классов и т.п.

EP>·>А что они дают-то? Почему вместо assert x просто нельзя if(!x) throw Boom()?
EP>Почему нельзя? — Можно (есть конечно случаи где нужен именно no-throw код, иначе в процессе раскрутки поломаются другие инварианты, но это отдельная тема, не особо влияющая на суть данной дискуссии).
EP>Отличительная черта assert'ов — в том что они могут быть опционально отключены,
Вот эта опциональность и не нравится. Добавляет ещё одну степень свободы в код, т.е. лишнюю сложность. Либо уж пусть будет тестовый код, прогоняемый во время билда, но не попадающий в релиз, либо релизный код, который работает всегда.

EP>более того — для формально верифицированного кода они не нужны.

Для формально верифицированного их разве кто-то пишет?

EP>·>Если медленно — это уже проблема алгоритма.

EP>Это ещё почему?
Точнее не так. Если медленно, то можно перенести ассерт в юнит-тест.

Добавление ассертов можно оправдать на большой старой кодобазе без единого ЮТ. Ассерт добавить обычно на порядки проще чем ЮТ. Ручные тестеры будут тестить дебаждую сборку. Или давать клиенту и попросить зарепродюсить прод-баг.

EP>·>При хорошем покрытии тестами ценность ассертов падает до нуля.

EP>Точно также как и ценность других defensive примочек, а-ля bounds checking
Не точно также же. В проде bounds checking валит исключения, а ассерты — ничего не делают.

EP>>>С другой стороны, выключение части из проверок в runtime'е, ровно как и отсутствии часть проверок вообще — не делает программу некорректной.

EP>·>Но только если ассерты расставлены корректно.
EP>Что ты имеешь в виду? То что проверка внутри assert'а может иметь side-effect?
Да, и такое бывает, к сожалению.

EP>·>Я что-то не понял что это. Судя по if (!condition)throw это не ассерты в понимании С++.

EP>Там некоторые из них опциональные, и не попадают в Release.
Ух ты. Это как устроено? Что-то не могу разобраться...

EP>>>В целом не пойму почему ты проводишь разделение managed/не managed относительно assert'ов.

EP>·>Это в ответ на то, что в С++ "включаются asserts, checked iterators и прочий defensive programming". Ассерты тут как частный случай скорее.
EP>·>Т.е. в managed у тебя всегда работает правильно, а когда может — работает быстро.
EP>Ты как-то перекручиваешь слова. Не "правильно", а ранее обнаружение бага, что вовсе не означает "правильно" — твой код уже пришёл в состояние в котором он быть не должен был, и неизвестно как он туда попал, и что уже натворил по пути.
"мой код", а не языковая конструкция.

EP>·>В unmanaged наоборот: когда может — работает правильно, и всегда быстро.

EP>Не всегда быстро, только когда assert'ы отключены.
При релизном использовании отключены.

EP>·>Есть конечно. Я говорю о корректности самого кода, а не логических ошибок в алгоритме.

EP>В чём ты видишь отличие? Выход за пределы bounds это есть логическая ошибка, которой в корректном коде нет
Эта ошибка явно прописана в спеке языка — результат — ArrayOutOfBoundException. Т.е. работает по спеке, однозначно, а не когда вместо исключения у тебя случится, что 1+2=42.

EP>·>Т.е. в С++ если видишь, что у тебя в коде написано a = b + c то при известных значениях b==1 и c==2 может случиться, что a!=3 т.к. где-то что-то стрельнуло по памяти из другого треда. В managed — a==3 всегда, доказано верификатором.

EP>Не доказано — ибо точно также используется не-managed код, точно также есть компилятор в котором могут быть баги, и даже железо может сбоить
Это понятно. Но для типичного приложения компилятор и железо таки можно считать надёжными. К ним применяют гораздо более серьёзные подходы, типа формальной верификации, да и квалификация инженеров выше как правило.

EP>>>P.S. Ничто не мешает оставить часть assert'ов включенных в Release. Для этого их обычно разбивают на классы "быстрые", "медленные", "очень медленные" — и уже пользователь библиотеки решает что попадёт в Release.

EP>·>По-моему излишнее усложнение. Собственно на основании чего пользователь будет принимать решение?
EP>1. На основании того какое быстродействие его устраивает
Чем быстрее, тем лучше, очевидно.

EP>2. На основании того насколько корректен его код (здесь речь идёт про библиотеку и пользовательский код, ассерты внутри библиотеки могут ловить ошибки в пользовательском коде).

Конечно, корректен, я что ламер некорректный код писать? А ты как корректность своего кода оцениваешь?
А вообще для этого сценария придумали логи и кастомизируемые (в т.ч. в рантайм) уровни логгирования. Ассерты тут пихать не надо.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[31]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Sinix  
Дата: 10.08.16 17:19
Оценка: +1
Здравствуйте, Evgeny.Panasyuk, Вы писали:

S>>А чего там обсуждать-то?

EP>·>Можно, конечно. [bНо непонятно зачем[/b].
А. Ну, у меня отпуск, настроение хорошее, спорить не тянет Незачем, значит незачем.


EP>Да, это преимущество. Но с другой стороны в юнит тестами намного проще перевести код в состояние всех edge-case'ов (в которых в том числе могут выстрелить assert'ы) по сравнению с интеграционными тестами.

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

А в сложных штуках, которые из этих самых хелперов собираются, оказывается полно кода, который хоть и простой, но всё равно хорошо бы проверить. Но при этом не разбирать код на доступные тестам куски, т.к. это заметно дороже обходится. Комбинации из ассертов и интеграционных тестов тут альтернативы нет, кмк.

EP>100% code coverage не даёт гарантии попадания во все edge cases.

Ага. Для меня code coverage — удобнейший инструмент для подсветки новых / изменённых кусков кода, которые ещё не покрыты тестами. Само качество покрытия, понятное дело, автоматом не проверяется никак (если говорить про реальные языки, а не про фантастику с полной формальной верификацией кода), только ручками.
Re[30]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 10.08.16 17:30
Оценка:
Здравствуйте, ·, Вы писали:

EP>>более того — для формально верифицированного кода они не нужны.

·>Для формально верифицированного их разве кто-то пишет?

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

EP>>·>Если медленно — это уже проблема алгоритма.

EP>>Это ещё почему?
·>Точнее не так. Если медленно, то можно перенести ассерт в юнит-тест.

Sinix выше правильно заметил — assert'ы отрабатывают во время всех тестов, как юнит, так и интеграционных, и поэтому есть приличный шанс того что они поймают баг пропущенный непосредственно юнит-тестированием.

Более того, юнит-тест конкретного компонента может успешно пройти при наличии бага, или например двойного бага — то есть false positive. При этом внутренний assert мог поймать эти баги на этом же прогоне. То есть assert'ы это отличное дополнение unit-тестов.

EP>>·>При хорошем покрытии тестами ценность ассертов падает до нуля.

EP>>Точно также как и ценность других defensive примочек, а-ля bounds checking
·>Не точно также же. В проде bounds checking валит исключения

Да какая разница если у тебя в оттестированном и корректном коде не будет этих исключений?
То есть ты определись — либо у тебя код оттестирован и defensive programming не нужен, либо не оттестирован и ты тестируешь его на своих пользователях

EP>>>>С другой стороны, выключение части из проверок в runtime'е, ровно как и отсутствии часть проверок вообще — не делает программу некорректной.

EP>>·>Но только если ассерты расставлены корректно.
EP>>Что ты имеешь в виду? То что проверка внутри assert'а может иметь side-effect?
·>Да, и такое бывает, к сожалению.

Я уже сказал что это ловится тестированием и debug и release версий. Но встречается крайне редко — я видел подобное только когда человек не знал что такое assert.

EP>>·>Я что-то не понял что это. Судя по if (!condition)throw это не ассерты в понимании С++.

EP>>Там некоторые из них опциональные, и не попадают в Release.
·>Ух ты. Это как устроено? Что-то не могу разобраться...

Conditional

Conditional methods allow developers to create methods whose calls can be placed in the code and then either included or omitted during compilation based on a preprocessing symbol.


EP>>·>В unmanaged наоборот: когда может — работает правильно, и всегда быстро.

EP>>Не всегда быстро, только когда assert'ы отключены.
·>При релизном использовании отключены.

Совсем необязательно — я их видел в коммерческом продукте имеющем сотни миллионов установок

·>>>Есть конечно. Я говорю о корректности самого кода, а не логических ошибок в алгоритме.

EP>>В чём ты видишь отличие? Выход за пределы bounds это есть логическая ошибка, которой в корректном коде нет
·>Эта ошибка явно прописана в спеке языка

Да какая разница — это и есть логическая ошибка в твоём алгоритме.

EP>>>>P.S. Ничто не мешает оставить часть assert'ов включенных в Release. Для этого их обычно разбивают на классы "быстрые", "медленные", "очень медленные" — и уже пользователь библиотеки решает что попадёт в Release.

EP>>·>По-моему излишнее усложнение. Собственно на основании чего пользователь будет принимать решение?
EP>>1. На основании того какое быстродействие его устраивает
·>Чем быстрее, тем лучше, очевидно.

Совсем не очевидно, ибо это не единственный критерий.

EP>>2. На основании того насколько корректен его код (здесь речь идёт про библиотеку и пользовательский код, ассерты внутри библиотеки могут ловить ошибки в пользовательском коде).

·>Конечно, корректен, я что ламер некорректный код писать?

Тогда тебе и не нужен никакой defensive programming

·>А ты как корректность своего кода оцениваешь?


Зависит от конкретного случая — различные комбинации unit/integration тестов, разбиение на классы эквивалентности, поиск изоморфизмов, assert'ы на пред/пост-условия и ванрианты/инварианты, доказательства. Вот до чего пока не доходил, так это до выражения доказательств на формальных языках и их дальнейшей автоматизированной проверки.

·>А вообще для этого сценария придумали логи и кастомизируемые (в т.ч. в рантайм) уровни логгирования. Ассерты тут пихать не надо.


А причём тут логи? Если у тебя условие assert'а сфейлилось — то дальше всё может полететь в тартарары, и лучше всего пристрелить такую программу.
Отредактировано 10.08.2016 17:33 Evgeny.Panasyuk . Предыдущая версия .
Re[26]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 10.08.16 19:11
Оценка:
Здравствуйте, gandjustas, Вы писали:

EP>>>>То есть ещё раз, код C# чисто по построению намного труднее оптимизировать — для оптимизаций до уровней аналогичных C++ нужно либо язык модифицировать, либо делать оптимизаторы намного более мощные чем оптимизаторы C++

G>>>Язык тут не при чем.
EP>>Именно язык тут и при чём. Если писать на C++ в стиле C# — динамические замыкания, динамический IEnumerable, множество индерекций по памяти — то получим примерно такие же тормоза
G>Что такое "данимические замыкания" ? В IL замыкания превращаются просто в классы.

При этом передаются через параметры, сохраняются в классы и т.п. посредством динамического полиморфизма, стирая исходный тип.

G>Что такое "динамический IEnumerable"?


Динамический полиморфизм для обхода последовательностей.

G>Это в смысле IEnumerable не по массивам? Зачем его использовать в performance-critical коде?


Затем что последовательности могут быть выражены разными структурами данных.
Собственно о том и речь — в C++ я могу накручивать уровни абстракций даже в performance-critical коде, без жёсткого penalty.

G>А IEnumerable (foreach) с массивами действительно тормозит (накладные расходы на Enumerator оказываются больше, чем затратры на тело цикла). Как раз из-за недостатка инлайнинга, в C++ foreach нилайнится.


Так дело не в самом foreach — ты если распишешь его вручную, то он также будет тормозить, за счёт динамического полиморфизма..

G>Или ты имеешь ввиду использование ФВП для обхода массивов? Оно действительно и в C++, и в C# плохо работает. И в C++ и в C# такой код вручную оптимизируется.


ФВП в том числе. А с чего ты взял что они в C++ плохо работают? Наоборот, прекрасно работают и отлично оптимизируются.
Пример C++ -> JS vs C# как раз ФВП и использует.

G>>>Машинный код генерируется из IL. В нем все указанные тобой оптимизации делаются элементарно.

G>>>Но у JIT нет столько времени на пребразования, как у компилятора C++.
EP>>Что мешает сразу генерировать оптимизированный IL?
G>IL — высокоуровневый язык. Он и так достаточно оптимален на своем уровне.

И что из этого? C# версия без ФВП тоже компилируется в тот же самый "высокоуровневый IL", но работает быстрее. Версия с ФВП могла бы давать точно такой же IL.

EP>>Я выше привёл пример с трансляцией C++ -> JS. JS ещё "хуже" IL, но тем не менее он работает быстро.

G>Что "хуже" ?

Тем что JS более высокоуровневый.

G>Работает быстро за счет "hotspot". Большинство движков JS перекомпилируют код на основании профиля использования. Кроме того "работает быстро" — это когда не используются ФВП.


Вот именно, в исходном коде на C++ были ФВП и замыкание, в результирующем JS они были выоптимизированы компилятором C++, так как это элементарная операция (никакого динамического полиморфизма) — именно поэтому и быстро.

EP>>Можно взять этот JS выхлоп и перевести на C# — и он там тоже будет работать быстро, несмотря ни на какой IL

G>Если не используются ФВП, то да.

ФВП в коде на C++ есть, но в выхлопе оптимизатора их нет.

G>Вообще при небольших усилиях скорость C# аналогична C++. Даже статью на эту тему писал https://habrahabr.ru/post/266373/


Твой тест низкоуровневый, без абстракций, и полностью подтверждает мой тезис, точнее вторую часть:

C++ быстрый не от того что нативный, а от того что даёт бесплатные, либо крайне дешёвые абстракции.
Если на C#/Java писать код без абстракций, то по скорости он будет близок к аналогу на C++ — но такого кода будет намного больше

А вот первую часть ты можешь проверить сделав сортировку похожей на реальную, а именно абстрагировавшись от конкретного контейнера, конкретного типа элемента, и конкретного предиката. Например сравнив:
template<typename RandomAccessIterator, typename BinaryPredicate>
void sort(RandomAccessIterator m, unsigned n, BinaryPredicate p)
vs
void Sort(IList<T> m, Comparison<T> comparison)
Re[29]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.08.16 20:18
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:


EP>И всё же ты не понимаешь. Класс да, генерируется, да размер на стороне вызова известен, но вот внутри дженерика размер стёрт, даже после всех подстановок, в C++ же его размер внутри шаблона известен во время компиляции.

Какой размер внутри дженерика? Кто стер? В .NET вся информация о типах хранится, поэтому размер известен не только в compile-time, но и в run-time.

EP>Перечитай десять раз, посмотри примеры выше, обрати внимание на static_assert — если не дойдёт, то задавай конкретный вопрос.

Ты приведи пример на C#, который иллюстрирует то, что ты говоришь. Потому что сейчас это звучит как бред сумасшедшего.


EP>>>В C# же у тебя будет Func<...> одинакового размера для всех вариантов замыканий, независимо от их оригинального размера..

G>>Ты наверное что-то другое хочешь сказать, но не можешь это словами выразить.
EP>Я уже выразил, и пример привёл. Но ты, из-за своего неконструктивного настроя, не можешь это понять.
Ты выразил что-то про C#, а пример привел на C++. Это разные языки если что. Ты на C# пример приведи.

EP>>>2. Речь даже не столько про стоимость аллокации, а про то что она сильно мешает последующему инлайнингу.

G>>Ты причину и следствие путаешь.
EP>Не путаю.
Путаешь.

G>>Убрать аллокацию для замыкания можно, если вызов делегата можно заинлайнить по месту вызова. Но это не значит что наличие аллокации мешает инлайну.

EP>Именно мешает. Я смотрел генерируемый код C++ компиляторами — простые виртуальные вызовы инлайнятся, если же вставить динамическую аллокацию (при прочих равных), то инлайна не происходит.
Так то ограничение компилятора C++, принципиальных проблем инлайна с аллокациями нет. JIT умеет инлайнить методы с new.


G>>>>Даже с учетом сборки мусора амортизированная стоимость аллокации невелика.

EP>>>Она огромна по сравнению с отсуствием аллокаций
G>>В реальной программе аллокаций будет дофига в любом случае.

EP>Это на C# дофига аллокаций, на C++ их на порядки меньше, так как многое хранится по значению. Вектор объектов класса — это минимум одна аллокация, на C# — минимум N+1 аллокаций.

EP>И в любом случае 100*дофига намного больше чем просто дофига
Разница будет даже не в разы, а в единицы процентов. А вот количество аллокаций будет для .NET выше.

EP>>>>>Виртуальный вызов и прочее можно соптимизировать, но это очевидно более сложная задача чем заинлайнить простой вызов конкретного метода

G>>>>JIT занимается девиртуализацией вызовов, причем успешно.
EP>>>Ты читать не умеешь? "это очевидно более сложная задача"
G>>С чего ты взял что она сложная? Почти примитивная оптимизация.
EP>И всё таки ты читать не умеешь "более сложная"
Более сложная чем что? Какую еще часть твоей фразы надо прочитать, чтобы понять тайный смысл того, что ты пишешь?

EP>>>В любом случае это будет медленная динамическая хрень, против обычного вызова невиртуальной функции. И эту хрень намного тяжелее оптимизировать, простым преобразования C# -> C++ не отделаешься

G>>Это надо проверить.
EP>Что конкретно?
Мои тесты показывают, что .NET Native после компиляции дает такую же скорость, как аналогичный рукопашный код на C++.
И "медленная динамическая хрень" на .NET вполне нормально работает при прямой компиляции в C++.
Re[27]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.08.16 21:01
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

G>>Что такое "данимические замыкания" ? В IL замыкания превращаются просто в классы.

EP>При этом передаются через параметры, сохраняются в классы и т.п. посредством динамического полиморфизма, стирая исходный тип.
Ты бредишь
1) В замыканиях нетполиморфизма
2) В замыканиях нет женериков
3) В .NET вообще нет стирания типов в женериках

G>>Что такое "динамический IEnumerable"?

EP>Динамический полиморфизм для обхода последовательностей.
Пример кода покажи, не ясно о чем ты пишешь.

G>>Это в смысле IEnumerable не по массивам? Зачем его использовать в performance-critical коде?

EP>Затем что последовательности могут быть выражены разными структурами данных.
Не пойму о чем ты. Если у тебя массив или строка — пиши обычный цикл. Если там не массив и не строка, то пофиг — IEnumerable нормально работает.

EP>Собственно о том и речь — в C++ я могу накручивать уровни абстракций даже в performance-critical коде, без жёсткого penalty.

Это только если инлайнинг сработает. Об этом тебе и писали, дело не в языке, а в компиляторе. К сожалению для .NET негде такую оптимизацию производить.

G>>А IEnumerable (foreach) с массивами действительно тормозит (накладные расходы на Enumerator оказываются больше, чем затратры на тело цикла). Как раз из-за недостатка инлайнинга, в C++ foreach нилайнится.

EP>Так дело не в самом foreach — ты если распишешь его вручную, то он также будет тормозить, за счёт динамического полиморфизма..
Для обычных массивов jit оптимизирует foreach
var xs = new[] { 1, 2, 3 };
var s = 0;
foreach (var item in xs)
{
    s += item;    
}


выхлоп:
            var s = 0;
019A34D5  xor         esi,esi  
            foreach (var item in xs)
019A34D7  xor         ecx,ecx  
019A34D9  mov         edi,dword ptr [edx+4]  
019A34DC  test        edi,edi  
019A34DE  jle         019A34EB  

            foreach (var item in xs)
019A34E0  mov         eax,dword ptr [edx+ecx*4+8]  
            {
                s += item;    
019A34E4  add         esi,eax  
019A34E6  inc         ecx  
            foreach (var item in xs)
019A34E7  cmp         edi,ecx  
019A34E9  jg          019A34E0  
            }

Найди тут виртуальные вызовы.

Для не-массивов применяется оптимизация:
1) Реализация IEnumerator делается структурой
2) GetEnumerator возвращает структуру
3) foreach в этом случае не использует ни аллокаций, ни приведений к интерфейсу, ни полиморфизм


C IEnumerable другая проблема, которая связана с ФВП. Вообще ФП в C# довольно медленно работает, не создавался язык под него.

G>>Или ты имеешь ввиду использование ФВП для обхода массивов? Оно действительно и в C++, и в C# плохо работает. И в C++ и в C# такой код вручную оптимизируется.


EP>ФВП в том числе. А с чего ты взял что они в C++ плохо работают? Наоборот, прекрасно работают и отлично оптимизируются.

EP>Пример C++ -> JS vs C# как раз ФВП и использует.
За счет инлайнинга, который JIT не делает.
Но ты же не будешь в performance-critical на автоматический инлайнинг полагаться.

G>>>>Машинный код генерируется из IL. В нем все указанные тобой оптимизации делаются элементарно.

G>>>>Но у JIT нет столько времени на пребразования, как у компилятора C++.
EP>>>Что мешает сразу генерировать оптимизированный IL?
G>>IL — высокоуровневый язык. Он и так достаточно оптимален на своем уровне.

EP>И что из этого? C# версия без ФВП тоже компилируется в тот же самый "высокоуровневый IL", но работает быстрее. Версия с ФВП могла бы давать точно такой же IL.

Не могла бы, потому что делегаты. В F# отказались от делегатов, там лучше работает.

EP>>>Я выше привёл пример с трансляцией C++ -> JS. JS ещё "хуже" IL, но тем не менее он работает быстро.

G>>Что "хуже" ?
EP>Тем что JS более высокоуровневый.
И что?

G>>Работает быстро за счет "hotspot". Большинство движков JS перекомпилируют код на основании профиля использования. Кроме того "работает быстро" — это когда не используются ФВП.

EP>Вот именно, в исходном коде на C++ были ФВП и замыкание, в результирующем JS они были выоптимизированы компилятором C++, так как это элементарная операция (никакого динамического полиморфизма) — именно поэтому и быстро.
Ну так ты продолжаешь доказывать, что проблема в языке C#. А проблема в компиляторе, который ФВП не инлайнит. О чем я тебе и говорил с самого начала.
Re[30]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 10.08.16 21:03
Оценка:
Здравствуйте, gandjustas, Вы писали:

EP>>И всё же ты не понимаешь. Класс да, генерируется, да размер на стороне вызова известен, но вот внутри дженерика размер стёрт, даже после всех подстановок, в C++ же его размер внутри шаблона известен во время компиляции.

G>Какой размер внутри дженерика?

Размер структуры/класса.

G>Кто стер?


Программист, в том момент когда передал замыкание в функцию принимающую Func<...>. Для разных замыканий тип один и тот же — Func<...>

G>В .NET вся информация о типах хранится, поэтому размер известен не только в compile-time, но и в run-time.


Внутри дженерика эта информация во время компиляции неизвестна. Известно только то что есть в типах, а тип один для разных замыканий Func<...>

EP>>Перечитай десять раз, посмотри примеры выше, обрати внимание на static_assert — если не дойдёт, то задавай конкретный вопрос.

G>Ты приведи пример на C#, который иллюстрирует то, что ты говоришь.

Я приведу на C++, а ты попробуй привести аналог на C# (хотя бы псевдокод):
template<unsigned SIZE> void size_is();

template<typename F>
auto foo(F f)
{
    size_is<sizeof(F)>();
    return f();
}

int main()
{
    auto x = 0, y = 1;
    foo([=]{ return x; });
    foo([=]{ return x + y; });
}
LIVE DEMO
/tmp/cclb4DzB.o: In function `_Z3fooIZ4mainEUlvE_EDaT_':
main.cpp:(.text+0x1c): undefined reference to `void size_is<4u>()'
/tmp/cclb4DzB.o: In function `_Z3fooIZ4mainEUlvE0_EDaT_':
main.cpp:(.text+0x54): undefined reference to `void size_is<8u>()'
collect2: error: ld returned 1 exit status


В foo предаются два разных замыкания с одинаковой сигнатурой. Размеры замыканий разные. Вызов size_is внутри foo демонстрирует то, что внутри foo размеры этих замыканий известны по построению, по правилам языка, даже без работы всяких оптимизаторов.
Вызов f() внутри — полностью статический и прямой, без всяких косвеностей и динамического полиморфизма — опять таки, по построению.

G>Потому что сейчас это звучит как бред сумасшедшего.


Не хами. Если ты чего-то не понимаешь, то необязательно называть это бредом, это не конструктивно. Я всегда привожу необходимые примеры.

EP>>Именно мешает. Я смотрел генерируемый код C++ компиляторами — простые виртуальные вызовы инлайнятся, если же вставить динамическую аллокацию (при прочих равных), то инлайна не происходит.

G>Так то ограничение компилятора C++

Так ты же говоришь что код C#/.NET будет транслироваться в C++ — я показываю что только этого недостаточно.

G>принципиальных проблем инлайна с аллокациями нет.


Принципиальных нет, я говорю о том что это сложнее.
Точно также как нет и принципиальных проблем генерировать супер-оптимальный код из Python.

EP>>>>>>Виртуальный вызов и прочее можно соптимизировать, но это очевидно более сложная задача чем заинлайнить простой вызов конкретного метода
G>>>>>JIT занимается девиртуализацией вызовов, причем успешно.
EP>>>>Ты читать не умеешь? "это очевидно более сложная задача"
G>>>С чего ты взял что она сложная? Почти примитивная оптимизация.
EP>>И всё таки ты читать не умеешь "более сложная"
G>Более сложная чем что? Какую еще часть твоей фразы надо прочитать, чтобы понять тайный смысл того, что ты пишешь?

Выделил. Могу продублировать:

EP>>>>>>Виртуальный вызов и прочее можно соптимизировать, но это очевидно более сложная задача чем заинлайнить простой вызов конкретного метода


EP>>>>В любом случае это будет медленная динамическая хрень, против обычного вызова невиртуальной функции. И эту хрень намного тяжелее оптимизировать, простым преобразования C# -> C++ не отделаешься

G>>>Это надо проверить.
EP>>Что конкретно?
G>Мои тесты показывают, что .NET Native после компиляции дает такую же скорость, как аналогичный рукопашный код на C++.

Твои тесты низкоуровневые. Собственно я выше уже много раз сказал, что на низком уровне на C#/Java можно достичь скорости близкой к C++ (не беря в расчёт автовекторизацию и подобное). Мне не нужно это доказывать, я сам это говорю, андерстенд?
Если же повысить уровень абстракции — сделать сортировку произвольных элементов, произвольных последовательностей, произвольным предикатом — так как выглядят реальные сортировки а-ля std::sort — то результат C++ не изменится, а вот C# во много раз просядет. Собственно мой тест с JS ровно это и продемонстрировал, и там даже абстракций было меньше чем у сортировки.
Re[26]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: CreatorCray  
Дата: 10.08.16 21:03
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Аллокация на куче для .NET на порядок дешевле аллокации на куче для C++.

В целом неверно.

В стандарте С++ не определено как должен быть реализован аллокатор.
Поэтому скорость "аллокации на куче для C++" просто не определена.

Пару лет назад я показывал как легко и быстро сделать аллокацию в С++ быстрее .NET.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[27]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: CreatorCray  
Дата: 10.08.16 21:03
Оценка: 1 (1)
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>И это причём GCC, а не отстающий MS.

Про МС хз, давно на него не смотрел.
Но от качества кода, генерируемого GCC, лично я не в восторге.

Не так давно разбирался почему вдруг одна функция стала жрать дофига стека. В кернеле это критично, так что у нас в build есть всякие анализаторы которые как раз на это и сработали.
Оказалось что GCC для каждого error out return зачем то заранее зарезервировал отдельный кусок стека, и каждый раз сохранял туда все регистры, вызывал какую то мелкую функцию, которая использовала только 2 регистра, вытягивал все регистры назад, сразу же большинство из них занулял и делал ret.
И так много раз, с отдельным куском стека на каждый return. x64 release build.
Такого шлака я нигде ещё не видел.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[27]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.08.16 21:10
Оценка:
Здравствуйте, CreatorCray, Вы писали:

CC>Пару лет назад я показывал как легко и быстро сделать аллокацию в С++ быстрее .NET.


Видел десяток проектов на C++ — везде стандартный аллокатор (внезапно).
Re[28]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: CreatorCray  
Дата: 10.08.16 21:23
Оценка: +1
Здравствуйте, gandjustas, Вы писали:

CC>>Пару лет назад я показывал как легко и быстро сделать аллокацию в С++ быстрее .NET.

G>Видел десяток проектов на C++ — везде стандартный аллокатор (внезапно).

Ну дык любую подсистему начинают трогать только когда она становится узким местом, по результатам профайлинга.
В С++ такое случается довольно редко, потому как там обычно не делают alloc/free на каждый чих.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[28]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 10.08.16 21:34
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>>>Что такое "данимические замыкания" ? В IL замыкания превращаются просто в классы.

EP>>При этом передаются через параметры, сохраняются в классы и т.п. посредством динамического полиморфизма, стирая исходный тип.
G>Ты бредишь

Хамство это конечно отличный, а главное конструктивный аргумент. Зачем думать, анализировать, спрашивать — когда можно просто нахамить — "не понимаю значит бред"

G>В замыканиях нетполиморфизма


Не в самих замыканиях. Напиши пример ФВП которая принимает простейшее замыкание.

G>>>Что такое "динамический IEnumerable"?

EP>>Динамический полиморфизм для обхода последовательностей.
G>Пример кода покажи, не ясно о чем ты пишешь.

Вот.

G>>>Это в смысле IEnumerable не по массивам? Зачем его использовать в performance-critical коде?

EP>>Затем что последовательности могут быть выражены разными структурами данных.
G>Не пойму о чем ты.

std::vector, std::deque, std::string — это всё random access последовательности. На них можно писать алгоритмы на итераторах, без abstraction penalty.
На C# IList даст приличную просадку. И это лишь один из примеров.

EP>>Собственно о том и речь — в C++ я могу накручивать уровни абстракций даже в performance-critical коде, без жёсткого penalty.

G>Это только если инлайнинг сработает.

И что характерно он работает, потому что язык к этому располагает. Потому что можно использовать ФВП, замыкания, и т.п. без всякого динамического полиморфизма.

G>>>А IEnumerable (foreach) с массивами действительно тормозит (накладные расходы на Enumerator оказываются больше, чем затратры на тело цикла). Как раз из-за недостатка инлайнинга, в C++ foreach нилайнится.

EP>>Так дело не в самом foreach — ты если распишешь его вручную, то он также будет тормозить, за счёт динамического полиморфизма..
G>Для обычных массивов jit оптимизирует foreach

Вообще-то про foreach начал говорить ты, сначала сказал что тормозит, потом привёл пример где не тормозит. Круто чё.
Я же говорил про IEnumerable.

G>C IEnumerable другая проблема, которая связана с ФВП. Вообще ФП в C# довольно медленно работает, не создавался язык под него.


О чём и речь

G>>>Или ты имеешь ввиду использование ФВП для обхода массивов? Оно действительно и в C++, и в C# плохо работает. И в C++ и в C# такой код вручную оптимизируется.

EP>>ФВП в том числе. А с чего ты взял что они в C++ плохо работают? Наоборот, прекрасно работают и отлично оптимизируются.
EP>>Пример C++ -> JS vs C# как раз ФВП и использует.
G>За счет инлайнинга, который JIT не делает.
G>Но ты же не будешь в performance-critical на автоматический инлайнинг полагаться.

Так в том-то и фишка что буду, because I can! Зачем мне делать его руками, для всех используемых комбинаций алгоритмов * замыканий * последовательностей * прочих абстракций, когда с этим прекрасно справляется компилятор?
Там где это критично — проверю сгенерированный код, сделаю замеры — и добавлю простой тест с замерами на эту тему

G>>>>>Машинный код генерируется из IL. В нем все указанные тобой оптимизации делаются элементарно.

G>>>>>Но у JIT нет столько времени на пребразования, как у компилятора C++.
EP>>>>Что мешает сразу генерировать оптимизированный IL?
G>>>IL — высокоуровневый язык. Он и так достаточно оптимален на своем уровне.
EP>>И что из этого? C# версия без ФВП тоже компилируется в тот же самый "высокоуровневый IL", но работает быстрее. Версия с ФВП могла бы давать точно такой же IL.
G>Не могла бы, потому что делегаты.

То есть таки язык мешает оптимизациям?

G>>>Работает быстро за счет "hotspot". Большинство движков JS перекомпилируют код на основании профиля использования. Кроме того "работает быстро" — это когда не используются ФВП.

EP>>Вот именно, в исходном коде на C++ были ФВП и замыкание, в результирующем JS они были выоптимизированы компилятором C++, так как это элементарная операция (никакого динамического полиморфизма) — именно поэтому и быстро.
G>Ну так ты продолжаешь доказывать, что проблема в языке C#.

Проблема в языке в том числе, за счёт повсеместного динамического полиморфизма и избыточных индерекций по памяти.
Re[27]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.08.16 04:21
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здравствуйте, Sinclair, Вы писали:


S>>Эмм. Это будет иметь значение только в том случае, если мы рассматриваем инлайнинг f. А надо рассматривать инлайнинг foo — потому что после него код приобретает вид

S>>
S>>class ConcreteF
S>>{
S>>  int x;
S>>  int callee() { return x;}
S>>}
S>>var cf = new ConcreteF(0);
S>>return cf.callee();
S>>


EP>Не верно, так как непосредственно после инлайнинга получаем:

EP>
EP>class ConcreteF
EP>{
EP>  int x;
EP>  int callee() { return x;}
EP>}
EP>Func<...> cf = new ConcreteF(0);
EP>return cf.callee();
EP>

И в чём различие? В том, что номинативный тип cf — Func<int>, а фактический — ConcreteF?
Я же написал, что задача "вычислить точный тип в cf.callee()" решается одинаково хорошо независимо от языка. Тут даже спекулятивный инлайнинг не нужен, т.к. после тривиального преобразования (см. тж. SSA form) имеем:
class ConcreteF
{
  int x;
  int callee() { return x;}
}
return (new ConcreteF(0)).callee();

EP>Так вот я и говорю, что даже C++ компиляторы делают подобную оптимизацию только для простых случаев
Автор: Evgeny.Panasyuk
Дата: 26.02.15
, если же вставить аллокацию — то всё облом
Автор: Evgeny.Panasyuk
Дата: 24.02.15
. И это причём GCC, а не отстающий MS.

Имхо, тут дело не в аллокации, а тупо в том, что оптимизатор для лямбд недокручен. В примере компилятор заинлайнил и foo и bar. Но вот в bar он смог заинлайнить и дальше — надо полагать, по причине знания точного типа. А пот почему он не стал девиртуализовывать и инлайнить лямбду — хрен его знает. По-хорошему, надо проверять на интеловском компиляторе — они в области девиртуализации, как спекулятивной, так и консервативной, были во времена моей юности впереди планеты всей.
EP>1. Для этого есть Link-Time Code Generation / Link Time Optimization
Ну я про него слышал, но отношусь скептически. Как оно вообще работает? Неужто компилятор оставляет фрагменты синтаксических деревьев внутри бинарного кода, на случай если они потребуются линкеру?
То есть я могу поверить, что линкер способен вклеить бинарник на место вызова, но как он будет проводить дальнейшие оптимизации лично мне непонятно. А ведь инлайнинг сам по себе малополезен — стоимость вызова обычно пренебрежимо мала. Его ценность — в том, что он разблокирует широкий класс дополнительных оптимизаций. Ровно как в нашем примере — мы не можем оптимизировать код функции foo сам по себе, т.к. он слишком обобщённый.
Зато после встраивания foo в main у нас становится доступно много контекстной информации, и мы можем делать всякие умные вещи.
EP>2. Замыкания, ФВП и прочее в большинстве случаев именно в исходниках и поставляются.
Это не потому, что так удобнее, а потому, что другого выхода нет.
EP>Именно из ограничений языка и вытекают дополнительные сложности оптимизации.
Основная дополнительная сложность — ресурсные ограничения.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[31]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 11.08.16 06:46
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

S>>Да и в C++ макросы оочень часто используются


EP>Во-первых не часто.

EP>Во-вторых изначально Страуструп пытался использовать макросы для обобщённого программирования — это очень неудобно, собственно поэтому мы и имеем шаблоны. Ты же предлагаешь воспроизводить грабли тридцатилетней давности посредством текстовых макросов
Я ничего такого не предлагаю. Я предлагаю использовать компиляцию в MSIL с опциями предполагающими специализацию дженериков и делегатов с инлайнингом методов.
Это можно добиться разными способами. Можно кодогенерацией, а можно и за счет преобразования MSIL кода.
и солнце б утром не вставало, когда бы не было меня
Re[2]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: ZloeBablo Германия  
Дата: 11.08.16 07:03
Оценка: +1
__>Как вы полагаете какие люди идут в си шарп? Правильно он сначала был велоинструктором 10 лет, потом программистом Шарепоинта на дельфи. Потом он еще 10 лет познавал гит (как некоторые эксперты си шарп на рсдн, до сих пор отсмеяться не могу).

тебе не кажется что в нетфликс набирают таких 10 человек. А микрософт сотнями... а то и тысячами... А так же надеюсь ты взял эти зарплаты из одного региона.
Re[31]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: · Великобритания  
Дата: 11.08.16 10:36
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>>>более того — для формально верифицированного кода они не нужны.

EP>·>Для формально верифицированного их разве кто-то пишет?
EP>Я имею в виду то, что после того как есть результат формальной верификации, можно их выключить и это никак не повлияют на корректность.
Если код формально верифицируется, то ассерты не нужны. Вообще. Смысл?

EP>·>Точнее не так. Если медленно, то можно перенести ассерт в юнит-тест.

EP>Sinix выше правильно заметил — assert'ы отрабатывают во время всех тестов, как юнит, так и интеграционных, и поэтому есть приличный шанс того что они поймают баг пропущенный непосредственно юнит-тестированием.
EP>Более того, юнит-тест конкретного компонента может успешно пройти при наличии бага, или например двойного бага — то есть false positive. При этом внутренний assert мог поймать эти баги на этом же прогоне. То есть assert'ы это отличное дополнение unit-тестов.
А конкретнее? Если ассерт можешь написать, почему это же нельзя выразить тестом?

EP>>>Точно также как и ценность других defensive примочек, а-ля bounds checking

EP>·>Не точно также же. В проде bounds checking валит исключения
EP>Да какая разница если у тебя в оттестированном и корректном коде не будет этих исключений?
Потенциально будет — если что-то неожиданно поломается, например, кто-то неверно использует компонент или не так "быстренько баг пофиксили".

EP>То есть ты определись — либо у тебя код оттестирован и defensive programming не нужен, либо не оттестирован и ты тестируешь его на своих пользователях

Оттестирован на требуемых спекой сценариях. В неожиданных сценариях надо аккуратно фейлиться, а не делать что попало где попало.

EP>>>Там некоторые из них опциональные, и не попадают в Release.

EP>·>Ух ты. Это как устроено? Что-то не могу разобраться...
EP>Conditional
EP>

EP>Conditional methods allow developers to create methods whose calls can be placed in the code and then either included or omitted during compilation based on a preprocessing symbol.

А оно правда надо? JIT прекрасно справляется и с тупым finalStaticBool=System.getProperty("DEBUG").....if(finalStaticBool) return.

EP>·>При релизном использовании отключены.

EP>Совсем необязательно — я их видел в коммерческом продукте имеющем сотни миллионов установок
Гы-гы. Ведь явно не от хорошей жизни, им тупо пришлось использовать ассерты не по назначению.

EP>>>В чём ты видишь отличие? Выход за пределы bounds это есть логическая ошибка, которой в корректном коде нет

EP>·>Эта ошибка явно прописана в спеке языка
EP>Да какая разница — это и есть логическая ошибка в твоём алгоритме.
Так она и сломает мой алгоритм, а не совершенно не относящийся к моему алгоритму код.

EP>>>·>По-моему излишнее усложнение. Собственно на основании чего пользователь будет принимать решение?

EP>>>1. На основании того какое быстродействие его устраивает
EP>·>Чем быстрее, тем лучше, очевидно.
EP>Совсем не очевидно, ибо это не единственный критерий.
Т.е. это вообще не критерий, на выбор-то не влияет.

EP>>>2. На основании того насколько корректен его код (здесь речь идёт про библиотеку и пользовательский код, ассерты внутри библиотеки могут ловить ошибки в пользовательском коде).

EP>·>Конечно, корректен, я что ламер некорректный код писать?
EP>Тогда тебе и не нужен никакой defensive programming
Т.е. предлагаешь какие-то субъективные оценки, гадание на кофейной гуще использовать для принятия решения какие ассерты включать, а какие нет?

EP>·>А ты как корректность своего кода оцениваешь?

EP>Зависит от конкретного случая — различные комбинации unit/integration тестов, разбиение на классы эквивалентности, поиск изоморфизмов, assert'ы на пред/пост-условия и ванрианты/инварианты, доказательства. Вот до чего пока не доходил, так это до выражения доказательств на формальных языках и их дальнейшей автоматизированной проверки.

EP>·>А вообще для этого сценария придумали логи и кастомизируемые (в т.ч. в рантайм) уровни логгирования. Ассерты тут пихать не надо.

EP>А причём тут логи? Если у тебя условие assert'а сфейлилось — то дальше всё может полететь в тартарары, и лучше всего пристрелить такую программу.
Так говорю же, использование ассертов не по назначению. Сфейлилось совсем — брось исключение, оно обработается как надо, а если сфейлилось, но не очень опасно, то пожалуйся в лог и продожи работу. Зачем куда-то лететь-то сразу?

В общем, подытожу. Ассерты нужны если:
1. Плохо дело с юнит-тестами. Ассерт куда угодно воткнуть легко и хоть какой-то эффект есть.
2. Плохо дело с логгированием. Нет нормального способа сообщать о каких-то непредвиденных ситуациях.
3. Плохо дело с обработкой ошибок. Проще грохнуть всё приложение, чем кинуть исключение или нормально обработать ошибочную ситуацию.

Т.е. получается что ассерт это такой индикатор code smells.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[28]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 11.08.16 11:08
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>И в чём различие? В том, что номинативный тип cf — Func<int>, а фактический — ConcreteF?


Да, в этом в том числе. Аллокация, динамический полиморфизм и необходимость более глубоких уровней инлайнинга.
Всё решаемо, но очевидно сложнее чем инлайнинг прямого вызова без аллокаций, причём на меньшей глубине.

И это только один из аспектов. Другой — вездесущие аллокации, которые даже если считать как zero cost, и не учитывать GC вовсе — всё равно являются индикатором увеличенной ветвистости по памяти, что само по себе является большим тормозом. Хорошо хоть структуры есть, но они ограниченные
Автор: Evgeny.Panasyuk
Дата: 11.10.14
, и не являются полноценной заменой классов.

S>Я же написал, что задача "вычислить точный тип в cf.callee()" решается одинаково хорошо независимо от языка.


Так дело в том что в C++ нет задачи вычислять фактический вызываемый метод — он известен по построению, ещё до любых оптимизаций.

EP>>Так вот я и говорю, что даже C++ компиляторы делают подобную оптимизацию только для простых случаев
Автор: Evgeny.Panasyuk
Дата: 26.02.15
, если же вставить аллокацию — то всё облом
Автор: Evgeny.Panasyuk
Дата: 24.02.15
. И это причём GCC, а не отстающий MS.

S>Имхо, тут дело не в аллокации, а тупо в том, что оптимизатор для лямбд недокручен.

Какой-то отдельный оптимизатор лямбд не нужен. Лямбда это обычная структура с невиртуальным методом operator()(...) внутри. Структуры такого типа повсеместно встречаются более 20 лет, и ничего особенного в них нет.
И в тех местах где нет динамического полиморфизма, оптимизаторы всех mainstream компиляторов прекрасно с ними справляются.

S>В примере компилятор заинлайнил и foo и bar. Но вот в bar он смог заинлайнить и дальше — надо полагать, по причине знания точного типа.


Да, там и тип известен, и аллокаций нет.

S>А пот почему он не стал девиртуализовывать и инлайнить лямбду — хрен его знает.


В примере по первой ссылке ситуация подобная — конкретный тип лямбды стирается, но при этом нет аллокаций — и в таком варианте оптимизаторы (и GCC, и Clang) генерируют код идентичный версии с конкретным типом.

S>По-хорошему, надо проверять на интеловском компиляторе — они в области девиртуализации, как спекулятивной, так и консервативной, были во времена моей юности впереди планеты всей.


Clang смог заинлайнить пример по второй ссылке (с аллокацией и косвенным вызовом), но как-то частично и не полностью (не смотря на SSA), то есть далеко от идеала.
Даже если какой-то из компиляторов (а-ля Intel) сможет сделать полную оптимизацию в худшем случае, то всё равно не опровергает мой тезис — оптимизировать такие конструкции сложнее чем обычные прямые вызовы без аллокаций. Рассмотренный пример — простейший, там даже лямбды не захватывают никакие переменные — по сути обычные функции.

EP>>1. Для этого есть Link-Time Code Generation / Link Time Optimization

S>Ну я про него слышал, но отношусь скептически. Как оно вообще работает? Неужто компилятор оставляет фрагменты синтаксических деревьев внутри бинарного кода, на случай если они потребуются линкеру?

Практически так — только встраивает не синтаксические деревья С++, а IL (тот же который используется при обычной оптимизации) в объектные файлы. И при линковке вызывается тот же бэкенд что и оптимизирует код в обычных случаях.

S>А ведь инлайнинг сам по себе малополезен — стоимость вызова обычно пренебрежимо мала. Его ценность — в том, что он разблокирует широкий класс дополнительных оптимизаций.


Да, естественно — часто это главное преимущество.

Тем не менее, стоимость вызова, а особенно нескольких вложенных, может существенно перевешивать стоимость выполняемой операции.
В обобщённом коде не редко встречается ситуация когда когда функция лишь является враппером над другой, и ничего по сути не делает — и так несколько уровней.
Например разнообразные обёртки над итераторами — поверх исходного итератора накручивается несколько уровней других (transform iterator, etc), при этом часть из операций просто forward'ятся, а конечная это например обычный инкремент указателя. В таких случаях стоимость вызовов (не столько безусловный переход, сколько передача параметров и дополнительный код) — может быть решающей.
Или например функции с переменным числом аргументов (через variadic templates) часто разруливаются рекурсивно — по сути добавляя лишний вызов на каждый аргумент.

EP>>2. Замыкания, ФВП и прочее в большинстве случаев именно в исходниках и поставляются.

S>Это не потому, что так удобнее, а потому, что другого выхода нет.

Да, экспорта шаблонов нету. Там где нужно скрыть исходники ФВП приходится стирать типы (например через std::function), либо поставлять только некоторые из воплощений шаблонов.
Но многие из используемых ФВП именно в исходниках и поставляются.
Re[31]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 11.08.16 11:31
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здравствуйте, gandjustas, Вы писали:


EP>>>И всё же ты не понимаешь. Класс да, генерируется, да размер на стороне вызова известен, но вот внутри дженерика размер стёрт, даже после всех подстановок, в C++ же его размер внутри шаблона известен во время компиляции.

G>>Какой размер внутри дженерика?
EP>Размер структуры/класса.
А он тут при чем?

G>>Кто стер?

EP>Программист, в том момент когда передал замыкание в функцию принимающую Func<...>. Для разных замыканий тип один и тот же — Func<...>
Ты хочешь сказать, что компилятор не знает как получить класс-замыкание функции-параметра? Это чушь полнейшая.


G>>В .NET вся информация о типах хранится, поэтому размер известен не только в compile-time, но и в run-time.

EP>Внутри дженерика эта информация во время компиляции неизвестна. Известно только то что есть в типах, а тип один для разных замыканий Func<...>
Все известно, но для программиста недоступно. Потому что не нужно.

EP>>>Перечитай десять раз, посмотри примеры выше, обрати внимание на static_assert — если не дойдёт, то задавай конкретный вопрос.

G>>Ты приведи пример на C#, который иллюстрирует то, что ты говоришь.

EP>Я приведу на C++, а ты попробуй привести аналог на C# (хотя бы псевдокод):...

Прости, но это говно. В реальности auto foo(F f) не дает никакой информации о том какой должен быть F. Скорее у тебя будет вместо F тип std::function и появится та же самая косвенность.
Только компилятор C++ через инлайнинг эту косвенность уберет, а C# — нет. Не занимается он этим.


G>>Потому что сейчас это звучит как бред сумасшедшего.

EP>Не хами. Если ты чего-то не понимаешь, то необязательно называть это бредом, это не конструктивно. Я всегда привожу необходимые примеры.
Ты пытаешься обилием "умных слов" скрыть свое поверхностное знание. Только ты не учел, что есть люди, которые "умные слова" понимают.

EP>>>Именно мешает. Я смотрел генерируемый код C++ компиляторами — простые виртуальные вызовы инлайнятся, если же вставить динамическую аллокацию (при прочих равных), то инлайна не происходит.

G>>Так то ограничение компилятора C++
EP>Так ты же говоришь что код C#/.NET будет транслироваться в C++ — я показываю что только этого недостаточно.
А по моим замерам — достаточно. То есть достаточно иметь компилятор, в который вложено на порядок больше трудозатрат, чем в компилятор C# и C# будет работать не хуже C++.

G>>принципиальных проблем инлайна с аллокациями нет.

EP>Принципиальных нет, я говорю о том что это сложнее.
Нет, ты говорил что аллокации мешают инлайну.

EP>Точно также как нет и принципиальных проблем генерировать супер-оптимальный код из Python.

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

G>>Более сложная чем что? Какую еще часть твоей фразы надо прочитать, чтобы понять тайный смысл того, что ты пишешь?

EP>Выделил. Могу продублировать:
EP>

EP>>>>>>>Виртуальный вызов и прочее можно соптимизировать, но это очевидно более сложная задача чем заинлайнить простой вызов конкретного метода

Успокойся уже. Оптимизировать вирутальные вызовы несложно. Но без мощного инлайна это бывает невозможно. У JIT нет времени делать инлайн в несколько проходов, увы.

EP>Если же повысить уровень абстракции — сделать сортировку произвольных элементов, произвольных последовательностей, произвольным предикатом — так как выглядят реальные сортировки а-ля std::sort — то результат C++ не изменится, а вот C# во много раз просядет. Собственно мой тест с JS ровно это и продемонстрировал, и там даже абстракций было меньше чем у сортировки.

Ты std::sort называешь высокоуровневым кодом? Прости, смешно.

В реальности такой подход не работает. Ты не сможешь написать эффективную сортировку, которая работает и для массива, и для односвязного списка. По факту у тебя будет несколько специализаций под разные типы контейнеров.
Re[29]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 11.08.16 11:51
Оценка: +1
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здравствуйте, gandjustas, Вы писали:


G>>>>Что такое "данимические замыкания" ? В IL замыкания превращаются просто в классы.

EP>>>При этом передаются через параметры, сохраняются в классы и т.п. посредством динамического полиморфизма, стирая исходный тип.
G>>Ты бредишь
EP>Хамство это конечно отличный, а главное конструктивный аргумент. Зачем думать, анализировать, спрашивать — когда можно просто нахамить — "не понимаю значит бред"
Ты пытаешься говорить умные слова, не понимая их смысл. Это и есть бред.

G>>В замыканиях нетполиморфизма

EP>Не в самих замыканиях. Напиши пример ФВП которая принимает простейшее замыкание.
Там тоже нет полиморфизма.

G>>>>Что такое "динамический IEnumerable"?

EP>>>Динамический полиморфизм для обхода последовательностей.
G>>Пример кода покажи, не ясно о чем ты пишешь.
EP>Вот.
И зачем его использовать в performance-critical коде?

G>>>>Это в смысле IEnumerable не по массивам? Зачем его использовать в performance-critical коде?

EP>>>Затем что последовательности могут быть выражены разными структурами данных.
G>>Не пойму о чем ты.

EP>std::vector, std::deque, std::string — это всё random access последовательности. На них можно писать алгоритмы на итераторах, без abstraction penalty.

Неправда. Эффективный sort для vector будет отличаться от эффективного sort для deque. Abstraction penality это не потому что компилятор не умеет девиртуализировать вызовы, а потому что детали абстрагируемого кода могут повлиять на быстродейсвтие.

EP>На C# IList даст приличную просадку. И это лишь один из примеров.

Просадку где?

EP>>>Собственно о том и речь — в C++ я могу накручивать уровни абстракций даже в performance-critical коде, без жёсткого penalty.

G>>Это только если инлайнинг сработает.
EP>И что характерно он работает, потому что язык к этому располагает. Потому что можно использовать ФВП, замыкания, и т.п. без всякого динамического полиморфизма.
Язык тут не при чем. 20 лет назад C++ был почти такой же, а инлайнинга почти не было. Странно, да?
Ты путеашь теплое с мягким. Быстродействие С++ — следствие миллинов трудочасов, вложенных в компилятор, а не свойство языка.
Например сейчас JS — достаточно быстрый язык. А 10 лет назад был одним из самых медленных. JS как язык за это время изменился? Практически нет. Зато гугл потратил огромную сумму денег на разработку v8 движка.

G>>>>А IEnumerable (foreach) с массивами действительно тормозит (накладные расходы на Enumerator оказываются больше, чем затратры на тело цикла). Как раз из-за недостатка инлайнинга, в C++ foreach нилайнится.

EP>>>Так дело не в самом foreach — ты если распишешь его вручную, то он также будет тормозить, за счёт динамического полиморфизма..
G>>Для обычных массивов jit оптимизирует foreach

EP>Вообще-то про foreach начал говорить ты, сначала сказал что тормозит, потом привёл пример где не тормозит. Круто чё.

Процитирую твою фразу:

Так дело не в самом foreach — ты если распишешь его вручную, то он также будет тормозить, за счёт динамического полиморфизма..

Оказывается дело банально в компиляторе, который умеет генерировать эффективный код.

EP>Я же говорил про IEnumerable.

Ты хоть проверял какой код генерируется? Может там тоже нет виртуальных вызовов, девиртуализация срабатывает.

G>>C IEnumerable другая проблема, которая связана с ФВП. Вообще ФП в C# довольно медленно работает, не создавался язык под него.

EP>О чём и речь
Проблема в компиляторе, вернее в JIT, а не в самом языке.

G>>>>Или ты имеешь ввиду использование ФВП для обхода массивов? Оно действительно и в C++, и в C# плохо работает. И в C++ и в C# такой код вручную оптимизируется.

EP>>>ФВП в том числе. А с чего ты взял что они в C++ плохо работают? Наоборот, прекрасно работают и отлично оптимизируются.
EP>>>Пример C++ -> JS vs C# как раз ФВП и использует.
G>>За счет инлайнинга, который JIT не делает.
G>>Но ты же не будешь в performance-critical на автоматический инлайнинг полагаться.

EP>Так в том-то и фишка что буду, because I can! Зачем мне делать его руками, для всех используемых комбинаций алгоритмов * замыканий * последовательностей * прочих абстракций, когда с этим прекрасно справляется компилятор?

Многие как раз делают иначе, постностью отказываясь от фич C++. Тот же v8.
Они чего-то не знают?


G>>>>>>Машинный код генерируется из IL. В нем все указанные тобой оптимизации делаются элементарно.

G>>>>>>Но у JIT нет столько времени на пребразования, как у компилятора C++.
EP>>>>>Что мешает сразу генерировать оптимизированный IL?
G>>>>IL — высокоуровневый язык. Он и так достаточно оптимален на своем уровне.
EP>>>И что из этого? C# версия без ФВП тоже компилируется в тот же самый "высокоуровневый IL", но работает быстрее. Версия с ФВП могла бы давать точно такой же IL.
G>>Не могла бы, потому что делегаты.
EP>То есть таки язык мешает оптимизациям?
Нет, именно JIT. Это его задача определять, что нужно выкинуть делегат и заинлайнить вызов функции. Увы этого в JIT нету.

G>>>>Работает быстро за счет "hotspot". Большинство движков JS перекомпилируют код на основании профиля использования. Кроме того "работает быстро" — это когда не используются ФВП.

EP>>>Вот именно, в исходном коде на C++ были ФВП и замыкание, в результирующем JS они были выоптимизированы компилятором C++, так как это элементарная операция (никакого динамического полиморфизма) — именно поэтому и быстро.
G>>Ну так ты продолжаешь доказывать, что проблема в языке C#.
EP>Проблема в языке в том числе, за счёт повсеместного динамического полиморфизма и избыточных индерекций по памяти.
Да-да, повтори еще 5 раз.
Re[32]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 11.08.16 12:08
Оценка:
Здравствуйте, ·, Вы писали:

EP>>>>более того — для формально верифицированного кода они не нужны.

EP>>·>Для формально верифицированного их разве кто-то пишет?
EP>>Я имею в виду то, что после того как есть результат формальной верификации, можно их выключить и это никак не повлияют на корректность.
·>Если код формально верифицируется, то ассерты не нужны. Вообще. Смысл?

Был код с ассертами -> формально верифицировали его -> выключили ассерты. Это иллюстрация на тему:

EP>Отличительная черта assert'ов — в том что они могут быть опционально отключены, более того — для формально верифицированного кода они не нужны.


EP>>Более того, юнит-тест конкретного компонента может успешно пройти при наличии бага, или например двойного бага — то есть false positive. При этом внутренний assert мог поймать эти баги на этом же прогоне. То есть assert'ы это отличное дополнение unit-тестов.

·>А конкретнее? Если ассерт можешь написать, почему это же нельзя выразить тестом?

Например двойная ошибка в коде. Из-за первой ошибки перешёл в неправильное состояние, из-за второй перешёл из неправильного в состояние подобное правильному. И вроде бы тест случай проверил, но ошибку не выявил.
При этом assert может элементарно проверять состояние между ошибками. А вот соответствующий юнит-тест мог бы быть на порядки менее очевидным, если вообще возможным.

·>>>>>При хорошем покрытии тестами ценность ассертов падает до нуля.

EP>>>>Точно также как и ценность других defensive примочек, а-ля bounds checking
EP>>·>Не точно также же. В проде bounds checking валит исключения
EP>>Да какая разница если у тебя в оттестированном и корректном коде не будет этих исключений?
·>Потенциально будет — если что-то неожиданно поломается, например, кто-то неверно использует компонент или не так "быстренько баг пофиксили".

Так ты определись, либо у тебя "что-то неожиданно поломается", либо "При хорошем покрытии тестами ценность ассертов падает до нуля."

EP>>То есть ты определись — либо у тебя код оттестирован и defensive programming не нужен, либо не оттестирован и ты тестируешь его на своих пользователях

·>Оттестирован на требуемых спекой сценариях.

У тебя в "cпеке" описаны все сценарии, для всех компонент на всех уровнях?

EP>>Conditional

·>А оно правда надо? JIT прекрасно справляется и с тупым finalStaticBool=System.getProperty("DEBUG").....if(finalStaticBool) return.

Я не понимаю что ты хочешь сказать — то что в Java непосредственно этой фичи нет, но не всё так плохо и взамен будет работать какая-то другая техника?
Ну ОК, но как это к обсуждаемой теме относится? То что техника другая, это как-то отменяет факт опциональности ассертов?

EP>>·>При релизном использовании отключены.

EP>>Совсем необязательно — я их видел в коммерческом продукте имеющем сотни миллионов установок
·>Гы-гы. Ведь явно не от хорошей жизни, им тупо пришлось использовать ассерты не по назначению.

Без понятия — но проблемы в этом нет. Если нужен over-defenesive, то оставляй assert'ы и в release

EP>>>>В чём ты видишь отличие? Выход за пределы bounds это есть логическая ошибка, которой в корректном коде нет

EP>>·>Эта ошибка явно прописана в спеке языка
EP>>Да какая разница — это и есть логическая ошибка в твоём алгоритме.
·>Так она и сломает мой алгоритм, а не совершенно не относящийся к моему алгоритму код.

Программа не выполнила свою задачу, не пришла в обещанный postcondition, не зависимо от того что где поломалось.

EP>>>>·>По-моему излишнее усложнение. Собственно на основании чего пользователь будет принимать решение?

EP>>>>1. На основании того какое быстродействие его устраивает
EP>>·>Чем быстрее, тем лучше, очевидно.
EP>>Совсем не очевидно, ибо это не единственный критерий.
·>Т.е. это вообще не критерий, на выбор-то не влияет.

Что? Как раз таки влияет

EP>>>>2. На основании того насколько корректен его код (здесь речь идёт про библиотеку и пользовательский код, ассерты внутри библиотеки могут ловить ошибки в пользовательском коде).

EP>>·>Конечно, корректен, я что ламер некорректный код писать?
EP>>Тогда тебе и не нужен никакой defensive programming
·>Т.е. предлагаешь какие-то субъективные оценки, гадание на кофейной гуще использовать для принятия решения какие ассерты включать, а какие нет?

Да, субъективные оценки основанные в том числе на объективных данных — тебя что удивляет?
Такие оценки повсеместно используются в софтостроении, и лишь мизерный процент кода формально верифицируется.
Вычисление любого нетривиального свойства кода крупного проекта является алгоритмически неразрешимой задачей

EP>>·>А вообще для этого сценария придумали логи и кастомизируемые (в т.ч. в рантайм) уровни логгирования. Ассерты тут пихать не надо.

EP>>А причём тут логи? Если у тебя условие assert'а сфейлилось — то дальше всё может полететь в тартарары, и лучше всего пристрелить такую программу.
·>Так говорю же, использование ассертов не по назначению. Сфейлилось совсем — брось исключение, оно обработается как надо, а если сфейлилось, но не очень опасно, то пожалуйся в лог и продожи работу. Зачем куда-то лететь-то сразу?

Так assert это и есть жёсткий фейл, семантически не менее (а зачастую более) жёсткий чем обычные исключения.

·>В общем, подытожу. Ассерты нужны если:

·>1. Плохо дело с юнит-тестами. Ассерт куда угодно воткнуть легко и хоть какой-то эффект есть.

Ассерты полезны и когда плохо и когда хорошо с юнит-тестами. Работают и при юнит и при интеграционных тестах. Позволяют легко выявлять двойные ошибки и подобное. "Втыкаются" элементарно, и сразу по месту. Плюс служат дополнительной документацией (фактически проверяемой)

·>2. Плохо дело с логгированием. Нет нормального способа сообщать о каких-то непредвиденных ситуациях.


Это ты не понимаешь семантику assert'а. Assert это очень жёсткий фейл.

·>3. Плохо дело с обработкой ошибок. Проще грохнуть всё приложение, чем кинуть исключение или нормально обработать ошибочную ситуацию.

·>Т.е. получается что ассерт это такой индикатор code smells.

Нет, и тут не верно. Это уже семантически не assert, так как assert опционален.
А то о чём ты говоришь повсеместно используется в C коде, действительно из-за кривой обработки ошибок, и что характерно не опционально.

Assert это не просто "ошибочная ситуация" а-ля неверный пользовательский ввод и т.п., это БАГ в коде.
Re[3]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: a_g_99 США http://www.hooli.xyz/
Дата: 11.08.16 12:17
Оценка:
Здравствуйте, ZloeBablo, Вы писали:

ZB>тебе не кажется что в нетфликс набирают таких 10 человек. А микрософт сотнями... а то и тысячами... А так же надеюсь ты взял эти зарплаты из одного региона.


Тысячами. Но и гугл набирает тысячу в год а зарплаты у них по факту в 4 раза выше считая бонусы. И факт остается фактом — на данный момент си_шарп один из наиболее низкооплачиваемых и менеее востребованных скиллов в США.
А ответ почему в принципе очевиден
Re[32]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 11.08.16 12:34
Оценка:
Здравствуйте, gandjustas, Вы писали:

EP>>>>И всё же ты не понимаешь. Класс да, генерируется, да размер на стороне вызова известен, но вот внутри дженерика размер стёрт, даже после всех подстановок, в C++ же его размер внутри шаблона известен во время компиляции.

G>>>Какой размер внутри дженерика?
EP>>Размер структуры/класса.
G>А он тут при чем?

Оптимизации — позволяет передавать через регистры, хранить в классах по значению и т.д. и т.п.

G>>>Кто стер?

EP>>Программист, в том момент когда передал замыкание в функцию принимающую Func<...>. Для разных замыканий тип один и тот же — Func<...>
G>Ты хочешь сказать, что компилятор не знает как получить класс-замыкание функции-параметра? Это чушь полнейшая.

Это передёргивание. Я говорю что это сложнее, а не невозможно, и примеры выше это подтверждают.

EP>>>>Перечитай десять раз, посмотри примеры выше, обрати внимание на static_assert — если не дойдёт, то задавай конкретный вопрос.

G>>>Ты приведи пример на C#, который иллюстрирует то, что ты говоришь.
EP>>Я приведу на C++, а ты попробуй привести аналог на C# (хотя бы псевдокод):...
G>Прости, но это говно.

Говно это твоё поведение. Ты неадекватен, не умеешь нормально вести диалог без всяких фекалий.

G>В реальности auto foo(F f) не дает никакой информации о том какой должен быть F. Скорее у тебя будет вместо F тип std::function и появится та же самая косвенность.


Не надо фантазировать. В подавляющем большинстве кода с ФВП на C++ — никаких std::function.

G>Только компилятор C++ через инлайнинг эту косвенность уберет, а C# — нет. Не занимается он этим.


Сейчас не убирает — пример выше — так это сложнее

EP>>>>Именно мешает. Я смотрел генерируемый код C++ компиляторами — простые виртуальные вызовы инлайнятся, если же вставить динамическую аллокацию (при прочих равных), то инлайна не происходит.

G>>>Так то ограничение компилятора C++
EP>>Так ты же говоришь что код C#/.NET будет транслироваться в C++ — я показываю что только этого недостаточно.
G>А по моим замерам — достаточно.

По каким именно? Тестирование низкоуровнего кода? Так я наоборот говорю, что да — в таких случаях будет одинаковый уровень. Ты подними уровень хоть чуть-чуть.

G>>>принципиальных проблем инлайна с аллокациями нет.

EP>>Принципиальных нет, я говорю о том что это сложнее.
G>Нет, ты говорил что аллокации мешают инлайну.

И до сих пор говорю — мешают, это труднее — и что характерно выше есть пример именно на эту тему.

EP>>Точно также как нет и принципиальных проблем генерировать супер-оптимальный код из Python.

G>А вот это неправда. В динамическом языке есть принципиальная проблема генерировать супер-оптимальный код. Некоторые паттерны использования могут обломать любую оптимизацию.

Нет принципиальной проблемы использовать всю доступную информацию для генерации супер-оптимального кода. Если же какая-то информация не доступна на момент компиляции (например текст eval приходит по сети) — то в аналогичном случае и языки со статической типизацией ничем не помогут.

G>Оптимизировать вирутальные вызовы несложно. Но без мощного инлайна это бывает невозможно.


Это сложнее. Выше как раз пример на компиляторе с мощным инлайном.

EP>>Если же повысить уровень абстракции — сделать сортировку произвольных элементов, произвольных последовательностей, произвольным предикатом — так как выглядят реальные сортировки а-ля std::sort — то результат C++ не изменится, а вот C# во много раз просядет. Собственно мой тест с JS ровно это и продемонстрировал, и там даже абстракций было меньше чем у сортировки.

G>Ты std::sort называешь высокоуровневым кодом? Прости, смешно.

У него уровень абстракции намного выше чем в твоём тесте сортирующем конкретные int'ы, конкретным предикатом, в конкретном контейнере.

G>В реальности такой подход не работает. Ты не сможешь написать эффективную сортировку, которая работает и для массива, и для односвязного списка. По факту у тебя будет несколько специализаций под разные типы контейнеров.


Можно иметь по одной сортировке для каждой концепции — всех вариантов списков, для всех видов массивов и т.п. Если же брать алгоритмы типа std::find_if — то они будут одинаково хорошо работать и для списков, и для массивов и т.п.

Но даже не вдаваясь во все эти подробности — попробуй хотя бы предикат и тип элемента абстрагировать — сразу получишь penalty.
Re[4]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: ZloeBablo Германия  
Дата: 11.08.16 12:52
Оценка:
А можно пример какой то что зп в 4 раза выше в одном и том же регионе? А то я тоже могу показать в мюнхене и дрездене.
Re[31]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: chaotic-kotik  
Дата: 11.08.16 13:06
Оценка: +1
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Да, это преимущество. Но с другой стороны в юнит тестами намного проще перевести код в состояние всех edge-case'ов (в которых в том числе могут выстрелить assert'ы) по сравнению с интеграционными тестами.


В общем случае это недостижимо, так как количество edge-case-ов растет экспоненциально, по отношению к количеству ветвлений в программе. Тот кто занимался fuzz-тестированием меня поймет. Язык тут роли не играет и вообще ничего не решает.
Re[5]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: a_g_99 США http://www.hooli.xyz/
Дата: 11.08.16 13:09
Оценка:
Здравствуйте, ZloeBablo, Вы писали:

ZB>А можно пример какой то что зп в 4 раза выше в одном и том же регионе? А то я тоже могу показать в мюнхене и дрездене.


MS vs Amazon в Сиэттле — у последнего базовая ставка выше в 2.5 раза (про бонусы не знаю)
MS vs Fb в Сиэттле — разница в 3-4 раза в зависимости от позиции
Re[30]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 11.08.16 13:29
Оценка: -1 :)
Здравствуйте, gandjustas, Вы писали:

EP>>Хамство это конечно отличный, а главное конструктивный аргумент. Зачем думать, анализировать, спрашивать — когда можно просто нахамить — "не понимаю значит бред"

G>Ты пытаешься говорить умные слова, не понимая их смысл. Это и есть бред.

Если тебе что-то недоступно — ты не стесняйся, спрашивай, без проблем объясню.

G>>>В замыканиях нетполиморфизма

EP>>Не в самих замыканиях. Напиши пример ФВП которая принимает простейшее замыкание.
G>Там тоже нет полиморфизма.

Ты код напиши — это несколько строк — тогда разговор будет предметным. Второе сообщение уже увиливаешь

G>>>>>Что такое "динамический IEnumerable"?

EP>>>>Динамический полиморфизм для обхода последовательностей.
G>>>Пример кода покажи, не ясно о чем ты пишешь.
EP>>Вот.
G>И зачем его использовать в performance-critical коде?

О том и речь — он тормозит. А вот диапазоны C++ — нет

EP>>std::vector, std::deque, std::string — это всё random access последовательности. На них можно писать алгоритмы на итераторах, без abstraction penalty.

G>Неправда. Эффективный sort для vector будет отличаться от эффективного sort для deque.

В случае deque — да — для неё может быть более оптимальный алгоритм, но этот будет работать в том числе. ОК, допустим вычеркнем deque — всё равно исключительно в поставке C++ имеем встроенные массивы, std::vector, std::string, std::array.

G>Abstraction penality это не потому что компилятор не умеет девиртуализировать вызовы,


По этому в том числе.

G>а потому что детали абстрагируемого кода могут повлиять на быстродейсвтие.


Могут влиять, а могут и не влиять std::find_if работает одинаково хорошо как для массивов, так и для списков.

EP>>На C# IList даст приличную просадку. И это лишь один из примеров.

G>Просадку где?

В коде использующем его вместо конкретных контейнеров.

EP>>>>Собственно о том и речь — в C++ я могу накручивать уровни абстракций даже в performance-critical коде, без жёсткого penalty.

G>>>Это только если инлайнинг сработает.
EP>>И что характерно он работает, потому что язык к этому располагает. Потому что можно использовать ФВП, замыкания, и т.п. без всякого динамического полиморфизма.
G>Язык тут не при чем. 20 лет назад C++ был почти такой же, а инлайнинга почти не было. Странно, да?

Был, менее сильный чем сейчас, но тем не менее был: http://www.osl.iu.edu/download/research/mtl/papers/iscope_final.pdf

G>Ты путеашь теплое с мягким. Быстродействие С++ — следствие миллинов трудочасов, вложенных в компилятор, а не свойство языка.


Не путаю, C++ быстрый в том числе потому что его легко оптимизировать — очевидно что встраивание обычного вызова легче чем виртуального.

EP>>Я же говорил про IEnumerable.

G>Ты хоть проверял какой код генерируется? Может там тоже нет виртуальных вызовов, девиртуализация срабатывает.

Проверял, но в другом случае
Автор: Evgeny.Panasyuk
Дата: 20.06.15
.
Если же брать этот конкретный случай — то он тормозит восьмикратно по сравнению с ручной подстановкой конкретных типов.

G>>>C IEnumerable другая проблема, которая связана с ФВП. Вообще ФП в C# довольно медленно работает, не создавался язык под него.

EP>>О чём и речь
G>Проблема в компиляторе, вернее в JIT, а не в самом языке.

В языке в том числе.

EP>>Так в том-то и фишка что буду, because I can! Зачем мне делать его руками, для всех используемых комбинаций алгоритмов * замыканий * последовательностей * прочих абстракций, когда с этим прекрасно справляется компилятор?

G>Многие как раз делают иначе, постностью отказываясь от фич C++. Тот же v8.
G>Они чего-то не знают?

Я не знаю что там конкретно внутри v8, и на основе чего они принимали какие-то там решения.
Но есть реальные и публичные примеры, где абстракции используются в полный рост, при этом давая исключительную производительность.
Re[33]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: · Великобритания  
Дата: 11.08.16 13:46
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>>>>>более того — для формально верифицированного кода они не нужны.

EP>>>·>Для формально верифицированного их разве кто-то пишет?
EP>>>Я имею в виду то, что после того как есть результат формальной верификации, можно их выключить и это никак не повлияют на корректность.
EP>·>Если код формально верифицируется, то ассерты не нужны. Вообще. Смысл?
EP>Был код с ассертами -> формально верифицировали его -> выключили ассерты. Это иллюстрация на тему:
Если код формально верифицирован — ассерты можно тупо удалить. Формальная верификация — сильная, но дорогая техника доказательства корректности кода, которая полностью заменяет ЮТ и ассерты.

EP>>>Более того, юнит-тест конкретного компонента может успешно пройти при наличии бага, или например двойного бага — то есть false positive. При этом внутренний assert мог поймать эти баги на этом же прогоне. То есть assert'ы это отличное дополнение unit-тестов.

EP>·>А конкретнее? Если ассерт можешь написать, почему это же нельзя выразить тестом?
EP>Например двойная ошибка в коде. Из-за первой ошибки перешёл в неправильное состояние, из-за второй перешёл из неправильного в состояние подобное правильному. И вроде бы тест случай проверил, но ошибку не выявил.
EP>При этом assert может элементарно проверять состояние между ошибками. А вот соответствующий юнит-тест мог бы быть на порядки менее очевидным, если вообще возможным.
Если ты вдруг полагаешь, что где-то может быть ошибочное состояние (т.е. хочешь написать там ассерт), то
либо воспроизведи это состояние тестом, т.е. ассерт не нужен;
либо почеши голову и убедись, что это состояние невозможно, т.е. ассерт не нужен.

EP>>>То есть ты определись — либо у тебя код оттестирован и defensive programming не нужен, либо не оттестирован и ты тестируешь его на своих пользователях

EP>·>Оттестирован на требуемых спекой сценариях.
EP>У тебя в "cпеке" описаны все сценарии, для всех компонент на всех уровнях?
Зачем на всех уровнях? Ошибка на уровне юнитов будет падать сразу с каким-нибудь bounds checking и видна немедленно и везде. В отличие от ассертов, которые в отключенном состоянии вызовут неопределённое поведение.
А высокоуровневые сценарии должны проходить, да.

EP>>>·>При релизном использовании отключены.

EP>>>Совсем необязательно — я их видел в коммерческом продукте имеющем сотни миллионов установок
EP>·>Гы-гы. Ведь явно не от хорошей жизни, им тупо пришлось использовать ассерты не по назначению.
EP>Без понятия — но проблемы в этом нет. Если нужен over-defenesive, то оставляй assert'ы и в release
Это не имеет смысла, используют инструмент не по назначению. Это уже тогда не ассерты, а обычные проверки.

EP>>>·>Эта ошибка явно прописана в спеке языка

EP>>>Да какая разница — это и есть логическая ошибка в твоём алгоритме.
EP>·>Так она и сломает мой алгоритм, а не совершенно не относящийся к моему алгоритму код.
EP>Программа не выполнила свою задачу, не пришла в обещанный postcondition, не зависимо от того что где поломалось.
Собственно в этом и проблема, что ты говоришь "программа", т.е. весь процесс. Хотя ошибка только в моём алгоритме. Плохо, когда локальная проблема внезапно становится глобальной. Именно за это не любят глобальные переменные, именно поэтому изобрели всякие защищённые режимы и т.п.

EP>>>·>Конечно, корректен, я что ламер некорректный код писать?

EP>>>Тогда тебе и не нужен никакой defensive programming
EP>·>Т.е. предлагаешь какие-то субъективные оценки, гадание на кофейной гуще использовать для принятия решения какие ассерты включать, а какие нет?
EP>Да, субъективные оценки основанные в том числе на объективных данных — тебя что удивляет?
EP>Такие оценки повсеместно используются в софтостроении, и лишь мизерный процент кода формально верифицируется.
EP>Вычисление любого нетривиального свойства кода крупного проекта является алгоритмически неразрешимой задачей
Т.е. придумали себе сложность и героически её решаем.

EP>·>Так говорю же, использование ассертов не по назначению. Сфейлилось совсем — брось исключение, оно обработается как надо, а если сфейлилось, но не очень опасно, то пожалуйся в лог и продожи работу. Зачем куда-то лететь-то сразу?

EP>Так assert это и есть жёсткий фейл, семантически не менее (а зачастую более) жёсткий чем обычные исключения.
"Опциональный жесткий фейл". Это не звучит для тебя как оксюморон?

EP>·>В общем, подытожу. Ассерты нужны если:

EP>·>1. Плохо дело с юнит-тестами. Ассерт куда угодно воткнуть легко и хоть какой-то эффект есть.
EP>Ассерты полезны и когда плохо и когда хорошо с юнит-тестами. Работают и при юнит и при интеграционных тестах. Позволяют легко выявлять двойные ошибки и подобное. "Втыкаются" элементарно, и сразу по месту. Плюс служат дополнительной документацией (фактически проверяемой)
Вот и воткни ЮТ. Почему обязательно ассерт?

EP>·>2. Плохо дело с логгированием. Нет нормального способа сообщать о каких-то непредвиденных ситуациях.

EP>Это ты не понимаешь семантику assert'а. Assert это очень жёсткий фейл.
Настолько жесткий, что его можно игнорировать в проде. Ха-ха.

EP>·>3. Плохо дело с обработкой ошибок. Проще грохнуть всё приложение, чем кинуть исключение или нормально обработать ошибочную ситуацию.

EP>·>Т.е. получается что ассерт это такой индикатор code smells.
EP>Нет, и тут не верно. Это уже семантически не assert, так как assert опционален.
EP>А то о чём ты говоришь повсеместно используется в C коде, действительно из-за кривой обработки ошибок, и что характерно не опционально.
EP>Assert это не просто "ошибочная ситуация" а-ля неверный пользовательский ввод и т.п., это БАГ в коде.
Который нужно чинить, а не просто игнорировать.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Негодяй  
Дата: 12.08.16 14:28
Оценка:
Здравствуйте, Arsen.Shnurkov, Вы писали:

AS>Собственно, сборка мусора в Rust есть (опционально), а такого мощного статического анализатора в C# нет.


Я маминой мамы маму Раста на твоей спине ....л
Re[32]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 15.08.16 16:24
Оценка:
Здравствуйте, chaotic-kotik, Вы писали:

EP>>Да, это преимущество. Но с другой стороны в юнит тестами намного проще перевести код в состояние всех edge-case'ов (в которых в том числе могут выстрелить assert'ы) по сравнению с интеграционными тестами.

CK>В общем случае это недостижимо так как количество edge-case-ов растет экспоненциально, по отношению к количеству ветвлений в программе.

Во-первых необязательно экспоненциально, есть простейшие контр-примеры. Во-вторых количество edge-case'ов зависит далеко не только от ветвлений — их может и вовсе не быть, а edge-case'ов много.
В-третьих речь идёт не про всю программу, а про юнит тесты, которые тестируют отдельные модули — в которых пусть и не всегда, но всё же представляется возможность протестировать все edge-case'ы (а в простых случаях и вовсе все case'ы)

CK>Язык тут роли не играет и вообще ничего не решает.


Да, об этом и речь — в частности assert'ы является общеязыковой техникой.
Re[34]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 15.08.16 17:25
Оценка:
Здравствуйте, ·, Вы писали:

EP>>·>Если код формально верифицируется, то ассерты не нужны. Вообще. Смысл?

EP>>Был код с ассертами -> формально верифицировали его -> выключили ассерты. Это иллюстрация на тему:
·>Если код формально верифицирован — ассерты можно тупо удалить. Формальная верификация — сильная, но дорогая техника доказательства корректности кода, которая полностью заменяет ЮТ и ассерты.

Да, после верификации ассерты можно хоть удалить. Я этот пример привёл именно в качестве иллюстрации на тему опциональности assert'ов

EP>>При этом assert может элементарно проверять состояние между ошибками. А вот соответствующий юнит-тест мог бы быть на порядки менее очевидным, если вообще возможным.

·>Если ты вдруг полагаешь, что где-то может быть ошибочное состояние (т.е. хочешь написать там ассерт), то
·>либо воспроизведи это состояние тестом, т.е. ассерт не нужен;

Протестировать внутреннее состояние далеко не всегда легко из вне. Assert же даёт самое ранее обнаружение, при этом крайне дешёв чтобы от него отказываться.
Думаешь все твои тесты делают ненужными написанные ассерты? ОК — в чём проблема их оставить? Когда-нибудь ты, или кто-то другой ошибётся и assert таки выстрелит.

·>либо почеши голову и убедись, что это состояние невозможно, т.е. ассерт не нужен.


assert помимо всего прочего может ловить нарушения preconditions, а конкретнее выстреливать во время интеграции компонентов. Ты не можешь "почесать голову" и убедится в том, что все компоненты (которых ты ещё даже не видел) обязательно будут удовлетворят предусловиям.
Более того, если например ты используешь чужой алгоритм с ассертами на предусловия — то ты фактически получаешь эти все проверки бесплатно.

EP>>>>То есть ты определись — либо у тебя код оттестирован и defensive programming не нужен, либо не оттестирован и ты тестируешь его на своих пользователях

EP>>·>Оттестирован на требуемых спекой сценариях.
EP>>У тебя в "cпеке" описаны все сценарии, для всех компонент на всех уровнях?
·>Зачем на всех уровнях? Ошибка на уровне юнитов будет падать сразу с каким-нибудь bounds checking и видна немедленно и везде.

bounds checking это лишь мизерная часть проверки ошибочных состояний, ассерты используются далеко не только для bounds checking.

EP>>>>·>При релизном использовании отключены.

EP>>>>Совсем необязательно — я их видел в коммерческом продукте имеющем сотни миллионов установок
EP>>·>Гы-гы. Ведь явно не от хорошей жизни, им тупо пришлось использовать ассерты не по назначению.
EP>>Без понятия — но проблемы в этом нет. Если нужен over-defenesive, то оставляй assert'ы и в release
·>Это не имеет смысла, используют инструмент не по назначению. Это уже тогда не ассерты, а обычные проверки.

Ассерты в первую очередь нацелены на поимку багов — нарушение инвариантов, вариантов, пред/пост-условий.
У них семантика другая нежели чем у обычных проверок. Обычные проверки нельзя выкинуть даже из формально верифицированного кода.

·>Т.е. придумали себе сложность и героически её решаем.


Это уже твои домыслы что выбор между включением/выключением ассертов это какая-то непомерная сложность требующая героического решения.

·>"Опциональный жесткий фейл". Это не звучит для тебя как оксюморон?


Нет. Нарушение условия ассерта это жёсткий фейл, баг в программе. Точно также как и нарушение любого пред/пост-условия вокруг каждого выражения (а-ля Hoare Triple).
При этом несмотря на то что это жёсткие фейлы, в релизной версии нет даже и малой части всех этих проверок, а некоторые и вовсе неразрешимы. Вот у тебя есть проверки пред/пост-условия вокруг каждого выражения?

EP>>Ассерты полезны и когда плохо и когда хорошо с юнит-тестами. Работают и при юнит и при интеграционных тестах. Позволяют легко выявлять двойные ошибки и подобное. "Втыкаются" элементарно, и сразу по месту. Плюс служат дополнительной документацией (фактически проверяемой)

·>Вот и воткни ЮТ. Почему обязательно ассерт?

Перечитай ещё раз то, на что ответил — например про то что ассерты работают и при интеграционных тестах.
Re[35]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Ночной Смотрящий Россия  
Дата: 15.08.16 17:29
Оценка: +1 :)
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP> bounds checking это лишь мизерная часть проверки ошибочных состояний, ассерты используются далеко не только для bounds checking.


95% ассертов в тех проектах, которые я хорошо знаю — проверка на null и строк на пустое значение. Это частный случай bounds checking.
Re[36]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 15.08.16 17:52
Оценка: :))
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>95% ассертов в тех проектах, которые я хорошо знаю — проверка на null и строк на пустое значение.


На каком языке?
95% от чего? Запускаемых проверок в рантайме, или от всех проверок выраженных в коде? Если второе, то непонятно зачем их копипастить вместо того чтобы сделать многократно используемый тип а-ля not_null<T>, у которого внутри будет assert.
Re[35]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: · Великобритания  
Дата: 16.08.16 06:49
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>·>Если код формально верифицирован — ассерты можно тупо удалить. Формальная верификация — сильная, но дорогая техника доказательства корректности кода, которая полностью заменяет ЮТ и ассерты.

EP>Да, после верификации ассерты можно хоть удалить. Я этот пример привёл именно в качестве иллюстрации на тему опциональности assert'ов
А так же на тему ненужности assert'ов

EP>·>Если ты вдруг полагаешь, что где-то может быть ошибочное состояние (т.е. хочешь написать там ассерт), то

EP>·>либо воспроизведи это состояние тестом, т.е. ассерт не нужен;
EP>Протестировать внутреннее состояние далеко не всегда легко из вне. Assert же даёт самое ранее обнаружение, при этом крайне дешёв чтобы от него отказываться.
EP>Думаешь все твои тесты делают ненужными написанные ассерты? ОК — в чём проблема их оставить? Когда-нибудь ты, или кто-то другой ошибётся и assert таки выстрелит.
Проблема в том, что их не надо писать. Ассерт это такой индикатор лажи, когда программист поленился либо написать тест, либо продумать корректное поведение в ошибочной ситуации.

EP>·>либо почеши голову и убедись, что это состояние невозможно, т.е. ассерт не нужен.

EP>assert помимо всего прочего может ловить нарушения preconditions, а конкретнее выстреливать во время интеграции компонентов. Ты не можешь "почесать голову" и убедится в том, что все компоненты (которых ты ещё даже не видел) обязательно будут удовлетворят предусловиям.
EP>Более того, если например ты используешь чужой алгоритм с ассертами на предусловия — то ты фактически получаешь эти все проверки бесплатно.
Для этого есть более хорошие средства — явно кидаться ошибками, писать логи, или просто продолжить корректно работать.

EP>>>·>Оттестирован на требуемых спекой сценариях.

EP>>>У тебя в "cпеке" описаны все сценарии, для всех компонент на всех уровнях?
EP>·>Зачем на всех уровнях? Ошибка на уровне юнитов будет падать сразу с каким-нибудь bounds checking и видна немедленно и везде.
EP> bounds checking это лишь мизерная часть проверки ошибочных состояний, ассерты используются далеко не только для bounds checking.
Для чего ещё? Ну там null-checks, валидность параметров и т.п. Может какая-то доля процента и будет чем-то интересным, но её лучше тогда явно протестировать.

EP>>>·>Гы-гы. Ведь явно не от хорошей жизни, им тупо пришлось использовать ассерты не по назначению.

EP>>>Без понятия — но проблемы в этом нет. Если нужен over-defenesive, то оставляй assert'ы и в release
EP>·>Это не имеет смысла, используют инструмент не по назначению. Это уже тогда не ассерты, а обычные проверки.
EP>Ассерты в первую очередь нацелены на поимку багов — нарушение инвариантов, вариантов, пред/пост-условий.
EP>У них семантика другая нежели чем у обычных проверок. Обычные проверки нельзя выкинуть даже из формально верифицированного кода.
Неотключённые ассерты в релизе по сути и есть эти сами обычные проверки. Т.е. были ассерты, а семантику поменяли.

EP>·>"Опциональный жесткий фейл". Это не звучит для тебя как оксюморон?

EP>Нет. Нарушение условия ассерта это жёсткий фейл, баг в программе. Точно также как и нарушение любого пред/пост-условия вокруг каждого выражения (а-ля Hoare Triple).
EP>При этом несмотря на то что это жёсткие фейлы, в релизной версии нет даже и малой части всех этих проверок, а некоторые и вовсе неразрешимы.
Если неразрешимы — они значит не нужны. Если разрешимы — то они должны фейлить и релиз.

EP>Вот у тебя есть проверки пред/пост-условия вокруг каждого выражения?

Нет. А у тебя ассерты есть вокруг каждого выражения?

EP>Перечитай ещё раз то, на что ответил — например про то что ассерты работают и при интеграционных тестах.

И что? Интеграционные тесты как правило тестируют сильно меньше, чем юнит. И ещё меньше, чем возможно в релизе. Почему вдруг интеграционные тесты стали важнее релиза?
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[36]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 16.08.16 14:27
Оценка: +1
Здравствуйте, ·, Вы писали:

EP>>Перечитай ещё раз то, на что ответил — например про то что ассерты работают и при интеграционных тестах.

·>И что? Интеграционные тесты как правило тестируют сильно меньше, чем юнит. И ещё меньше, чем возможно в релизе. Почему вдруг интеграционные тесты стали важнее релиза?

"Меньше" в чем померяно? На практике интеграционные тестируют "больше" если мерить так — количество сценариев * частоту использования сценария / количество добавленных строк.

Юнит-тесты, несмотря на большое покрытие, обычно бесполезны для отлавливания ошибок на границах модулей. Кроме того большое количество UT затрудняет рефакторинг классов — много тестов ломаются, приходится править.
Re[37]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: · Великобритания  
Дата: 16.08.16 14:35
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>·>И что? Интеграционные тесты как правило тестируют сильно меньше, чем юнит. И ещё меньше, чем возможно в релизе. Почему вдруг интеграционные тесты стали важнее релиза?

G>"Меньше" в чем померяно? На практике интеграционные тестируют "больше" если мерить так — количество сценариев * частоту использования сценария / количество добавленных строк.
Это в хорошей практике. А если брать среднее по больнице... с учётом того, что большинство тесты вообще не пишет...

Кстати, вопрос. Если все тесты проходят, но ассерт падает — значит ли это что ассерт валидный?

G>Юнит-тесты, несмотря на большое покрытие, обычно бесполезны для отлавливания ошибок на границах модулей. Кроме того большое количество UT затрудняет рефакторинг классов — много тестов ломаются, приходится править.

В сравнении с ассертами как оно? Ассерты тоже начинают ломаться внезапно.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[38]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 16.08.16 15:02
Оценка: +1
Здравствуйте, ·, Вы писали:

·>Здравствуйте, gandjustas, Вы писали:


G>>·>И что? Интеграционные тесты как правило тестируют сильно меньше, чем юнит. И ещё меньше, чем возможно в релизе. Почему вдруг интеграционные тесты стали важнее релиза?

G>>"Меньше" в чем померяно? На практике интеграционные тестируют "больше" если мерить так — количество сценариев * частоту использования сценария / количество добавленных строк.
·>Это в хорошей практике. А если брать среднее по больнице... с учётом того, что большинство тесты вообще не пишет...
Ну и пусть не пишут, может проще проверять код другими способами. Эффективность это польза/затраты, затраты на тесты довольно высоки, по сравнению с другими способами.


·>Кстати, вопрос. Если все тесты проходят, но ассерт падает — значит ли это что ассерт валидный?

Каким образом проходят тесты при падающем ассерте? Ассерт падает только в продакшене?

G>>Юнит-тесты, несмотря на большое покрытие, обычно бесполезны для отлавливания ошибок на границах модулей. Кроме того большое количество UT затрудняет рефакторинг классов — много тестов ломаются, приходится править.

·>В сравнении с ассертами как оно? Ассерты тоже начинают ломаться внезапно.
С ассертами гораздо проще — они часть кода, который рефактортся.
Ну и правильные ассерты должны инварианты алгоритмов проверять, а инварианты при рефакторинге не меняются.
Re[39]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: · Великобритания  
Дата: 16.08.16 15:07
Оценка: -1
Здравствуйте, gandjustas, Вы писали:

G>>>"Меньше" в чем померяно? На практике интеграционные тестируют "больше" если мерить так — количество сценариев * частоту использования сценария / количество добавленных строк.

G>·>Это в хорошей практике. А если брать среднее по больнице... с учётом того, что большинство тесты вообще не пишет...
G>Ну и пусть не пишут, может проще проверять код другими способами. Эффективность это польза/затраты, затраты на тесты довольно высоки, по сравнению с другими способами.
Вручную, как же ещё.

G>·>Кстати, вопрос. Если все тесты проходят, но ассерт падает — значит ли это что ассерт валидный?

G>Каким образом проходят тесты при падающем ассерте? Ассерт падает только в продакшене?
Допустим, что ассерты отключены (не валят процесс), но условие не соблюдается.

G>>>Юнит-тесты, несмотря на большое покрытие, обычно бесполезны для отлавливания ошибок на границах модулей. Кроме того большое количество UT затрудняет рефакторинг классов — много тестов ломаются, приходится править.

G>·>В сравнении с ассертами как оно? Ассерты тоже начинают ломаться внезапно.
G>С ассертами гораздо проще — они часть кода, который рефактортся.
G>Ну и правильные ассерты должны инварианты алгоритмов проверять, а инварианты при рефакторинге не меняются.
Правильные тесты — тоже.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Отредактировано 16.08.2016 15:09 · . Предыдущая версия . Еще …
Отредактировано 16.08.2016 15:08 · . Предыдущая версия .
Re[36]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 16.08.16 15:41
Оценка:
Здравствуйте, ·, Вы писали:

EP>>·>Если код формально верифицирован — ассерты можно тупо удалить. Формальная верификация — сильная, но дорогая техника доказательства корректности кода, которая полностью заменяет ЮТ и ассерты.

EP>>Да, после верификации ассерты можно хоть удалить. Я этот пример привёл именно в качестве иллюстрации на тему опциональности assert'ов
·>А так же на тему ненужности assert'ов

Это ты уже не знаешь к чему придраться. Иллюстрация была на тему опциональности, а не ненужности.
Если следовать твоим же рассуждениям о ненужности — то и bound checks не нужны, как и прочий defensive, ибо можно использовать формальную верификацию

EP>>Протестировать внутреннее состояние далеко не всегда легко из вне. Assert же даёт самое ранее обнаружение, при этом крайне дешёв чтобы от него отказываться.

EP>>Думаешь все твои тесты делают ненужными написанные ассерты? ОК — в чём проблема их оставить? Когда-нибудь ты, или кто-то другой ошибётся и assert таки выстрелит.
·>Проблема в том, что их не надо писать. Ассерт это такой индикатор лажи, когда программист поленился либо написать тест,

Это твои фантазии — я например использую ассерты одновременно с тестами.

·>либо продумать корректное поведение в ошибочной ситуации.


Предлагаешь продумывать поведение для каждого возможного поломанного инварианта?

·>или просто продолжить корректно работать.


Не получится — у тебя код пришёл в состояние в которое не должен был прийти по логике вещей — каким образом он в него пришёл ты не знаешь, глобальное состояние тоже не известно, а точнее может содержать неизвестно какие ошибки.

EP>>>>·>Оттестирован на требуемых спекой сценариях.

EP>>>>У тебя в "cпеке" описаны все сценарии, для всех компонент на всех уровнях?
EP>>·>Зачем на всех уровнях? Ошибка на уровне юнитов будет падать сразу с каким-нибудь bounds checking и видна немедленно и везде.
EP>> bounds checking это лишь мизерная часть проверки ошибочных состояний, ассерты используются далеко не только для bounds checking.
·>Для чего ещё?

Например инварианты класса. Классы (с private полями) это не просто группировка полей а-ля структуры (либо эмуляция структур через getters&setters) — это ещё и дополнительные инварианты наложенные на эти private поля.

·>Ну там null-checks


На C++ null-checks прячутся во внутрь небольшого набора классов, и раскидывать их по коду нет никакой необходимости.

·>валидность параметров


Для этого в том числе.

·>Может какая-то доля процента и будет чем-то интересным, но её лучше тогда явно протестировать.


Ассерты используются вместе с тестами, а не вместо них.

EP>>У них семантика другая нежели чем у обычных проверок. Обычные проверки нельзя выкинуть даже из формально верифицированного кода.

·>Неотключённые ассерты в релизе по сути и есть эти сами обычные проверки. Т.е. были ассерты, а семантику поменяли.

Нет, так как после формальной верификации (либо например через несколько релизов без выстреливания assert'ов) их можно отключить, в то время как проверки не являются опциональными.

EP>>·>"Опциональный жесткий фейл". Это не звучит для тебя как оксюморон?

EP>>Нет. Нарушение условия ассерта это жёсткий фейл, баг в программе. Точно также как и нарушение любого пред/пост-условия вокруг каждого выражения (а-ля Hoare Triple).
EP>>При этом несмотря на то что это жёсткие фейлы, в релизной версии нет даже и малой части всех этих проверок, а некоторые и вовсе неразрешимы.
·>Если неразрешимы — они значит не нужны.
·>Если разрешимы — то они должны фейлить и релиз.

Нет, неразрешимы означает что неразрешимы. Нужность/ненужность тут ортогонально — смотри например halting probelm

EP>>Вот у тебя есть проверки пред/пост-условия вокруг каждого выражения?

·>Нет. А у тебя ассерты есть вокруг каждого выражения?

Нет, при этом это всё жёсткие фейлы.
Жёсткие в том смысле что говорят о серьёзном баге, а не о том что кто-то умрёт.

EP>>Перечитай ещё раз то, на что ответил — например про то что ассерты работают и при интеграционных тестах.

·>И что? Интеграционные тесты как правило тестируют сильно меньше, чем юнит. И ещё меньше, чем возможно в релизе. Почему вдруг интеграционные тесты стали важнее релиза?

Что значит важнее релиза? Я интеграционным тестированием называю в том числе и тестирование всего вместе.
В любом случае, даже если использовать другую терминологию и выделять ещё и системное тестирование — то мой поинт всё равно остаётся в силе — assert'ы отрабатывают на всех этапах тестирования.
Re[37]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: · Великобритания  
Дата: 16.08.16 16:03
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>·>А так же на тему ненужности assert'ов

EP>Это ты уже не знаешь к чему придраться. Иллюстрация была на тему опциональности, а не ненужности.
EP>Если следовать твоим же рассуждениям о ненужности — то и bound checks не нужны, как и прочий defensive, ибо можно использовать формальную верификацию
Я просто не понял зачем ты это доказываешь. Тем более таким образом. Опциональность ассертов, точнее их отключение в release — это by design.

EP>>>Думаешь все твои тесты делают ненужными написанные ассерты? ОК — в чём проблема их оставить? Когда-нибудь ты, или кто-то другой ошибётся и assert таки выстрелит.

EP>·>Проблема в том, что их не надо писать. Ассерт это такой индикатор лажи, когда программист поленился либо написать тест,
EP>Это твои фантазии — я например использую ассерты одновременно с тестами.
Вредная привычка...

EP>·>либо продумать корректное поведение в ошибочной ситуации.

EP>Предлагаешь продумывать поведение для каждого возможного поломанного инварианта?
Да. Или лучше — не допускать ломание инвариантов.
А что по-твоему оно будет делать в релизе?

EP>·>или просто продолжить корректно работать.

EP>Не получится — у тебя код пришёл в состояние в которое не должен был прийти по логике вещей — каким образом он в него пришёл ты не знаешь, глобальное состояние тоже не известно, а точнее может содержать неизвестно какие ошибки.
Значит кинь исключение, сбрось дамп состояния в лог, етс.

EP>>>·>Зачем на всех уровнях? Ошибка на уровне юнитов будет падать сразу с каким-нибудь bounds checking и видна немедленно и везде.

EP>>> bounds checking это лишь мизерная часть проверки ошибочных состояний, ассерты используются далеко не только для bounds checking.
EP>·>Для чего ещё?
EP>Например инварианты класса. Классы (с private полями) это не просто группировка полей а-ля структуры (либо эмуляция структур через getters&setters) — это ещё и дополнительные инварианты наложенные на эти private поля.
Т.е. косяки дизайна в алгоритме затыкаются ассертами.

EP>·>Ну там null-checks

EP>На C++ null-checks прячутся во внутрь небольшого набора классов, и раскидывать их по коду нет никакой необходимости.
EP>·>валидность параметров
EP>Для этого в том числе.
Так что остаётся-то? Примеры можно? Так что тестами ну никак не покрывается?

EP>·>Может какая-то доля процента и будет чем-то интересным, но её лучше тогда явно протестировать.

EP>Ассерты используются вместе с тестами, а не вместо них.
Я не говорю, что их невозможно использовать. Я говорю, что их не следует использовать, лучше заменять на что-то более надёжное: лучший дизайн алгоритмов, не допускающий всякую НЁХ, более качественное покрытие тестами и более качественную диагностику.

EP>>>У них семантика другая нежели чем у обычных проверок. Обычные проверки нельзя выкинуть даже из формально верифицированного кода.

EP>·>Неотключённые ассерты в релизе по сути и есть эти сами обычные проверки. Т.е. были ассерты, а семантику поменяли.
EP>Нет, так как после формальной верификации (либо например через несколько релизов без выстреливания assert'ов) их можно отключить, в то время как проверки не являются опциональными.
Ээээээ.. Ты что под формальной верификацией понимаешь?

EP>>>Нет. Нарушение условия ассерта это жёсткий фейл, баг в программе. Точно также как и нарушение любого пред/пост-условия вокруг каждого выражения (а-ля Hoare Triple).

EP>>>При этом несмотря на то что это жёсткие фейлы, в релизной версии нет даже и малой части всех этих проверок, а некоторые и вовсе неразрешимы.
EP>·>Если неразрешимы — они значит не нужны.
EP>·>Если разрешимы — то они должны фейлить и релиз.
EP>Нет, неразрешимы означает что неразрешимы. Нужность/ненужность тут ортогонально — смотри например halting probelm
halting problem это построение универсального алгоритма. Причём тут это? Программист обычно может чуть больше. По крайней мере в случае, когда хочет написать ассерт.

EP>>>Вот у тебя есть проверки пред/пост-условия вокруг каждого выражения?

EP>·>Нет. А у тебя ассерты есть вокруг каждого выражения?
EP>Нет, при этом это всё жёсткие фейлы.
EP>Жёсткие в том смысле что говорят о серьёзном баге, а не о том что кто-то умрёт.
Т.е. ты считаешь, что наличие серьёзного бага должно игнорироваться в проде?

EP>>>Перечитай ещё раз то, на что ответил — например про то что ассерты работают и при интеграционных тестах.

EP>·>И что? Интеграционные тесты как правило тестируют сильно меньше, чем юнит. И ещё меньше, чем возможно в релизе. Почему вдруг интеграционные тесты стали важнее релиза?
EP>Что значит важнее релиза? Я интеграционным тестированием называю в том числе и тестирование всего вместе.
EP>В любом случае, даже если использовать другую терминологию и выделять ещё и системное тестирование — то мой поинт всё равно остаётся в силе — assert'ы отрабатывают на всех этапах тестирования.
Но почему не в релизе-то?
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[38]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 16.08.16 18:03
Оценка:
Здравствуйте, ·, Вы писали:

·>Я просто не понял зачем ты это доказываешь. Тем более таким образом. Опциональность ассертов, точнее их отключение в release — это by design.


Показываю опциональность, для того чтобы было видно семантическое отличие от обычных проверок. Таким образом — потому что самая красноречивая демонстрация того, что для корректного кода они не нужны.

EP>>·>Проблема в том, что их не надо писать. Ассерт это такой индикатор лажи, когда программист поленился либо написать тест,

EP>>Это твои фантазии — я например использую ассерты одновременно с тестами.
·>Вредная привычка...

Почему? Потому что ты не используешь?
Даже если ты не веришь в то что они помогают в отлове багов, то всё равно остаётся аспект документирования пред/пост-условий и т.п. Причём это не просто текстовый комментарий, а реально выполняемая проверка, пусть даже только при тестировании.
При этом втыкаются непосредственно во время кодирования, не переключая контекст. И являются крайне дешёвыми.

EP>>·>либо продумать корректное поведение в ошибочной ситуации.

EP>>Предлагаешь продумывать поведение для каждого возможного поломанного инварианта?
·>Да. Или лучше — не допускать ломание инвариантов.

Ага, за всё хорошее и против всего плохого.
Если у тебя инварианты и т.п. не ломаются, то непонятно зачем ты восхваляешь всякие defensive штуки типа range check?

·>А что по-твоему оно будет делать в релизе?


Кто оно? Баги?

EP>>·>или просто продолжить корректно работать.

EP>>Не получится — у тебя код пришёл в состояние в которое не должен был прийти по логике вещей — каким образом он в него пришёл ты не знаешь, глобальное состояние тоже не известно, а точнее может содержать неизвестно какие ошибки.
·>Значит кинь исключение, сбрось дамп состояния в лог, етс.

Это же не "продолжить корректно работать" — ты не локализовал и не устранил причину, а лишь пытаешься собрать данные для последующего разбирательства и хоть как-то восстановиться.

EP>>·>Для чего ещё?

EP>>Например инварианты класса. Классы (с private полями) это не просто группировка полей а-ля структуры (либо эмуляция структур через getters&setters) — это ещё и дополнительные инварианты наложенные на эти private поля.
·>Т.е. косяки дизайна в алгоритме затыкаются ассертами.

Шта? Как ты пришёл к этому выводу? Я говорю про инварианты классов, и они таки существуют.

EP>>·>Может какая-то доля процента и будет чем-то интересным, но её лучше тогда явно протестировать.

EP>>Ассерты используются вместе с тестами, а не вместо них.
·>Я не говорю, что их невозможно использовать. Я говорю, что их не следует использовать, лучше заменять на что-то более надёжное: лучший дизайн алгоритмов, не допускающий всякую НЁХ, более качественное покрытие тестами и более качественную диагностику.

Ты так и не объяснил почему их не следует использовать, учитывая их минимальную цену. Пока всё сводится к "я их не использую, значит их не следует использовать".
И непонятно причём тут "лучший дизайн алгоритмов" — речи о том чтобы делать плохие алгоритмы не было. При этом "лучший дизайн алгоритмов" не избавляет от необходимости их тестирования, одним из аспектов которого являются в том числе assert'ы.

EP>>>>У них семантика другая нежели чем у обычных проверок. Обычные проверки нельзя выкинуть даже из формально верифицированного кода.

EP>>·>Неотключённые ассерты в релизе по сути и есть эти сами обычные проверки. Т.е. были ассерты, а семантику поменяли.
EP>>Нет, так как после формальной верификации (либо например через несколько релизов без выстреливания assert'ов) их можно отключить, в то время как проверки не являются опциональными.
·>Ээээээ.. Ты что под формальной верификацией понимаешь?

Доказывание свойств алгоритмов на формальном языке с автоматической проверкой правильности применения правил вывода и т.п.

EP>>>>Нет. Нарушение условия ассерта это жёсткий фейл, баг в программе. Точно также как и нарушение любого пред/пост-условия вокруг каждого выражения (а-ля Hoare Triple).

EP>>>>При этом несмотря на то что это жёсткие фейлы, в релизной версии нет даже и малой части всех этих проверок, а некоторые и вовсе неразрешимы.
EP>>·>Если неразрешимы — они значит не нужны.
EP>>·>Если разрешимы — то они должны фейлить и релиз.
EP>>Нет, неразрешимы означает что неразрешимы. Нужность/ненужность тут ортогонально — смотри например halting probelm
·>halting problem это построение универсального алгоритма. Причём тут это? Программист обычно может чуть больше. По крайней мере в случае, когда хочет написать ассерт.

Смотри выделенное — проверка далеко не каждого пред/пост-условия является разрешимой задачей.

EP>>>>Вот у тебя есть проверки пред/пост-условия вокруг каждого выражения?

EP>>·>Нет. А у тебя ассерты есть вокруг каждого выражения?
EP>>Нет, при этом это всё жёсткие фейлы.
EP>>Жёсткие в том смысле что говорят о серьёзном баге, а не о том что кто-то умрёт.
·>Т.е. ты считаешь, что наличие серьёзного бага должно игнорироваться в проде?

Это очевидно зависит от цены не игнорирования, от цены бага и т.п. Это компромисс — где-то уместный, а где-то нет.

EP>>В любом случае, даже если использовать другую терминологию и выделять ещё и системное тестирование — то мой поинт всё равно остаётся в силе — assert'ы отрабатывают на всех этапах тестирования.

·>Но почему не в релизе-то?

Я уже ранее говорил что в основном из-за производительности.
Re[39]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: · Великобритания  
Дата: 17.08.16 06:48
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>·>Я просто не понял зачем ты это доказываешь. Тем более таким образом. Опциональность ассертов, точнее их отключение в release — это by design.

EP>Показываю опциональность, для того чтобы было видно семантическое отличие от обычных проверок. Таким образом — потому что самая красноречивая демонстрация того, что для корректного кода они не нужны.
Это не опциональность. Во-первых, верификация делает ненужным не только ассерты, но и многие виды тестов. Во-вторых, как часто попадаются проекты с верифицированным кодом? Один на миллион? Мне не попадались...

EP>>>·>Проблема в том, что их не надо писать. Ассерт это такой индикатор лажи, когда программист поленился либо написать тест,

EP>>>Это твои фантазии — я например использую ассерты одновременно с тестами.
EP>·>Вредная привычка...
EP>Почему? Потому что ты не используешь?
Да. Когда писал на Плюсах — использовал. Но тогда у меня опыта не было, да и практика юнит-тестирования была экзотикой. Потом перешел на Яву, там ассертов изначально не было, приходилось обходиться, а потом они появились (java5 афаир), но осмысленных применений им уже не нашлось.

EP>Даже если ты не веришь в то что они помогают в отлове багов, то всё равно остаётся аспект документирования пред/пост-условий и т.п. Причём это не просто текстовый комментарий, а реально выполняемая проверка, пусть даже только при тестировании.

Угу, что прекрасно делается юнит-тестами.

EP>При этом втыкаются непосредственно во время кодирования, не переключая контекст. И являются крайне дешёвыми.

TDD же.

EP>>>Предлагаешь продумывать поведение для каждого возможного поломанного инварианта?

EP>·>Да. Или лучше — не допускать ломание инвариантов.
EP>Ага, за всё хорошее и против всего плохого.
EP>Если у тебя инварианты и т.п. не ломаются, то непонятно зачем ты восхваляешь всякие defensive штуки типа range check?
Ломаются. Но я знаю, что в этом случае получу чёткий стек-трейс, а не UB.

EP>·>А что по-твоему оно будет делать в релизе?

EP>Кто оно? Баги?
Да. И баги тоже. Fail-fast, слышал?

EP>>>Не получится — у тебя код пришёл в состояние в которое не должен был прийти по логике вещей — каким образом он в него пришёл ты не знаешь, глобальное состояние тоже не известно, а точнее может содержать неизвестно какие ошибки.

EP>·>Значит кинь исключение, сбрось дамп состояния в лог, етс.
EP>Это же не "продолжить корректно работать" — ты не локализовал и не устранил причину, а лишь пытаешься собрать данные для последующего разбирательства и хоть как-то восстановиться.
Правильно. А как надо? Продолжить работать будто ничего не случилось?

EP>>>·>Для чего ещё?

EP>>>Например инварианты класса. Классы (с private полями) это не просто группировка полей а-ля структуры (либо эмуляция структур через getters&setters) — это ещё и дополнительные инварианты наложенные на эти private поля.
EP>·>Т.е. косяки дизайна в алгоритме затыкаются ассертами.
EP>Шта? Как ты пришёл к этому выводу? Я говорю про инварианты классов, и они таки существуют.
Т.е. инварианты "сами нарушились"?

EP>>>·>Может какая-то доля процента и будет чем-то интересным, но её лучше тогда явно протестировать.

EP>>>Ассерты используются вместе с тестами, а не вместо них.
EP>·>Я не говорю, что их невозможно использовать. Я говорю, что их не следует использовать, лучше заменять на что-то более надёжное: лучший дизайн алгоритмов, не допускающий всякую НЁХ, более качественное покрытие тестами и более качественную диагностику.
EP>Ты так и не объяснил почему их не следует использовать, учитывая их минимальную цену. Пока всё сводится к "я их не использую, значит их не следует использовать".
Ок. Насчёт цены согласен, об этом я уже писал. Если с тестами плохо, то использовать ЮТ получится дороже ассертов, получается компромисс — уж лучше что-то, чем ничего. В хорошо организованном проекте тесты дёшевы и ассерты становятся бессмысленны.

EP>И непонятно причём тут "лучший дизайн алгоритмов" — речи о том чтобы делать плохие алгоритмы не было. При этом "лучший дизайн алгоритмов" не избавляет от необходимости их тестирования, одним из аспектов которого являются в том числе assert'ы.

Ассерты это тестирование для убогих.

EP>>>Нет, так как после формальной верификации (либо например через несколько релизов без выстреливания assert'ов) их можно отключить, в то время как проверки не являются опциональными.

EP>·>Ээээээ.. Ты что под формальной верификацией понимаешь?
EP>Доказывание свойств алгоритмов на формальном языке с автоматической проверкой правильности применения правил вывода и т.п.
Ну... и зачем при наличии верификации вообще нужны ассерты? Откуда они возьмутся? Какой смысл их писать в верифицируемом коде?

EP>>>Нет, неразрешимы означает что неразрешимы. Нужность/ненужность тут ортогонально — смотри например halting probelm

EP>·>halting problem это построение универсального алгоритма. Причём тут это? Программист обычно может чуть больше. По крайней мере в случае, когда хочет написать ассерт.
EP>Смотри выделенное — проверка далеко не каждого пред/пост-условия является разрешимой задачей.
Не понял. И как ты проверишь с помощью ассерта неразрешимое предусловие? И чем это будет отличаться от ЮТ?

EP>>>Нет, при этом это всё жёсткие фейлы.

EP>>>Жёсткие в том смысле что говорят о серьёзном баге, а не о том что кто-то умрёт.
EP>·>Т.е. ты считаешь, что наличие серьёзного бага должно игнорироваться в проде?
EP>Это очевидно зависит от цены не игнорирования, от цены бага и т.п. Это компромисс — где-то уместный, а где-то нет.
Что именно это значит? Опять у тебя какой-то оксюморон, "серьёзный дешевый баг". Прям как "солидная фирма возьмёт в аренду дырокол".
Ок. Допустим у тебя есть ассерт какой-то. И ты считаешь, что цена велика. А в соседней строчке ещё один ассерт и цена мала. Ты включишь или выключишь ассерты в релизе?
Или ты ставишь ассерты только на дешевые баги? И зачем же тогда этими ассертами заморачиваться, время тратить на дешевую мелочёвку?

EP>>>В любом случае, даже если использовать другую терминологию и выделять ещё и системное тестирование — то мой поинт всё равно остаётся в силе — assert'ы отрабатывают на всех этапах тестирования.

EP>·>Но почему не в релизе-то?
EP>Я уже ранее говорил что в основном из-за производительности.
Ок, допишу ещё причину.
4. Плохо дело с языком, убогий компилятор, для преждевременной оптимизации. Приходится явно подсказывать компилятору какие проверки необязательны.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[2]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Farsight СССР  
Дата: 17.08.16 12:23
Оценка:
Здравствуйте, a_g_99, Вы писали:

__>Зарплата Senior Staff Engineer (Java/JavaScript) в Google ~ 250k в год

__>Зарплата Senior Engineer (Java/JavaScript) в Netflix ~ 350k в год

__>Зарплата Senior .Net Engineer в Microsoft ~ 80k в год


А если бы в Netflix на стеке MS жили, то было бы уже не 350k в год?
</farsight>
Re[3]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: a_g_99 США http://www.hooli.xyz/
Дата: 17.08.16 12:46
Оценка:
Здравствуйте, Farsight, Вы писали:

F>А если бы в Netflix на стеке MS жили, то было бы уже не 350k в год?

Было бы 80 или 100. В стеке MS главное что? Tools. Visual Studio, Sharepoint, все это. И кто будет платить за знание VS 350 велоинструктору?
Re[4]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Farsight СССР  
Дата: 17.08.16 13:27
Оценка:
Здравствуйте, a_g_99, Вы писали:

__>Было бы 80 или 100. В стеке MS главное что? Tools. Visual Studio, Sharepoint, все это. И кто будет платить за знание VS 350 велоинструктору?


Заболтать хотите? Я думал, что платят за решение задач. Это я, как бывший велоинструктор, говорю .
</farsight>
Re[5]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: a_g_99 США http://www.hooli.xyz/
Дата: 17.08.16 14:24
Оценка: -1
Здравствуйте, Farsight, Вы писали:

F>Заболтать хотите? Я думал, что платят за решение задач. Это я, как бывший велоинструктор, говорю .


Чтобы решать сложные задачи нужна соотвествующая платформа. Невозможно решать задачи нетфликс на .net or php или дельфи. Это вам не педали крутить велоинструктор. Это другой уровень
Re[6]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Farsight СССР  
Дата: 17.08.16 15:55
Оценка: +1
Здравствуйте, a_g_99, Вы писали:

__>Чтобы решать сложные задачи нужна соотвествующая платформа. Невозможно решать задачи нетфликс на .net or php или дельфи.


Простите, но это болтология. Очередной треп на тему "Java vs .Net vs _ВАШ_ВАРИАНТ_". Я, пожалуй, пропущу .

__>Это вам не педали крутить велоинструктор. Это другой уровень


"Это вам не по кнопкам долбить и в экран пялится, это другой уровень" © Велоинструктор
</farsight>
Re[7]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: · Великобритания  
Дата: 17.08.16 16:12
Оценка: :))
Здравствуйте, Farsight, Вы писали:

__>>Чтобы решать сложные задачи нужна соотвествующая платформа. Невозможно решать задачи нетфликс на .net or php или дельфи.

F>Простите, но это болтология. Очередной треп на тему "Java vs .Net vs _ВАШ_ВАРИАНТ_". Я, пожалуй, пропущу .
Да что тут пропускать, кроме фактов. Покажи мне хоть одну low latency систему на .Net. Или клиент-серверную СУБД. Или Search Engine. Или framework/vm для mobile devices. Или тупо web server. Или clustering engine типа Spark/Hadoop/etc. Или MQ.
Вот и думай кому ещё нужет этот ваш .net/php/дельфи кроме как велоинструкторам.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[8]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Farsight СССР  
Дата: 17.08.16 16:42
Оценка:
Здравствуйте, ·, Вы писали:

·>Да что тут пропускать, кроме фактов. Покажи мне хоть одну low latency систему на .Net. Или клиент-серверную СУБД. Или Search Engine. Или framework/vm для mobile devices. Или тупо web server. Или clustering engine типа Spark/Hadoop/etc. Или MQ.

·>Вот и думай кому ещё нужет этот ваш .net/php/дельфи кроме как велоинструкторам.

Запахло Apache'м .

Так уж сложилось, что .net догоняющая платформа, со всеми вытекающими. Не приходило в голову?
</farsight>
Re[9]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: · Великобритания  
Дата: 17.08.16 16:57
Оценка:
Здравствуйте, Farsight, Вы писали:

F>·>Вот и думай кому ещё нужет этот ваш .net/php/дельфи кроме как велоинструкторам.

F>Запахло Apache'м .
Причем тут Апач?

F>Так уж сложилось, что .net догоняющая платформа, со всеми вытекающими. Не приходило в голову?

В каком месте догоняющая? Что именно удалось догнать? Так что не догоняющая, а просто отсталая. Тот же .net compact, подогоняли, да бросили ещё до Андроида.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[7]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: a_g_99 США http://www.hooli.xyz/
Дата: 17.08.16 17:03
Оценка: :)
Здравствуйте, Farsight, Вы писали

Уровень платформы определят salary. Уровень .net 80-140. Уровень Java 150-500. Вот она реальность. Те кто выбрал .net неудачник по умолчанию. Вот она реальность
Re[40]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Evgeny.Panasyuk Россия  
Дата: 17.08.16 18:36
Оценка:
Здравствуйте, ·, Вы писали:

·>как часто попадаются проекты с верифицированным кодом? Один на миллион? Мне не попадались...


Я тебе привожу иллюстрацию показывающую что в корректном коде они не нужны. ВСЁ! Какая разница как часто попадаются такие проекты?

EP>>Даже если ты не веришь в то что они помогают в отлове багов, то всё равно остаётся аспект документирования пред/пост-условий и т.п. Причём это не просто текстовый комментарий, а реально выполняемая проверка, пусть даже только при тестировании.

·>Угу, что прекрасно делается юнит-тестами.

Каким образом? Юнит-тесты в общем случае это набор входных и выходных векторов, которые помимо всего прочего хранятся отдельно от кода.

EP>>При этом втыкаются непосредственно во время кодирования, не переключая контекст. И являются крайне дешёвыми.

·>TDD же.

И причём тут TDD?

EP>>>>·>Для чего ещё?

EP>>>>Например инварианты класса. Классы (с private полями) это не просто группировка полей а-ля структуры (либо эмуляция структур через getters&setters) — это ещё и дополнительные инварианты наложенные на эти private поля.
EP>>·>Т.е. косяки дизайна в алгоритме затыкаются ассертами.
EP>>Шта? Как ты пришёл к этому выводу? Я говорю про инварианты классов, и они таки существуют.
·>Т.е. инварианты "сами нарушились"?

Не сами, а из-за бага, которые нужно отлавливать. Ассерты способствуют этому в том числе.

EP>>Ты так и не объяснил почему их не следует использовать, учитывая их минимальную цену. Пока всё сводится к "я их не использую, значит их не следует использовать".

·>Ок. Насчёт цены согласен, об этом я уже писал. Если с тестами плохо, то использовать ЮТ получится дороже ассертов, получается компромисс — уж лучше что-то, чем ничего.

Ещё раз, я не говорю про то что не нужно использовать тесты. Я использую и тесты и ассерты — совместно.

·>В хорошо организованном проекте тесты дёшевы и ассерты становятся бессмысленны.


Я использую и тесты и ассерты. А ты так и не объяснил почему нужно отказываться от крайне дешёвых ассертов, отрабатывающих в большем количестве случаев чем юнит-тесты. Они никак не мешают, пишутся не отходя от кассы, отрабатывают в огромном количестве состояний.
Может потому что ты веришь в то что юнит-тесты покрывают все граничные ситуации? Или хотя бы что ты их все локализовал? Очевидно ни то, ни другое не гарантируется, и непонятно почему нужно отказываться от дополнительного практически бесплатного средства?

EP>>И непонятно причём тут "лучший дизайн алгоритмов" — речи о том чтобы делать плохие алгоритмы не было. При этом "лучший дизайн алгоритмов" не избавляет от необходимости их тестирования, одним из аспектов которого являются в том числе assert'ы.

·>Ассерты это тестирование для убогих.

Ассерты не заменяют остальное тестирование — ты это сам придумал, и сам же с этим споришь.

EP>>>>Нет, так как после формальной верификации (либо например через несколько релизов без выстреливания assert'ов) их можно отключить, в то время как проверки не являются опциональными.

EP>>·>Ээээээ.. Ты что под формальной верификацией понимаешь?
EP>>Доказывание свойств алгоритмов на формальном языке с автоматической проверкой правильности применения правил вывода и т.п.
·>Ну... и зачем при наличии верификации вообще нужны ассерты? Откуда они возьмутся? Какой смысл их писать в верифицируемом коде?

Ещё раз, я иллюстрирую их опциональную семантику, смотри выделенное.

EP>>>>Нет, неразрешимы означает что неразрешимы. Нужность/ненужность тут ортогонально — смотри например halting probelm

EP>>·>halting problem это построение универсального алгоритма. Причём тут это? Программист обычно может чуть больше. По крайней мере в случае, когда хочет написать ассерт.
EP>>Смотри выделенное — проверка далеко не каждого пред/пост-условия является разрешимой задачей.
·>Не понял. И как ты проверишь с помощью ассерта неразрешимое предусловие? И чем это будет отличаться от ЮТ?

Смотри контекст:

·>>>"Опциональный жесткий фейл". Это не звучит для тебя как оксюморон?
EP>>Нет. Нарушение условия ассерта это жёсткий фейл, баг в программе. Точно также как и нарушение любого пред/пост-условия вокруг каждого выражения (а-ля Hoare Triple).
EP>>При этом несмотря на то что это жёсткие фейлы, в релизной версии нет даже и малой части всех этих проверок, а некоторые и вовсе неразрешимы.


·>Ок. Допустим у тебя есть ассерт какой-то. И ты считаешь, что цена велика. А в соседней строчке ещё один ассерт и цена мала. Ты включишь или выключишь ассерты в релизе?


Я же говорил уже выше — assert'ы разбивают на классы. В зависимости от заданного уровня при компиляции часть из них, либо все отключаются.
Подобное используется например в Bloomberg'е — 1, 2.

·>Ок, допишу ещё причину.

·>4. Плохо дело с языком, убогий компилятор, для преждевременной оптимизации. Приходится явно подсказывать компилятору какие проверки необязательны.

Ещё раз поясняю — assert'ы используются далеко не только для тех вещей которые автоматически проверяются в managed языках. Собственно наличие assert'ов в managed языках как раз тому подтверждение
Re[8]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Farsight СССР  
Дата: 17.08.16 19:25
Оценка:
Здравствуйте, a_g_99, Вы писали:

__>Уровень платформы определят salary. Уровень .net 80-140. Уровень Java 150-500. Вот она реальность. Те кто выбрал .net неудачник по умолчанию. Вот она реальность


Это феерично, спасибо!
</farsight>
Re[10]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Farsight СССР  
Дата: 17.08.16 20:26
Оценка:
Здравствуйте, ·, Вы писали:

·>Причем тут Апач?

Так просто, подумалось...

·>В каком месте догоняющая? Что именно удалось догнать? Так что не догоняющая, а просто отсталая.

Ну, например, посмотрели на стопитсот mvc-фреймворков разной степени укуренности и крутизны, и сделали один нормальный — asp.net mvc.

·>Тот же .net compact, подогоняли, да бросили ещё до Андроида.

Бывает.
</farsight>
Re[2]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: r.kamenskiy Россия  
Дата: 17.08.16 20:34
Оценка: +1
Здравствуйте, a_g_99, Вы писали:

__>Зарплата Senior Staff Engineer (Java/JavaScript) в Google ~ 250k в год

__>Зарплата Senior Engineer (Java/JavaScript) в Netflix ~ 350k в год

__>Зарплата Senior .Net Engineer в Microsoft ~ 80k в год


Враньё. Медианные зарплаты для Senior Software Engineer в названных вами компаниях в 2016 году:

Microsoft: $147702
Google: $160250
Netfix: $164382

Как бы известно, что в Netflix самые большие зарплаты, но java здесь не причем. Присто у них досталочно денег, чтобы собирать сливки
Re[41]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: · Великобритания  
Дата: 18.08.16 07:03
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>·>как часто попадаются проекты с верифицированным кодом? Один на миллион? Мне не попадались...

EP>Я тебе привожу иллюстрацию показывающую что в корректном коде они не нужны. ВСЁ! Какая разница как часто попадаются такие проекты?
Не надо мне доказывать, что они не нужны. Я это и сам прекрасно знаю.

EP>·>Угу, что прекрасно делается юнит-тестами.

EP>Каким образом? Юнит-тесты в общем случае это набор входных и выходных векторов, которые помимо всего прочего хранятся отдельно от кода.
Условие ассерта переносится в тестовый код.

EP>>>При этом втыкаются непосредственно во время кодирования, не переключая контекст. И являются крайне дешёвыми.

EP>·>TDD же.
EP>И причём тут TDD?
В случае TDD тесты втыкаются непосредственно во время кодирования, не переключая контекст. И являются крайне дешёвыми.

EP>>>·>Т.е. косяки дизайна в алгоритме затыкаются ассертами.

EP>>>Шта? Как ты пришёл к этому выводу? Я говорю про инварианты классов, и они таки существуют.
EP>·>Т.е. инварианты "сами нарушились"?
EP>Не сами, а из-за бага, которые нужно отлавливать. Ассерты способствуют этому в том числе.
Вот если ты догадался вставить куда-то ассерт, значит ты предположил, что здесь что-то может быть нарушено, т.е. вероятен какой-то косяк. Вместо того, чтобы просто заткнуть неизвестное ассертом: "хз чё, потом вдруг грохнется — разберусь", следует просто подумать и либо исключить возможность этого косяка (чтобы условие под ассертом не случалось вообще), либо аккуратно покрыть тестовым сценарием, возможно обсудив с бизнесом корректное поведение.

EP>·>Ок. Насчёт цены согласен, об этом я уже писал. Если с тестами плохо, то использовать ЮТ получится дороже ассертов, получается компромисс — уж лучше что-то, чем ничего.

EP>Ещё раз, я не говорю про то что не нужно использовать тесты. Я использую и тесты и ассерты — совместно.
Так а я говорю, что тестов достаточно. Просто пиши тесты везде где чешется вставить ассерт.

EP>·>В хорошо организованном проекте тесты дёшевы и ассерты становятся бессмысленны.

EP>Я использую и тесты и ассерты. А ты так и не объяснил почему нужно отказываться от крайне дешёвых ассертов, отрабатывающих в большем количестве случаев чем юнит-тесты. Они никак не мешают, пишутся не отходя от кассы, отрабатывают в огромном количестве состояний.
EP>Может потому что ты веришь в то что юнит-тесты покрывают все граничные ситуации? Или хотя бы что ты их все локализовал? Очевидно ни то, ни другое не гарантируется, и непонятно
А ты веришь, что ассерты покрывают все граничные ситуации и тд?

EP>почему нужно отказываться от дополнительного практически бесплатного средства?

Так объяснил же уже. Ассерты слабее тестов. Выбирай более сильное средство. Пиши код качественнее, продумывай архитектуру лучше, чтобы тесты тоже были практически бесплатны.

EP>>>И непонятно причём тут "лучший дизайн алгоритмов" — речи о том чтобы делать плохие алгоритмы не было. При этом "лучший дизайн алгоритмов" не избавляет от необходимости их тестирования, одним из аспектов которого являются в том числе assert'ы.

EP>·>Ассерты это тестирование для убогих.
EP>Ассерты не заменяют остальное тестирование — ты это сам придумал, и сам же с этим споришь.
Я не это утверждаю, я утверждаю что тестирование заменяет ассерты.

EP>>>·>Ээээээ.. Ты что под формальной верификацией понимаешь?

EP>>>Доказывание свойств алгоритмов на формальном языке с автоматической проверкой правильности применения правил вывода и т.п.
EP>·>Ну... и зачем при наличии верификации вообще нужны ассерты? Откуда они возьмутся? Какой смысл их писать в верифицируемом коде?
EP>Ещё раз, я иллюстрирую их опциональную семантику, смотри выделенное.
Ещё раз, опциональную семантику не надо иллюстрировать. Ассерты опциональны по определению. Ассерты задизайнены так, что они отключаются в релизе.
А в верифицируемом коде ассерты не просто опциональны, они не нужны от слова вообще.

EP>·>Не понял. И как ты проверишь с помощью ассерта неразрешимое предусловие? И чем это будет отличаться от ЮТ?

EP>Смотри контекст:
EP>

EP>·>>>"Опциональный жесткий фейл". Это не звучит для тебя как оксюморон?
EP>>>Нет. Нарушение условия ассерта это жёсткий фейл, баг в программе. Точно также как и нарушение любого пред/пост-условия вокруг каждого выражения (а-ля Hoare Triple).
EP>>>При этом несмотря на то что это жёсткие фейлы, в релизной версии нет даже и малой части всех этих проверок, а некоторые и вовсе неразрешимы.

Не понимаю к чему всё это. Причём тут ассерты? Чем ЮТ не устраивают?

EP>·>Ок. Допустим у тебя есть ассерт какой-то. И ты считаешь, что цена велика. А в соседней строчке ещё один ассерт и цена мала. Ты включишь или выключишь ассерты в релизе?

EP>Я же говорил уже выше — assert'ы разбивают на классы. В зависимости от заданного уровня при компиляции часть из них, либо все отключаются.
EP>Подобное используется например в Bloomberg'е — 1, 2.
Смотреть два часа видео пока не сильно тянет. Может конкретные места укажешь?
Или сразу ответь на вопрос — чем это лучше хорошей библиотеки логирования с разными log levels?

EP>·>Ок, допишу ещё причину.

EP>·>4. Плохо дело с языком, убогий компилятор, для преждевременной оптимизации. Приходится явно подсказывать компилятору какие проверки необязательны.
EP>Ещё раз поясняю — assert'ы используются далеко не только для тех вещей которые автоматически проверяются в managed языках. Собственно наличие assert'ов в managed языках как раз тому подтверждение
Наличие — да, ибо добавить элементарно, но использование минимально, в основном неопытными, новичками.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[11]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: · Великобритания  
Дата: 18.08.16 07:22
Оценка:
Здравствуйте, Farsight, Вы писали:

F>·>В каком месте догоняющая? Что именно удалось догнать? Так что не догоняющая, а просто отсталая.

F>Ну, например, посмотрели на стопитсот mvc-фреймворков разной степени укуренности и крутизны, и сделали один нормальный — asp.net mvc.
Ага, прям уж такая silver bullet, жуткий монстр.

F>·>Тот же .net compact, подогоняли, да бросили ещё до Андроида.

F>Бывает.
И это характерно, не единственный заброшенный проект. И ничего нового на что бы стоило обратить внимание, мол, на .net такое есть, а в java — нет. Единственная уникальная ниша это windows gui, ну может ещё web ui, формоклёпство т.е. одно.
Может 10 лет назад это была догоняющая платформа, а сейчас она просто отставшая.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[12]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Farsight СССР  
Дата: 18.08.16 12:26
Оценка:
Здравствуйте, ·, Вы писали:

·>Ага, прям уж такая silver bullet, жуткий монстр.

Боюсь-боюсь прям.

·>И это характерно, не единственный заброшенный проект. И ничего нового на что бы стоило обратить внимание, мол, на .net такое есть, а в java — нет. Единственная уникальная ниша это windows gui, ну может ещё web ui, формоклёпство т.е. одно.

·>Может 10 лет назад это была догоняющая платформа, а сейчас она просто отставшая.

На .net есть новая система, автоматизирующая специфический бизнес моего заказчика, на java нет. Все, java отсталая .
</farsight>
Re[13]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: · Великобритания  
Дата: 18.08.16 13:28
Оценка:
Здравствуйте, Farsight, Вы писали:

F>·>Ага, прям уж такая silver bullet, жуткий монстр.

F>Боюсь-боюсь прям.
Опыт-то в чём-то другом есть? Может тебе сравнить не с чем, вот и радуешься тому что дают?

F>·>И это характерно, не единственный заброшенный проект. И ничего нового на что бы стоило обратить внимание, мол, на .net такое есть, а в java — нет. Единственная уникальная ниша это windows gui, ну может ещё web ui, формоклёпство т.е. одно.

F>·>Может 10 лет назад это была догоняющая платформа, а сейчас она просто отставшая.
F>На .net есть новая система, автоматизирующая специфический бизнес моего заказчика, на java нет.
F>Все, java отсталая .
У тебя с логикой беда, или с вниманием. Вспомни суть дискуссии: "Невозможно решать задачи нетфликс на .net or php или дельфи."
Я уверен, если ты не лабаешь Windows GUI, то этот твой .net возможно без проблем заменить той же Java. А если Windows GUI, то можно взять Delphi или Qt или ещё что с тем же успехом.
Есть области где java тянет, но .net не тянет. Но не наоборот.
Другими словами. Допустим твой заказчик захочет поиграться на бирже и построить low latency систему. Выбор будет только C/C++/Java, всё. Ну ещё может какая-нибуь экзотика типа haskell. А вот очередную систему очередной автоматизации очередного бизнеса можно строить хоть на чём, принципиальной разницы никакой.
Т.е. да, с твоей точки зрения ява отсталая, ибо ты ничем другим кроме "система, автоматизирующая специфический бизнес" не занимался и ничего кроме .net не знаешь. С т.з. индустрии — совсем наоборот. Т.е. по сути это не Java отсталая, а твои знания о ней.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[14]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Farsight СССР  
Дата: 18.08.16 14:09
Оценка: +1
Здравствуйте, ·, Вы писали:

·>Опыт-то в чём-то другом есть? Может тебе сравнить не с чем, вот и радуешься тому что дают?

Есть. С java в том числе.

·>У тебя с логикой беда, или с вниманием. Вспомни суть дискуссии: "Невозможно решать задачи нетфликс на .net or php или дельфи."

·>Я уверен, если ты не лабаешь Windows GUI, то этот твой .net возможно без проблем заменить той же Java. А если Windows GUI, то можно взять Delphi или Qt или ещё что с тем же успехом.
·>Есть области где java тянет, но .net не тянет. Но не наоборот.
·>Другими словами. Допустим твой заказчик захочет поиграться на бирже и построить low latency систему. Выбор будет только C/C++/Java, всё. Ну ещё может какая-нибуь экзотика типа haskell. А вот очередную систему очередной автоматизации очередного бизнеса можно строить хоть на чём, принципиальной разницы никакой.
·>Т.е. да, с твоей точки зрения ява отсталая, ибо ты ничем другим кроме "система, автоматизирующая специфический бизнес" не занимался и ничего кроме .net не знаешь. С т.з. индустрии — совсем наоборот. Т.е. по сути это не Java отсталая, а твои знания о ней.

Не надо мне приписывать то, чего я не утверждал. Java мне нравится. Бомбит от апологетов, которые все на черное и белое делят. Я пытаюсь сказать, что .net догоняющая, по ряду причин (позже появился, ограничен платформой, сурово проприетарный). Суть у платформ +- одинаковая. В ответ — осталая и вообще уже в могиле, потому что на ней нельзя low latency и netflix. Можно, если осторожно.

PS: Торжественно обещаю больше в холивары .net vs java не вступать, ибо смысла в них нет. Всем добра.
</farsight>
Re[15]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: · Великобритания  
Дата: 18.08.16 14:27
Оценка:
Здравствуйте, Farsight, Вы писали:

F>·>Опыт-то в чём-то другом есть? Может тебе сравнить не с чем, вот и радуешься тому что дают?

F>Есть. С java в том числе.
И чем какой-нибудь банальный spring.mvc хуже?

F>·>Т.е. да, с твоей точки зрения ява отсталая, ибо ты ничем другим кроме "система, автоматизирующая специфический бизнес" не занимался и ничего кроме .net не знаешь. С т.з. индустрии — совсем наоборот. Т.е. по сути это не Java отсталая, а твои знания о ней.

F>Не надо мне приписывать то, чего я не утверждал. Java мне нравится. Бомбит от апологетов, которые все на черное и белое делят. Я пытаюсь сказать, что .net догоняющая, по ряду причин (позже появился,
Это плохая отмаза. Прошло уже довольно много времени. Java тоже когда-то была догоняющей, например, по сравнению со стариком C/C++, то теперь как минимум наравне и составляет серьёзную конкуренцию.

F>ограничен платформой, сурово проприетарный).

Так в этом виноват только сам .net, точнее ИндусоМикрософт.

F>Суть у платформ +- одинаковая. В ответ — осталая и вообще уже в могиле,

Не в могиле, конечно, но отсталая, в одном ряду с php.

F>потому что на ней нельзя low latency и netflix. Можно, если осторожно.

Нельзя, к сожалению. Не подходящий gc, так себе jit, не особо с линухом дружит.

F>PS: Торжественно обещаю больше в холивары .net vs java не вступать, ибо смысла в них нет. Всем добра.

Хе-хе.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Отредактировано 18.08.2016 14:29 · . Предыдущая версия .
Re[3]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: a_g_99 США http://www.hooli.xyz/
Дата: 18.08.16 15:55
Оценка: :)))
Здравствуйте, r.kamenskiy, Вы писали:

RK>Враньё. Медианные зарплаты для Senior Software Engineer в названных вами компаниях в 2016 году:


RK>Microsoft: $147702

RK>Google: $160250
RK>Netfix: $164382

Кто вам такую чушь рассказывает? Очередной дурацкий сайтик?

Я вам привел реальный расклад по деньгам вы мне в ответ всякие глупости несете. Вы когда поговорите вживую с МС, Гуглом и Нетфликс — сможете со мной дискутировать на одном уровне. А пока посидите и послушайте информацию из первых рук. И будьте благодарны за это в конце концов.

RK>Как бы известно, что в Netflix самые большие зарплаты, но java здесь не причем. Присто у них досталочно денег, чтобы собирать сливки

Вот опять. Они собирают сливки потому что выбрали правильную платформу. С .net/php/delphi у них не было бы шансов вырваться вперед. .Net вообще просто какая-то жуткая примочка к Вижуал Студио. Ну как можно хоть что-то сделать там в принципе? Это же смешно.
Ну кто будет нанимать программистов за 350 в год чтобы утопить свой бизнес? Достаточно и 80к в год на такое доброе дело . Тем более что программисту дотНет больше полгода не нужно на это.
Re[4]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: r.kamenskiy Россия  
Дата: 18.08.16 16:15
Оценка: +4
Здравствуйте, a_g_99, Вы писали:
__>Кто вам такую чушь рассказывает? Очередной дурацкий сайтик?

Для справки: зарплаты, которые платятся по рабочей визе работодатель обязан раскрывать.
И если вы называете "дурацким сайтиком" базу зарплат американских компаний — это объясняет причину всех ваших нелепых постов.
вот база, если что http://h1bdata.info/


__>Я вам привел реальный расклад по деньгам вы мне в ответ всякие глупости несете. Вы когда поговорите вживую с МС, Гуглом и Нетфликс — сможете со мной дискутировать на одном уровне.
О каком уровне идет речь? Уровне балабольства?

__>А пока посидите и послушайте информацию из первых рук. И будьте благодарны за это в конце концов.


Re[16]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Farsight СССР  
Дата: 18.08.16 17:45
Оценка:
Здравствуйте, ·, Вы писали:

Просто на вопросы отвечу, не холивара ради ...

·>И чем какой-нибудь банальный spring.mvc хуже?

Ничем. Я же не говорю, что все плохие. Есть классные, есть треш. Опыт учли и выкатили один asp.net mvc. Чем плохо?

·>Это плохая отмаза. Прошло уже довольно много времени. Java тоже когда-то была догоняющей, например, по сравнению со стариком C/C++, то теперь как минимум наравне и составляет серьёзную конкуренцию.

Ну так и .нет так же догонит. Даже с учетом такого талантливого вендора. А самые критичные по производительности вещи все равно на старичках пишут.

·>Не в могиле, конечно, но отсталая, в одном ряду с php.

Голословно.

·>Нельзя, к сожалению. Не подходящий gc, так себе jit, не особо с линухом дружит.

jit в таких системах убирается. gc конфигурируется под серверное приложение. К проектированию надо ответственно подходить. Скажете, на java нельзя набыдлокодить и погрязнуть во всевозможных задержках? А линух да. Но мы будем посмотреть на .Net Core. А еще на .Net Native.

F>>PS: Торжественно обещаю больше в холивары .net vs java не вступать, ибо смысла в них нет. Всем добра.

·>Хе-хе.
</farsight>
Re[17]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: · Великобритания  
Дата: 18.08.16 22:45
Оценка:
Здравствуйте, Farsight, Вы писали:

F>·>И чем какой-нибудь банальный spring.mvc хуже?

F>Ничем. Я же не говорю, что все плохие. Есть классные, есть треш. Опыт учли и выкатили один asp.net mvc. Чем плохо?
И что? Ты считаешь большое разнообразие плохо?

F>·>Это плохая отмаза. Прошло уже довольно много времени. Java тоже когда-то была догоняющей, например, по сравнению со стариком C/C++, то теперь как минимум наравне и составляет серьёзную конкуренцию.

F>Ну так и .нет так же догонит. Даже с учетом такого талантливого вендора. А самые критичные по производительности вещи все равно на старичках пишут.
Что-то мне кажется, что уже можно не надеяться.

F>·>Не в могиле, конечно, но отсталая, в одном ряду с php.

F>Голословно.
Ниша та же.

F>·>Нельзя, к сожалению. Не подходящий gc, так себе jit, не особо с линухом дружит.

F>jit в таких системах убирается.
Неправда. Просто код прогревается.

F>gc конфигурируется под серверное приложение.

Шутишь? Судя по графикам в .net в 99.99% задержки в районе 100ms, а для Явы эти просят репортить баг, если вдруг возникнет задержка более 10us. Разница на четыре порядка!

F>К проектированию надо ответственно подходить. Скажете, на java нельзя набыдлокодить и погрязнуть во всевозможных задержках?

Можно, но проблема в том что на .net не погрязнуть ни у кого не получилось.

F>А линух да. Но мы будем посмотреть на .Net Core. А еще на .Net Native.

А без линуха тупо ничего не выйдет, ни железа подходящего, ни поддержки ядра.

F>>>PS: Торжественно обещаю больше в холивары .net vs java не вступать, ибо смысла в них нет. Всем добра.

F>·>Хе-хе.
F>
И вечно так.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[18]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Farsight СССР  
Дата: 19.08.16 06:18
Оценка:
Здравствуйте, ·, Вы писали:

Да блин...

·>И что? Ты считаешь большое разнообразие плохо?

Наоборот — очень хорошо. Позволяет учитывать опыт и ошибки. java — испытательный полигон, в каком-то смысле.

·>Что-то мне кажется, что уже можно не надеяться.

Мне по другому кажется.

·>Ниша та же.

А энтерпрайз? (вот только не надо, что там тупо веб-сайтики — это неправда)

·>Неправда. Просто код прогревается.

Я про ngen.

·>Шутишь? Судя по графикам в .net в 99.99% задержки в районе 100ms, а для Явы эти просят репортить баг, если вдруг возникнет задержка более 10us. Разница на четыре порядка!

В этой же статье пишут, что удалось уменьшить кол-во задержек на 70% в версии 4.5, хотя все еще есть куда рости. А что касается zing — я не особо в курсе, но вот эта фраза на главной странице "Azul has solved Java's Garbage Collection problem. No more jitter, stalls and pauses." как бы намекает на несовсем корректное сравнение. Это тулинг какой-то или это целый свой рантайм с блэкджеком и....

·>Можно, но проблема в том что на .net не погрязнуть ни у кого не получилось.

Погрязнуть можно в чем угодно — проверено.

·>А без линуха тупо ничего не выйдет, ни железа подходящего, ни поддержки ядра.

Ну я по этому и упомянул .Net Core.

·>И вечно так.

Да.
</farsight>
Re[19]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: · Великобритания  
Дата: 19.08.16 08:06
Оценка:
Здравствуйте, Farsight, Вы писали:

F>Да блин...

Му-ха-ха!!

F>·>И что? Ты считаешь большое разнообразие плохо?

F>Наоборот — очень хорошо. Позволяет учитывать опыт и ошибки. java — испытательный полигон, в каком-то смысле.
Т.е. .net не позволяет учитывть опыт или ошибки...

F>·>Ниша та же.

F>А энтерпрайз? (вот только не надо, что там тупо веб-сайтики — это неправда)
Серверная часть обычно java, интерфейсики|веб-сайтики — да, попадается .net. Я имею в виду крупные компании, банки, етс. На производствах SAP и прочий ужас.

F>·>Неправда. Просто код прогревается.

F>Я про ngen.
Так jit вроде в runtime выполняется, а ngen — deployment time. Или я что-то не знаю?

F>·>Шутишь? Судя по графикам в .net в 99.99% задержки в районе 100ms, а для Явы эти просят репортить баг, если вдруг возникнет задержка более 10us. Разница на четыре порядка!

F>В этой же статье пишут, что удалось уменьшить кол-во задержек на 70% в версии 4.5, хотя все еще есть куда рости.
Они время измеряют в миллисекундах!! Куда там расти...

F>А что касается zing — я не особо в курсе, но вот эта фраза на главной странице "Azul has solved Java's Garbage Collection problem. No more jitter, stalls and pauses." как бы намекает на несовсем корректное сравнение. Это тулинг какой-то или это целый свой рантайм с блэкджеком и....

Просто альтернативная VM для запуска приложений. Т.е. вместо Oracle JRE в продакшне работает ZingVM. В общем на этом разница и заканчивается. Ну и денег стоит...

F>·>Можно, но проблема в том что на .net не погрязнуть ни у кого не получилось.

F>Погрязнуть можно в чем угодно — проверено.
Это понятно. Суть в том, что на .net нелья не погрязнуть.

F>·>А без линуха тупо ничего не выйдет, ни железа подходящего, ни поддержки ядра.

F>Ну я по этому и упомянул .Net Core.
Поживём, увидим.

F>·>И вечно так.

F>Да.
Не волнуйся, когда .net умрёт, это закончится.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[20]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Farsight СССР  
Дата: 19.08.16 08:37
Оценка:
Здравствуйте, ·, Вы писали:

·>Т.е. .net не позволяет учитывть опыт или ошибки...

Позволяет, вот только тащат все в основном с java.

·>Серверная часть обычно java, интерфейсики|веб-сайтики — да, попадается .net. Я имею в виду крупные компании, банки, етс. На производствах SAP и прочий ужас.

На всем чем угодно серверная часть. Несколько наших клиентов живут на стеке МС, у них полно всяких штук на .net, в том числе да — интерфейсики с сайтиками.

·>Так jit вроде в runtime выполняется, а ngen — deployment time. Или я что-то не знаю?

Коротенько — чпуньк.

·>Они время измеряют в миллисекундах!! Куда там расти...

·>Просто альтернативная VM для запуска приложений. Т.е. вместо Oracle JRE в продакшне работает ZingVM. В общем на этом разница и заканчивается. Ну и денег стоит...
Насколько понял, они еще неслабо прокачали jit (или вообще убрали) и сборку мусора относительно Oracle JRE. Комерческих альтернатив рантайму .net я не знаю. Вдруг запилит кто-нить?

·>Это понятно. Суть в том, что на .net нелья не погрязнуть.

Что значит погрязнуть?

F>>Ну я по этому и упомянул .Net Core.

·>Поживём, увидим.


·>Не волнуйся, когда .net умрёт, это закончится.

Думаю, это никогда не закончится...
</farsight>
Re[15]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Sinix  
Дата: 19.08.16 08:39
Оценка: +1
Здравствуйте, Farsight, Вы писали:

F>PS: Торжественно обещаю больше в холивары .net vs java не вступать, ибо смысла в них нет. Всем добра.

+1
По опыту — холиварить нет смысла, если хоть один из основных участников не разбирается в теме. Иначе большую часть времени придётся разбирать не собстсвенно проблемы, а аргументы в стиле "мне нравится — значит правда", причём с обоих сторон. Не, читать отдельные вещи забавно, но всю ветку целиком и тем более спорить — нафиг-нафиг.
Re[16]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Farsight СССР  
Дата: 19.08.16 08:41
Оценка: :))
Здравствуйте, Sinix, Вы писали:

S>+1

S>По опыту — холиварить нет смысла, если хоть один из основных участников не разбирается в теме. Иначе большую часть времени придётся разбирать не собстсвенно проблемы, а аргументы в стиле "мне нравится — значит правда", причём с обоих сторон. Не, читать отдельные вещи забавно, но всю ветку целиком и тем более спорить — нафиг-нафиг.

Я... не... могу... остановиться... Еще и оратор из меня херовый
</farsight>
Re[21]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: · Великобритания  
Дата: 19.08.16 09:03
Оценка:
Здравствуйте, Farsight, Вы писали:

F>·>Т.е. .net не позволяет учитывть опыт или ошибки...

F>Позволяет, вот только тащат все в основном с java.
Стоить заметить, что тащить с Явы на Яву проще, чем куда-то ещё.

F>·>Серверная часть обычно java, интерфейсики|веб-сайтики — да, попадается .net. Я имею в виду крупные компании, банки, етс. На производствах SAP и прочий ужас.

F>На всем чем угодно серверная часть. Несколько наших клиентов живут на стеке МС, у них полно всяких штук на .net, в том числе да — интерфейсики с сайтиками.
По моим наблюдениям такое практикуется в небольших компаниях, нанимают студентов, те им пилят что-то в в красивенькой Студии... В большом Энтерпрайзе — шарпа мало.

F>·>Так jit вроде в runtime выполняется, а ngen — deployment time. Или я что-то не знаю?

F>Коротенько — чпуньк.
Ну, а я что говорил? " to be pre-compiled instead of letting the Common Language Runtime (CLR) do a just-in-time compilation (JIT) at runtime".
Этого в Яве не было, сразу в хороший JIT вложились.

F>·>Они время измеряют в миллисекундах!! Куда там расти...

F>·>Просто альтернативная VM для запуска приложений. Т.е. вместо Oracle JRE в продакшне работает ZingVM. В общем на этом разница и заканчивается. Ну и денег стоит...
F>Насколько понял, они еще неслабо прокачали jit (или вообще убрали) и сборку мусора относительно Oracle JRE.
Не то что прокачали, а запилили совсем новый тип сборщика — C4 gc, а это и компиляцию особую требует.

F>Комерческих альтернатив рантайму .net я не знаю. Вдруг запилит кто-нить?

Это дорого, и совсем не выгодно, т.к. нет ниши, а нет ниши — пилить никто не начнёт, да ещё и закрытость фреймворка создаёт проблемы стартапщикам.
Изначально надо было вкладываться. В Яве изначально было направление — write once, run everywhere. Хоть это и обсмеяли, чуда не случилось, но это дало хороший пинок в правильном направлении для развития платформы.

F>·>Это понятно. Суть в том, что на .net нелья не погрязнуть.

F>Что значит погрязнуть?
Написать эффективный код для low latency.

F>·>Не волнуйся, когда .net умрёт, это закончится.

F>Думаю, это никогда не закончится...
C++ vs Pascal закончился же. А такие холивары были...
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[20]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 19.08.16 11:18
Оценка:
Здравствуйте, ·, Вы писали:

·>Не волнуйся, когда .net умрёт, это закончится.



Кстати из новостей Microsoft .Net Core после масштабного обновления будет поддерживать процессоры ARM

Кстати раз проект умирающий, зачем Самсунг в него прётся?
Announcing .NET Core 1.0

Samsung joins the .NET Foundation

Increased interest in .NET Core has also driven deeper engagement in the .NET Foundation, which now manages more than 60 projects. Today we are announcing Samsung as the newest member. In April, Red Hat, Jet Brains and Unity were welcomed to the .NET Foundation Technical Steering Group.

“.NET is a great technology that dramatically boosts developer productivity. Samsung has been contributing to .NET Core on GitHub – especially in the area of ARM support – and we are looking forward to contributing further to the .NET open source community. Samsung is glad to join the .NET Foundation’s Technical Steering Group and help more developers enjoy the benefits of .NET.” Hong-Seok Kim, Vice President, Samsung Electronics.

The contributions from Samsung have been impressive. They have a great team of developers that have taken an interest in .NET Core. We’re glad to have them as part of the larger team.

и солнце б утром не вставало, когда бы не было меня
Re[21]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: · Великобритания  
Дата: 19.08.16 14:12
Оценка:
Здравствуйте, Serginio1, Вы писали:

S> Кстати раз проект умирающий, зачем Самсунг в него прётся?

Он не умирающий, он застывший в росте, попал в нишу и оттуда ему не вылезти в обозримом будущем. Как ПХП. Туча низкоквалифицированой работы и низкие зарплаты.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[22]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 19.08.16 20:39
Оценка:
Здравствуйте, ·, Вы писали:

·>Здравствуйте, Serginio1, Вы писали:


S>> Кстати раз проект умирающий, зачем Самсунг в него прётся?

·>Он не умирающий, он застывший в росте, попал в нишу и оттуда ему не вылезти в обозримом будущем. Как ПХП. Туча низкоквалифицированой работы и низкие зарплаты.
То есть Samsung вкладывает деньги, что бы топтаться на месте? Кстати какие там ЗП в Самсунге?
А что, в Java исключительно высококвалифицированная работа и огромные зп у джуниоров?
и солнце б утром не вставало, когда бы не было меня
Re[23]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: · Великобритания  
Дата: 20.08.16 14:22
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>>> Кстати раз проект умирающий, зачем Самсунг в него прётся?

S>·>Он не умирающий, он застывший в росте, попал в нишу и оттуда ему не вылезти в обозримом будущем. Как ПХП. Туча низкоквалифицированой работы и низкие зарплаты.
S> То есть Samsung вкладывает деньги, что бы топтаться на месте? Кстати какие там ЗП в Самсунге?
Так себе зарплаты, и качеством софта самсунг отличается не в лучшую сторону.

S>А что, в Java исключительно высококвалифицированная работа и огромные зп у джуниоров?

Джуниоров я не сравниваю. Зачем о них вообще говорить? Джуниорами работают недолго.
Не "исключительно", а можно найти довольно много высококвалифицированной работы с соответствующей зарплатой. В отличие того же php или .net.
Вот факты:
http://www.indeed.co.uk/jobs?q=java+Software+Developer+%C2%A3100,000&amp;l=London&amp;jt=permanent
http://www.indeed.co.uk/jobs?q=.net+Software+Developer+%C2%A3100,000&amp;l=London&amp;jt=permanent
В первом случае 26 позиций, больше половины похожи на правду.
Во втором 7, притом только две более менее совпадают с C#Dev, остальное не очень понятно как попало в список.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[24]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 20.08.16 17:06
Оценка:
Здравствуйте, ·, Вы писали:

·>Здравствуйте, Serginio1, Вы писали:


S>>>> Кстати раз проект умирающий, зачем Самсунг в него прётся?

S>>·>Он не умирающий, он застывший в росте, попал в нишу и оттуда ему не вылезти в обозримом будущем. Как ПХП. Туча низкоквалифицированой работы и низкие зарплаты.
S>> То есть Samsung вкладывает деньги, что бы топтаться на месте? Кстати какие там ЗП в Самсунге?
·>Так себе зарплаты, и качеством софта самсунг отличается не в лучшую сторону.

Да только продает больше всех. Я к тому, что если бы было все шоколадно, то Самсунг бы и не посмотрел в сторону .Net Core.
.Net на самом деле развивается, просто не такими темпами как хотелось бы. Но например C# развивается достаточно интенсивно.
и солнце б утром не вставало, когда бы не было меня
Re[25]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: · Великобритания  
Дата: 20.08.16 20:06
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>>> То есть Samsung вкладывает деньги, что бы топтаться на месте? Кстати какие там ЗП в Самсунге?

S>·>Так себе зарплаты, и качеством софта самсунг отличается не в лучшую сторону.
S>Да только продает больше всех. Я к тому, что если бы было все шоколадно, то Самсунг бы и не посмотрел в сторону .Net Core.
Продают барахло больше всего китайцы. Но это не значит, что работать программистом на китайцев выгодно.

S>.Net на самом деле развивается, просто не такими темпами как хотелось бы. Но например C# развивается достаточно интенсивно.

Темпы развития JVM тоже не отличаются стремительностью. Java сама вообще считается жутким динозавром (хотя мне кажется что так и надо, ибо язык дружелюбный к IDE важнее, чем примочки языка).
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[26]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 21.08.16 05:24
Оценка:
Здравствуйте, ·, Вы писали:

·>Здравствуйте, Serginio1, Вы писали:


S>>>> То есть Samsung вкладывает деньги, что бы топтаться на месте? Кстати какие там ЗП в Самсунге?

S>>·>Так себе зарплаты, и качеством софта самсунг отличается не в лучшую сторону.
S>>Да только продает больше всех. Я к тому, что если бы было все шоколадно, то Самсунг бы и не посмотрел в сторону .Net Core.
·>Продают барахло больше всего китайцы. Но это не значит, что работать программистом на китайцев выгодно.
Потому, что их много. А вот из крупных компаний только АлиБаба
S>>.Net на самом деле развивается, просто не такими темпами как хотелось бы. Но например C# развивается достаточно интенсивно.
·>Темпы развития JVM тоже не отличаются стремительностью. Java сама вообще считается жутким динозавром (хотя мне кажется что так и надо, ибо язык дружелюбный к IDE важнее, чем примочки языка).

Ну вроде как и C# c VS прекрасно дружат. И VS тоже развивается. Тот же UWP, .Net Native, .Net Core
и солнце б утром не вставало, когда бы не было меня
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.