Как стать автором
Обновить

Комментарии 45

Кажется MS явно дали понять что C# и XAML для обычных приложений, а C++ и DirectX для хардкора. Для пущего хардкора писать библиотеки на C++ а потом использовать их в C#.
А если хочется C# и DirectX? Без сторонних библиотек вроде SharpDX это невозможно. XNA безусловно хорош, но он устарел и скорее мертв, чем жив.
Основная идея в том, что нужно меньше добавить в C#, чем убрать из C++, чтобы полностью задействовать возможности подобной интегрированной системы, увеличить продуктивность разработчика и без сопутствующих потерь производительности.

Мне кажется, что при добавлении всех перечисленных фич (если их вообще можно добавить с учетом обратной совместимости и минимального сохранения идеологии C# и .Net) C# станет не менее запутанным чем С++.
Вроде C# был сделан для бизнес-приложений, а не для сложных и медленных расчётов. А в них нет разницы, открылось окошко за 0,1 с или за 0,2 с.
С таким подходом, когда всем плевать на производительность (и иногда дизайн) бизнес приложений, не удивляйтесь, что в мире существуют миллионы человек, ненавидящих свою работу.
Не утрируйте. В любом программном продукте на производительность плевать в определённых пределах. Если для игр этот предел в районе 0,1 секунды, то для бизнес-приложений достаточно и 0,5 с. Если у ПО (любого) отзывчивость не удовлетворяет данным требованиям, то тогда нужно оптимизировать.
Верно, верно. Причем, речь же не идет о разнице в 1-2 секунды. Когда там десятые доли — ничего страшного.

P.S. Единственное, где даже такие задержки недопустимы — аэрокосмические технологии. Но там и подход вообще в корне другой.
А какой там подход?
Там самый что ни на есть real-time нужен. Там нет временных решений, нет компромиссов, и уж тем более никто не жертвует производительностью в пользу удобства разработки. Нет задачи универсальности/мультиплатформенности. И все должно работать просто идеально.

На Хабре проскакивало несколько интересных статей на эту тему — всецело советую для ознакомления.
НЛО прилетело и опубликовало эту надпись здесь
открытие окна за 0,2с != плевать на производительность
JIT производит недостаточные оптимизации в сравнении с C++ -O2, потому что он должен генерировать код очень быстро (также, в отличае от Java HotSpot JVM, .NET JIT не может на лету подменять существующий код на более оптимизированный).

до генерации нативного кода, компилятор уже производит многие оптимизации MSIL.

Типы .NET, такие как Array, всегда делают проверку границ при доступе (не считая простых циклов, где JIT может убирать проверки, если условие завершения цикла меньше или равно длине массива).


VS->Project Settings->Build->Optimize code.
VS->Project Settings->Build->Configuration->Release

в mono это также отключаемо.

Сборщик мусора останавливает все потоки во время сборки (хотя новый сборщик мусора в .NET 4.5 в этом отношении несколько улучшили), что может приводить к непредсказуемым падениям производительности.

смотрим, мою недавнюю статью на тему GC.

облачный компилятор


compiler as service — это еще понятно, но ОБЛАЧНЫЙ???

Легковесное взаимодействие с нативным кодом:

как быть с недетерминированным управлением памяти с GC и C++? проблема еще не решена.
может быть CXXI, но там также есть ограничения.

Также очевидно, что WinRT не предоставляет продвинутые оптимизации, когда мы используем его API.


как может API (!!!) оптимизировать код, его использующий???

Векторизованные типы (вроде float4 в HLSL)


уже есть! MS Research Accelerator v2
Типы .NET, такие как Array, всегда делают проверку границ при доступе (не считая простых циклов, где JIT может убирать проверки, если условие завершения цикла меньше или равно длине массива).

VS->Project Settings->Build->Optimize code.
VS->Project Settings->Build->Configuration->Release

в mono это также отключаемо.

Не уверен. Есть статья на эту тему.
Хорошо бы чтобы при unsafe { } не делалась проверка границ.
здесь существует небольшая грань — либо проверка границ явная (и оптимизация возможна), либо ситуация типа:
for (int i = a.Length - 1; i >= 0; i--)

где как программисту цикл понятен, но не компилятору (ибо компилятор обрабатывает только обобщенные ситуации).

так следует использовать IEnumerable с включенной оптимизацией (т.к. границы не проверяются).

если по mono, то презентация mono for game developers (слайд #39).

и да, O2 — не панацея, т.к. можно приводить к гейзенбагам.
и, кстати, при unsafe не делается проверка границ (!!!).
Ой, я ошибся. Я имел ввиду чтобы делалась :)
В загашнике у MS компиляция C# сразу в нативный код.
Для меня .NET — это прежде всего клей, позволяющий совместно использовать разные библиотеки и языки без написания бесконечных переходников и обёрток. Какая платформа способна предложить мне такой клей? Я такой платформы не знаю.

Производительность .NET меня полностью устраивает.
я вас здесь поддерживаю и клей — прекрасная метафора)
Но я не пишу высокопроизводительных вещей, вы, наверное, тоже)))
Это клей в своей песочнице, склеивающий только *# языки + один внешний C++

Хотя нельзя не согласиться, что библиотек красивых к нему приклеили немало…
Что то много в последнее время всяких авторитетных людей, пророчащих смерть/разорение/полосу неудач другим людям и их творениям…
Не знаю, где вы усмотрели разорение и полосу неудач. Я вижу только желание более активного развития и улучшения.
В фразе ".net должен умереть" © Кэп
Автору спасибо за перевод, кстати. А то сейчас частенько ужасные переводы начали мелькать в ленте (и даже на главной)
Каждый вызов метода в WinRT — это виртуальный вызов, который обязательной пойдет через таблицу виртуальных методов (а в некоторых случаях требуется несколько виртуальных вызовов, когда например используется статический метод). Простейшие чтение-запись свойства потребуют виртуального вызова. Это явно неэффективно.


Заявление автора про «явную неэффективность» — подтасовка фактов. Виртуальные функции, конечно, будут вызываться медленнее невиртуальных. В абсолютных числах. Но если посмотреть накладные расходы в тактах на вызов функции и на то, что эта функция делает (а функции ведь что-то делают?), то непосредственно вызов будет ничтожно малой величиной. Профайлинг усредненного приложения (а я их много профайлил) показывает накладные расходы на выовы функций 1-2%. Это не та неэффективность, о которой имеет смысл говорить :).
Хочу добавить по поводу оптимизации вызовов виртуальных методов. В 1993 году вышел язык программирования Self, виртуальная машина которого поддерживала JIT компиляцию (первый в мире JIT компилятор). Self — это динамически типизированный язык, основаный на прототипах. Язык очень динамический. Например, там даже доступ к полям объекта происходит только через посылку сообщений, плюс штатная возможность менять иерархию наследования объекта, плюс множественное наследование. В общем, в Self есть куча особенностей затрудняющих создание эффективной реализации VM.

В результате работ над Self-90 и Self-93 оказалось, что у того около 25% всех точек вызовов являются не мономорфными, а полиморфными. То есть, местами где значительное число сообщений посылаются объектам разных классов. Для ускорения работы таких случаев используется polimorphic inline cache (PIC). При этом, в скомпилированном машинном коде кешируется некоторое ограниченное (например 5) число найденных методов. Скомпилированный код при этом может выглядеть так:

if (object->class == #A) goto #A::m;
if (object->class == #B) goto #B::m;
goto #system_lookup;


Количество сравнений увеличивается только при необходимости, то есть для мономорфных точек вызова эффективность будет точно такая же, как при простом inline cache. Если список классов переполняется, то какой-то из наличных закешированных методов заменяется новым. То есть PIC значительно теряет в эффективности в мегаморфных точках вызова. Т.е. в точках где класс объектов меняется часто. Но, к счастью, таких мест незначительное количество. PIC перекочевал в современные виртуальные машины: Java, Visual Works Smalltalk, др.

Технологии PIC уже почти 20 лет. Так что говорить о «медленности» виртуальных вызовов уже не модно. Хороший JIT компилятор должен уметь оптимизировать такие вызовы на лету.
(по материалам smalltalk.ru)
а .net умеет?
да умеет, но только компилятор C# с его dynamic. советую почитать мою статью на эту тему.
по-моему, здесь немного путают PIC (предназначенный для кэширования эквивалентных по своей сигнатуре методов в динамических языках) с виртуальными методами.
если рассматривать статические языки, то для их виртуальных методов есть немного другие техники.
Ееееееееее, это прекрасно, если снова будет модно делать нативные приложения.
А вообще, .NET не так уж и плох — его виртуальная машина не сильно уступает нативному коду (за исключением повышенного потребления памяти). И уж явно лучше стековой явы.
А в .net разве не стековая виртуальная машина?
«Лучше явы» по причине отречения от явовского принципа работы на многих, очень многих платформах. А когда я не могу нормально писать на С# под *nix — нафиг оно мне надо? Нет, конечно, если Вам не нужно ничего, кроме Win, то это безусловно лучший инструмент.
Можете. Mono вам в помощь.
И как оно с WinForms, м?
www.mono-project.com/WinForms

Support for Windows Forms 2.0 is complete. At this point, we are largely just fixing bugs and polishing our code.
Спасибо, классно. Правда до меня доходили слухи со сложностью в отношении winforms на других платформах в смысле возможных притязаний microsoft.
боюсь вас огорчить, у .net нет виртуальной машины. промежуточный код компилится на лету в нативный.
O RLY? Я огорчен скорее тем, что есть такие комментарии.
ок. ступил. голова забита была всякими глупостями.
Автор путает LINQ выражения с лямбда-выражениями.
Прочитал в оригинале(кстати, почему нет ссылки на него?), тоже ничего не понял, почему он предлагает синтаксический сахар для делегатов, взамен не имеющей к ним отношения функциональной части языка.
Опять же синтаксис есть и так, то есть можно написать var a = B, где B это, например void B(){} такой метод класса.
Не хватает не синтаксиса, а его имплементации — компилятор ругается, что нельзя это делать implicitly, ибо автоматически тип делегата не создается (что, если я не напутал, автор предлагает реализовать, попутно упомнув всуе wpf), его надо декларировать самостоятельно.
Я так понял, что он не только про методы говорит, а про свойства также например, на них действительно нельзя сделать ссылки без создания делегатов, которые возвращали бы их значения. А ссылка на оригинал есть в стандартном месте (не знаю как точно называется, панель под статьей).
Ссылка на оригинал находится там же, где и у всех остальных топиков-переводов на хабре — имя автора в панели под постом.

Что касается предлагаемого автором синтаксиса, то тут скорее имелись в виду не ссылки на методы и свойства для их вызова, а специальные конструкции вроде атрибутов, которые можно использовать в метапрограммировании. Т. е. symbol myMethod — это не делегат и даже не MethodInfo, а нечто новое, что например можно использовать для анализа или генерации кода во время JIT компиляции. Это позволит заменить строки с названиями свойств в реализации INotifyPropertyChanged на строготипизированные ссылки на свойства, проверяемые во время компиляции. Также такие ссылки можно использовать в сценариях, в которых сейчас используются PropertyInfo, FieldInfo и прочие MemberInfo из System.Reflection. Ну и теоретически производительность подобных символов должна быть по-лучше отражения, где-то на уровне делегатов в последних версиях .net.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Изменить настройки темы

Истории