Pull to refresh

Comments 484

Анализ конечно хороший в статье, но я почувствовал огромный скептицизм и недооцененность в сторону C#.
На мой взгляд, анализ крайне субъективный, и автор вместо конкретных примеров просто переозвучил распространенные стереотипы: C++ побыстрее (и не такой страшный, как кажется), а C# поудобнее (но не настолько удобнее, как кажется).
Анализ безусловно субъективный, но основан на практике по большей части. Я хотел не вдаваться в частности, а предоставить общее видение ситуации. Можно было бы детальнее расписать пункты с конкретными примерами, но думаю это сильно бы утяжелило статью.

У меня действительно есть некоторый скептицизм относительно C#, возможно он вызван завышенными ожиданиями от С# ранее.
Я понимаю, что болшая часть Windows разработчиков аудитории сайта, предпочитают C# в силу тех или иных причин, я и сам недавно его предпочитал.
Но я хотел бы зародить сомнения в том, что C# является столь перспективным и показать некоторую недооцененность
С++, сложившуюся за последние 5-10 лет.
Вот как раз с перспективами у C# (и вообще .net) все неплохо, учитывая, что под перспективами вы понимаете параллельные вычисления, а в .net над этим активно работают.
Параллельные обработки часто упираются в синхронизацию и доступ к ограниченным ресурсам. И тут становится крайне важным быстро обрабатывать такие ситуации, что требует оптимизации. А поскольку возможности по оптимизации managed кода ниже, вполне возможно что это станет узким местом, избавиться от которого можно только перейдя на unmanaged решения.
Параллельные обработки часто упираются в синхронизацию и доступ к ограниченным ресурсам. И тут становится крайне важным быстро обрабатывать такие ситуации, что требует оптимизации

… или перехода на решения с минимумом синхронизации. На десктопе это, правда, в меньшей степени критично, на мой вкус, но тут вообще все очень занятно даже с банальной точки зрения «а зачем нам столько производительности».
Мне кажется минимум синхронизации возможен только в очень изолированных задачах (чисто математичаских например). Однако даже в чистой математике сложно обойтись без ввода-вывода данных, то есть без коммуникации с другими потоками или ресурсами ввода вывода.
Далее, если говорить о приложениях для пользователя — всегда есть метрика отзывчивости приложения на ввод пользователя. В таких ситуациях многопоточность может больше мешать чем помогать, ведь в пределе для максимально быстрого отклика (в виде результата, а не в виде прогрессбара) лучше иметь один поток с максимальным доступом к ресурсам, чем несколько толкающихся друг с другом потоков.

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

А тем не менее, сейчас такие решения активно используются для LOB-приложений.

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

Пожалуйста, не путайте отзывчивость (т.е., скорость отклика приложения на действия пользователя) с производительностью (т.е., скоростью получения им результата).
Посмотрим какую долю и какого рынка займут LOB-приложения.

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

Уже заняли, стопроцентную. LOB — line-of-business, приложение, выполняющее основные задачи предприятия.

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

Существуют. Но сколько их в процентах от всего ПО?
Все таки интересно какого именно рынка заняли 100% долю LOB приложения.

Относительно частоты задач где очень желательна быстрая реакция приложения: CAD область, работа с музыкой и видео, веб браузеры, терминалы ввода данных, игры, думаю кстати что если из проектов по созданию дополненой реальности что-то выстрелит — то там определенно реакция будет критична.

Какой процент таких задач в ПО? Возмонж не очень большой, но далеко не нулевой. И если критично избежать ощущения тормознутости приложения, эти задачи придется решать…
Все таки интересно какого именно рынка заняли 100% долю LOB приложения.

Рынка приложений для бизнеса, очевидно. Как игры заняли 100% рынка игр.

Относительно частоты задач где очень желательна быстрая реакция приложения: [...] веб браузеры, терминалы ввода данных

В браузерах и терминалах ввода данных есть I/O, которое доминирует (должно доминировать) над процессорным временем. И здесь — с точки зрения скорости реакции — платформа, которая умеет нативно (и прозрачно для программиста) работать с IOCP в ощутимом выигрыше.
Я несколько знаком с приложениями для бизнеса, но среди известных мне бизнесов, нет использующих LOB приложения. Из этого могу сделать вывод, что далеко не любому бизнесу они нужны.

Можете охарактеризовать сегмент, в который позиционируются LOB приложения? Есть ли примеры внедрений? Было-бы интересно узнать…
Я несколько знаком с приложениями для бизнеса, но среди известных мне бизнесов, нет использующих LOB приложения. Из этого могу сделать вывод, что далеко не любому бизнесу они нужны.

Серьезно? Ни один известный вам бизнес не использует ERP? CRM? Бухгалтерию в любом виде? Систему управления складом? Интернет-магазин? Систему управления проектами? Систему управления задачами?
Я наверное не правильно понял, что вы имеете ввиду под LOB-приложениями. Мне показалось что вы имели ввиду какието специфичные приложения построенные на специфичных технологиях.Я никогда раньше не слышал этот термин, хотя знаком со всеми остальными перечисленными вами терминами.

Правильно ли я понимаю, что это термин чисто маркетинговый, и не связан с какими-то конкретными решениями или технологиями.
Расскажите что именно он значит?
Это просто «в любые приложениях для бизнеса» или что-то другое?
Я же вам сразу написал:

LOB — line-of-business, приложение, выполняющее основные задачи предприятия.


en.wikipedia.org/wiki/Line_of_business:

In the context of computing, a «line-of-business application» is one of the set of critical computer applications perceived as vital to running an enterprise.
Спасибо, понятно) Это видимо достаточно широкий термин.

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

Кстати, особенно неприятны ситуации где синхронизацию избегают там, где делать этого нельзя, тогда проблемы начинают вылезать случайным образом в зависимости от производительности железа и сетевых задержек. (это чуть-чуть офтопик, но наболело)
Спасибо автору. Помогло «окинуть » взглядом основные отличия.
Хотя не сказано было про отладку кода, здесь то разбежка в скорости будет существеннее.
Пожалуйста.Про отладку я написал в п.5 что С# тут безоговорочно лучше до тех пор пока не нужно отлаживать Mixed код.

Вообще забавно что единственный чисто позитивный комментарий жестно заминусован.

Да, я знаю что фанаты С# и Microsoft могут болезненно отнестись к некоторым моим рассуждениям и их количество тут не в пользу моих рассуждений, но я пишу не с целью троллить фанатов, а с целью задуматься о перспективах как С++ так и С# и в конечном счете о перспективах наших приложений и нас в свете их развития.
Я не являюсь фанатом ни того ни другого. И уважительно отношусь к обоим языкам.
Я сам разработчик в области прикладного и web. Владею навыками как С++ так и шарпа, но прикладное разрабатываю – так уж сложилось на делфях.
Для меня чужое мнение о выборе языка не является конечно решающим, но считаю полезным для общего просвещения прочесть материал от человека имеющего опыт разработки в обеих сравниваемых им языках.
Выбор инструмента зависит от задачи. Нельзя сравнивать два языка по отношению к абстрактному проекту. И да, некоторые аргументы в статье достаточно спорны.
Например, странно писать обычное ui-приложение на плюсах под винду, также как и на шарпе кроссплатформенную игру под андроид и айос.
также как и на шарпе кроссплатформенную игру под андроид и айос

Тысячи их, на фреймворке Unity
Не только Unity. MonoGame тоже используется.
Я сам использовал и Xamarin, и MonoGame, и могу вас заверить, что это не лучшее решение.
Я же не отрицаю, что нельзя, можно и на плюсах обычное ui-приложение наваять, но этот инструмент не для таких задач.
А вот банковский клиент на Xamarin под три платформы — самое то.
Может потому, что моногейм не лучшее решение, а не Xamarin? Знаю несколько игр, написаных на Xamarin (не MG) которые работают очень шустро (и новые фичи в них добавляются очень быстро сразу на все платформы ибо C#).
Части .net framework, python и lua написаны на C/C++. Это что-то меняет по отношению к обсуждаемому вопросу?

на шарпе кроссплатформенную игру под андроид и айос

Я вас порадую (а может, и огорчу): xamarin.com.
xamarin все же не самый лучший выбор для игр
UI-приложения бывают разные. Например если это CAD (или другое ресурсоемкое приложение), то исключительно на шарпе он будет очень неэффективный (медленный и часто прожорливый).
Бывает такие приложения сводится к компромисному решению, когда в одном приложении собирается нативный код для рендеринга и ресурсоемких задач, а C# для UI.
Все это приводит к Mixed коду который отлаживать часто хуже чем нативный C++ код. Про частные проблемы с Mixed кодом можно написать достаточно много, но это за рамками статьи.
WPF в Autocad так та…
Странное заблуждение по части прожорливости — не плодите объекты бездумно и все будет ок.
Такими темпами можно и до ассемблера опуститься. Вот еще на почитать — Numeric performance in C, C# and Java
Уверены?
forums.autodesk.com/t5/tag/Qt/tg-p www.nixp.ru/news/10377.html да и среди вакансий есть псециалисты по Qt
Autocad перепилена на WPF
Чуть точнее — на WPF в нем добавлен рибон и кнопка «пуск» + несколько _новых_ диалогов написаны на WPF. Больше WPF там нет. Примечательно, что далеко не все новые диалоги с 2009 года были построены на WPF. И разумеется к рендерингу сцены WPF не причастен вообще.
Одновременно используется одна из новых возможностей упрощенного хостинга Direct3D сцен в рамках приложения для той части, где визуализируются создаваемые модели.


Только сейчас весь гугл закакан туториалами о том как хостить WPF в автокаде во всех возможных местах) Если научились делать игры на C# так что GC не мешает, то уж UI нарисовать — не проблема. В целом, я бы на вашем месте обсуждал тему десктопных приложений на JS, так как в 90% случаев C#+Java не оставят шансов C++ на сервере и клиенте(ИМХО).

Хостинг WPF для сцены в Автокаде не используется. Максимум для превью в тултипов, но это вряд-ли можно назвать хостингом Direct3D сцен.

Насчет игр, пока не видел тяжелых 3D игр на C#, все(что я знаю) топовые 3D игры — исключительно С++. Если у вас есть примеры релизов чего-нибудь уровня GTA4,5\Fallout\Battlefield на C# — очень хотелось бы увидеть, напишите пожалуйста.

Десктопные приложения на JS я бы вряд-ли ожидал. Я не спорю, что например на связке HTML+JS и правильном подходе можно достичь производительности не многим меньше чем на связке WPF + C#, но все-таки для interoperability JS мне кажется плохой вариант, да и инфраструктура JS библиотек недотягивает ни до С# ни до С++ в области за пределами написания веб клиентов.
У вас есть исходники Автокада?

C# for Gaming
«Тяжесть игры» это что? Если вы про рендер — то спору нет. Но тут и C++ не всегда хорош) Если про логику — то разницы особой нет. Вон на Unity шлепают фигалионы игр. Как Мигель договорится то и в UE появится поддержка C#.

C# прекрасно уживается вместе с C++ как в движках так и в тулинге и на серверах.

ORLY?
Atom, VS Code нативные приложения в Win на XAML+JS?

Зачем исходники, когда есть дизассемблер, Spy++ и reflector ?:)

Под тяжестью конечно рендер в первую очередь имею ввиду.

Atom, VS Code нативные приложения в Win на XAML+JS — не встречался с этим. не могу судить, если есть примеры приложений обещаю посмотреть.
Я не берусь судить весь их codebase по Spy++ )

Редкое использование C# в рендеринге в первую очередь из-за необходимости RAII и нежелательности доп. интеропа. Тут уж разные платформы и особо ничего не попишешь(разве что Unsafe, но расходы на интероп остаются)
Но и тут уже есть прогресс — Paradox 3D Engine Trailer
Paradox Game Engine. Плюс не списывайте со счетов .Net native. Поглядим еще как пойдет ;)

Активно педалируемая тема — берем V8 и хостим в него наше приложение на JS — Profit.
Редкое использование C# в рендеринге в первую очередь из-за необходимости RAII и нежелательности доп. интеропа.

Это тоже правда, но знаете, мне тут как-то попалась библиотека для чтения и рендера DWG написанная на .net (конкретно вот эта: https://www.woutware.com/cadlib/4.0)
Интерес ее в том, что она действительно работает с файлом и рендерит его на .net

И вот она открывала не очень сложный DWG значительно медленнее AutoCAD-а, разница была многократной. WPF рендеринг в библиотеке работал ужасно медленно, впрочем как и GDI+ рендеринг (обычные pan\zoom безбожно тормозили)

Единственный рендеринг работающий в ней более менее достойно был рендеринг с помощью OpenGL, он хотя и строил сцену дольше остальных но зато потом работал с ней довольно быстро. При этом именно он был написан через импорты opengl32.dll, то есть по сути и не был .net овским.

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

Помню еще в 2005 году были библиотеки для разработки на C# 3D приложений, но с тех пор прошло 10 лет, а любая графика чуть потяжелее как писалась на С++ так и пишется, врядли это иррационально.
Вы не думали что просто через одно место написана? Можно и на C++ Написать так, что будет ползать.
Вот небольшой пример — Debunking C# vs C++ Performance

У C++ нет явных преимуществ без RAII и возможности работы с памятью. Небольшой оверхед есть из-за рефлекшена, но он же иногда помогает компилятору лучше оптимизировать код чем на C++. Плюс советую посмотреть .Net Native.

С++ нишевое решение для специфических задач, где необходим очень жесткий контроль ресурсов, да и то при большом желании — unsafe в помощь.

В общем можете почитать достаточно подробные ответы на SO — C++ performance vs. Java/C#

>Вы не думали что просто через одно место написана?
Никакой другой .Net библиотеки решающей ту же задачу я не нашел. Вообще.

>Вот небольшой пример — Debunking C# vs C++ Performance
Это же чистая синтетика в вакууме, работающая сама с собой.
В реальных же задачах нужно достаточно часто работать с системой, где и случаются основные провалы у С# на маршалинге

>.Net Native.
Интересно. Пара глупых вопросов по нему: как его потом дебажить? И можно ли заставить студию строить прямо в него, а не в IL?

>В общем можете почитать достаточно подробные ответы на SO — C++ performance vs. Java/C#
Кажется читал как-то, но ссылка хорошая, спасибо.
И? Причем тут выводы о быстродействии .Net на основе левой либы?

Это пример, показывающий что говнокодить можно везде, и вы, возможно сталкивались с этим. Делать выводы на основе этого — глупо.

Google

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

>И? Причем тут выводы о быстродействии .Net на основе левой либы?
Я видел и другие библиотеки .net, которые не поразили меня своей производительностью.

Например возьмем WPF, вы тоже скажете что это пример говнокода?
Если нет, то почему у нее такая низкая производительность?

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

Или например WPF рибон, в каком-нибудь автокаде или вашем приложении. Почему переключение между табами идет так долго?

А если взять какую-нибудь библиотеку WPF контролов, например DevExpress, то там с производительностью все будет еще раза в 2 хуже.

Вы можете сказать что C# в этом не виноват, что .net в этом тоже не виноват.
Хорошо, а кто тогда виноват в столь низкой производительности WPF?
Если вас интересует отладка — Debugging support for .NET Native Preview apps

С чего вы взяли что у WPF низкая производительность? На нем например пишется софт для трейдеров в Дойче Банке ЕМНИП?

Вы серьезно? Для начала соберите свой софт без флага Debug ;)

Не берите DevExpress. Возьмите Telerik или напишите свое.

Вы серьезно думаете что в медленном переключении табов виноват .Net? Еще раз — если вы сталкивались с посредственными результатами — не означает, что .Net медленный. Это то же самое, что сказать — C++ медленный, так как игры на нем тормозят.

>С чего вы взяли что у WPF низкая производительность?
Из собственной практики, я даже примеры привел.

>На нем например пишется софт для трейдеров в Дойче Банке ЕМНИП?
Я очень сильно этому удивился. Может это попил какой-то…

>Telerik
Вполне возможно он заметно быстрее DevExpress, но базовую тормозню WPF он вряд-ли уберет.

>Если вы сталкивались с посредственными результатами — не означает, что .Net медленный
Не подскажите альтернативную UI библиотеку под .net без проблем с производительностью?
Ваша практика — контрол от DevExpress?

Попил в Дойче — это даже не смешно.

Еще раз повторю — торомозит не WPF, а товарищи, пихающие в ObservableCollection миллион записей по одной.

>контрол от DevExpress
У DevExpress медленно работали Tabbed groups, Grid, Property Grid

Чего там в Дойче я не знаю, но у меня тормозит именно WPF, например у моем обычном wpf датагриде нет никаких ObservableCollection, но как только там появляется больше 1000-2000 элементов он начинает тормозить.

Я его профайлил — тормозит обход дерева визуальных элементов и многократные вызовы Measure.Я незнаю зачем так часто и в таком количестве мерить ячейки грида, но я знаю что мой код в этом процессе не вызывался.
Еще раз — как тормоза DevExpress относятся к .Net? И еще раз — тестить производительность надо без флага Debug.

Может надо понять почему он тормозит при 2000+ элементах? У нас в админке по 10к+ транзакций без тормозов показываются, а у вас простой грид тупит. Может искать проблему в своем коде?

Вот ответ на ваш вопрос — Performance issue with “Measure”

Обычный баг для которого уже давно есть хотфикс. При чем тут .Net то? Как лишние вызовы метода стали являться мерилом производительности платформы?
Спасибо конечно, но эти фиксы не помогают. Проблема с вызовом UIElement.Measure вылезает даже на последних версиях фреймворка, где все фиксы уже включены.

Вероятно что то недофиксили и забили, как это принято в Microsoft :(
Или вы криво построили дерево контролов, проводите лишние модификации дерева.

Может перестанете кидаться голословными утверждениями? После того как вы сделали вывод о тормозах .Net по частому вызову метода Measure в WPF — я бы рекомендовал вам внимательно присмотреться к своему коду.
WPF MeasureOverride called multiple times after multiple PropertyChanged notifications
Optimizing Performance: Layout and Design

Да тут собственно и дерева то нет. Я же говорю, только обычный родной WPF датагрид. В нем штук 10 колонок, некоторые из них на основе DataTemplate c одним простым контролом (комбобоксом или datetime picker или numericupdown из codeplex) внутри, остальные колонки стандартные.

Из своего кода только установка ItemSource обычным листом из 1000-2000 элементов и xaml разметка.

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

Код смотрели многократно — нету там ничего особенного.
Как нет? Вы точно понимаете как устроен WPF? У кого Measure то дергается? В ответ на какое событие?

Если это грид DevExpress — то к ним и пишите на форум. Опять же WPF и .Net То тут каким местом?

Не поленился, скачал демку Telerik — 1 млн. записей отфильтровались за ~400ms и плавно скролятся.

Кроме грида на форме ничего не было, поэтому дерево только грида.
Measure дергается по всей видимости для ячеек грида в ответ на попытку скролить содержимое.

Это стандартный датагрид WPF.

(C DevExpress отдельные проблемы)

Telerik вполне возможно работает лучше — не знаю — не пробовал…
Я сейчас сделал датагрид, в нем 10,000,000 элементов. И ничего не тормозит, виртуализация работает…



Какая точно была версия фремворка? Как вы добавляли элементы? Просто datagrid.ItemsSource = somelist? Что было внутри того контрола numericupdown смотрели? Как правильно заметил Razaz: Measure у какого элемента дергался и после чего? Если фреймворк был >= 4.5, то какой стоял VirtualizationMode?

Пожалуйста, покажите уже этот код. Хочу понять, что за мистика такая у вас.
А теперь заказчик хочет, чтобы слово Customer было зелёным, а номер за ним — красным. Для этого ячейка темплейтится и в template ставится два TextBlock. Вроде как после этого будет плоховато скроллиться
Не будет. Только если ты datatemplate selector применишь, или группировку к элементам и еще в некоторых случаях. А по умолчанию виртуализирует и показывает спокойно хоть миллионы элементов.
После TDBGridEh из дельфи, который стабильно даст 60fps при навигации, wpf-ные гриды оставляют плохое впечатление. Сложно объяснить, но как будто интерфейс лагает, уже в раздумьях не погоняешь Selection по строкам, потому что лаг отклика раздражает.
Кстати можете ради интереса попробовать UI из FLTK

Это кросплатформенная С++ библиотека, кстати разработка по ней вполне жива
www.fltk.org/index.php

Там конечно нельзя по-простому делать всякие WPF-овские красивости и нет биндингов, но UI написанный на ней крайне отзывчивый.
К сожалению, на плюсах никто не даст писать gui для enterprise ))
Интересно, почему?
Молодёжь не умеет писать на древних языках
Ну «даст/не даст» — это обычно начальство, а оно обычно не такое молодое и дерзкое.
gui обычно дают писать новичкам, начальство будет из этих соображений решать, на чём его писать
Это заведомо проигрышная стратегия, вне зависимости от языка.
Почему? Вместо нудного клепания тупых формочек и отчётов лучше дать новичкам нечто сложное и важное?
Потому что хороший интерфейс — это не тупые формочки и отчеты.
Есть масса типовых задач, таких как показать движения по счёту или вывести складские обороты. Интерфейс давно придуман — обычная таблица, ничего лучше не нужно.

Или есть такие скучные направления, как «зарплата и управление персоналом». Там в приложении куча списков сущностей и редакторов для них. Что там можно сделать хорошего и нетупого, кроме как поиграться расположением контролов, размером и цветом кнопочек?
Перевести с сущностно-ориентированной парадигмы на задаче-ориентированную, например. Внезапно выяснится, что это далеко не так скучно, как кажется.
Обычно пользователи привыкли работать по стандартам (и это в принципе нормально, годами проверенные способы работы) и от программиста не ждут, что он придумает новые подходы к работе, а если и придумает, скажут — не хотим нового, хотим привычного.
И будут неправы. Хотя, конечно, придумывать новые подходы должен не программист, а UX-дизайнер, но реализовывать-то потом все равно программисту.
В enterprise отзывчивость интерфейса стоит на одном из последних мест в списке приоритетов.
Ведь тот кто за него платит, и тот кто им пользуется — как правило абсолютно разные люди.
(я возможно немного драматизировал ситуацию, но думаю не сильно)
У меня на WFP 3.5 не было проблем с производительностью грида, 60FPS на современном (на тот момент) компе.

Если чето лагает надо запускать профайлер и смотреть что. Скорее всего перерисовка в несколько слоев.

ЗЫ. Не надо WPF запускать в RDP.
И… ничего не поменялось.
Спасибо, что попробовали воспроизвести.

>Какая точно была версия фремворка?
4.0 и 4.5

>Как вы добавляли элементы? Просто datagrid.ItemsSource = somelist?
да
>Что было внутри того контрола numericupdown смотрели?
Профайлер непосредственно этот контрол не дергал. В каком смысле что внутри?

>Measure у какого элемента дергался и после чего?
Больше всего времяни было кажется в базовой реализации Measure, могу уже не помнить

>Если фреймворк был >= 4.5, то какой стоял VirtualizationMode?
Все варианты VirtualizationMode были точно испробованы на 4.0 фреймворке.
На машинах с 4.5 это тоже не помогало. Специфичные только 4.5 режимы не использовались, т.к. нужна была поддержка 4.0

По вашему примеру, важно как минимум поменять:
1. Колонки должны быть не автогенеренные, а явно прописанные в xaml с указанным размером
2. Их должно быть хотябы 10 штук
3. Часть из них, доблжы быть типа datagridtemplatecolumn, c Combobox внутри
4. Колонки должны быть забинжены на данные
5. В гиде должны быть разрешены редактирование и сортировка
— возможно этого минимума хватить чтобы воспроизвести проблему

Можно еще добавить (хотя и не обязательно, и наверное не стоит вам тратить на это время):
1. Визуальные стили на лист
2. Конвертеры в биндинге
3. В идеале добавить datagridtemplatecolumn с datetime picker и numericupdown из codeplex
4. В datagridtemplatecolumn использовать разные темплейты для редактирования и просмотра.

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

В прямом, код смотрели? С учетом, что непонятно, как компонент написан.

Больше всего времяни было кажется в базовой реализации Measure, могу уже не помнить

Вот не понял, в базовой реализации чего и где? Откуда постоянно вызывались Measure и после какого события?

По вашему примеру, важно как минимум поменять:
1. Колонки должны быть не автогенеренные, а явно прописанные в xaml с указанным размером
2. Их должно быть хотябы 10 штук
3. Часть из них, доблжы быть типа datagridtemplatecolumn, c Combobox внутри
4. Колонки должны быть забинжены на данные
5. В гиде должны быть разрешены редактирование и сортировка

Добавил 10 колонок. Остальное и так все было. И ничего не поменялось.

Можно еще добавить (хотя и не обязательно, и наверное не стоит вам тратить на это время):
1. Визуальные стили на лист
2. Конвертеры в биндинге
3. В идеале добавить datagridtemplatecolumn с datetime picker и numericupdown из codeplex
4. В datagridtemplatecolumn использовать разные темплейты для редактирования и просмотра.

1-2. с конвертерами и стилями все ясно. я пытаюсь понять где был затык с Measure.
3-4. проверил с компонентами от Telerik, засунул и в CellTemplate и в CellEditingTemplate, и только в Editing — ничего.

В общем, я думаю что где-то у вас в коде зарылась ошибка. С виртуализацией такой DataGrid вообще не тормозит — визуальное дерево обновляется только для того, чтобы покрыть видимую область. А если поставить
VirtualizingStackPanel.VirtualizationMode="Recycling"
так и вообще визуальное дерево не меняется при перелистывании.
На самом деле, там регулярно упоминаются какие-то контролы с codeplex. В них вообще что угодно может быть.
>Остальное и так все было.
и datagridtemplatecolumn-ы были и биндинг на контролы в них?

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

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


i61.tinypic.com/f00uwo.png

Снапшута профайлера во время скроллинга вертикальным скроллером вверх и вниз. Лаги при этом страшные(без профайлера разумеется)

(почемуто у меня нормально картинка в пост не вставилась :( )
Да и еще проект тестовый, очень быстро набросан, кода почти нет

s000.tinyupload.com/?file_id=09607171972593390390

Воспроизводить так:
1. Запустить
2. Развернуть на полный экран (хотя должна развернуться итак на старте)
3. Подергать вертикальный скроллер ввер и вниз.
4. Наблюдать лаги отзывчивости UI на скроллер.
Перезалил скриншот профайлера, тот както плохо открывается

s30.postimg.org/4lvgfhrnl/Measure.png
В общемто тут нет ни темплейтных колонок, ни codeplex-а, ни стилей.

Тут вообще ничего нет, только сгенеренные данные, и достаточно много колонок (автогенеренные колонки я не выключал)

Виртуализация — включена.
Показываю код

s000.tinyupload.com/?file_id=09607171972593390390

Воспроизводить так:
1. Запустить
2. Развернуть на полный экран (хотя должна развернуться итак на старте)
3. Подергать вертикальный скроллер ввер и вниз.
4. Наблюдать лаги отзывчивости UI на скроллер.

А ниже можно еще найти скриншот профайлера.
Razaz, я выложил тестовый проект с тормозным гридом (на чистом WPF), и скриншот профайлера во время скрола. Можете посмотреть и вынести свое суждение относительно причин тормозни, былобы очень интересно узнать.
WPF в Autocad — да это реальность, но там есть и Windows Forms, и MFC даже на html+javascript некоторые контролы написаны.
Qt в виндовом Autocad я не замечал, но возможно они работают над тем чтобы уйти от зоопарка Microsoft контролов, кто знает…
Так или иначе, под MacOS есть своя версия Autocad и она написана не на UI от Microsoft.
Спору нет. Просто у них скорее всего ядро и морды для каждой платформы — под Win — скорее всего перепиливают на WPF+XAML. Ядро хоть на бэйсике можно написать, один фиг все будет слито на видеокарту для рассчета.
Дочитал до пункта про отсутствие сборки мусора в С++ и ринулся комментировать, извините.

1. Сборщик мусора в С++ НЕ НУЖЕН! Точка.
2. Если (ЕСЛИ!!!) сборщик мусора в С++ всё-таки нужен (прям необходим, ага, RAII для слабаков, дайте сборщик мусора, даже два), то этот самый сборщик мусора вполне можно реализовать самостоятельно. Т.к. самостоятельно реализовать сборщик мусора такой программист не сможет (такой — которому нужен сборщик мусора), то его можно взять из библиотеки Loki, например. Александреску не только с шаблонами извращается. Его вкусы могут показаться… хотелось вставить картинку про 50 оттенков, но лучше не буду.)

Пока писал комментарий, случайно прочитал пункт 9. Опровергну. На С++ можно скомпилировать приложение БЕЗ рантайма. Это будет извращение похлеще реализации сборщика мусора, но это возможно.

Добавлю ещё к выводу: С++ и С# это разные языки с разными задачами. Их бесполезно сравнивать. Вот замените цвет текста у кнопки на С++ и С#. А после нажатия на эту кнопку, производится поиск обратной матрицы размером 100000*100000. И какой язык для этого лучше? ;)
Меня больше всего поразило, записанный в минус отсутсвие глобальный процедур и функций в C#. Это огромный плюс. Это ООП, какие глобальные процедуры.
Пока до нас докатится C#6, много еще ждать. Поэтому пока о нем умолчим.
Он прекрасно работает даже при использовании .NET 2.0 в качестве целевого фреймворка. Я не вижу ни одной причины не использовать его уже сейчас и начал миграцию всех проектов ещё пару месяцев назад.
Ну напишите вы статический метод вместо глобальной функции, по сути — то же самое, зато «ООП».
> На С++ можно скомпилировать приложение БЕЗ рантайма. Это будет извращение похлеще реализации сборщика мусора, но это возможно.

Есть ещё один вариант: слинковать рантайм в свой бинарник, это очень просто, но имеет свои плюсы и минусы
в Qt замена цвета кнопки — плевое дело, ну а для матриц есть Eigen. Так что в данном сравнении C# проигрывает C++ по всем статьям.
Да, я несколько не корректно выразился. Разумеется, я имел в виду замену цвета текста кнопки на чистом WinAPI (к С++ вообще никакого отношения, (MF)Сишечный код).
Сборщик мусора нужен чтобы собрать эту статью
1. Может быть он и не нужен, но его отсутсвие влечет дополнительные требования к разработчикам, что так или иначе удорожает разработку.
2. Это хорошо.

На счет разних задач С++ и С# я соглашусь. Но вопрос в том где проходит линия раздела этих задач?
Ведь широкий круг задач успешно решаем и на С++ и на С# соизмеримым количеством времяни разработчика…
В задачах требующих высокой производительности, наличие gc наоборот усложняет разработку
Сильно зависит от задачи. И того, что понимать под производительностью (throughput или latency). В комментариях к этому топику их периодически путают.
А можно пример, какие задачи вы имеете ввиду? И какую производительность вы имеете ввиду?

Я видел несколько задач, в которых C++ «рулит»:
1) Числомолотилки, только в них не C++, а скорее C_с_классами. Да и рулит C_c_классами по одной причине — более крутые компиляторы, которые арифметику оптимизируют до невозможности. Использование любых фишек C++ (динамическое выделение памяти, stl и прочие радости) убивают быстродействие.
2) Всяческий embedded с очень ограниченными ресурсами, тут по понятным причинам надо контролировать каждый байт. Но такого embed_а все меньше. Устройства дешевеют и получают больше ресурсов. Пару сотен МБ уже не редкость, а на таких объемах даже JS работает.

Задачи в которых реально C++ рулит:
1) Визуальные редакторы, браузеры — любые десктоп-приложения с большим количеством объектов. Так как большинство GC не проектируются для работы с миллионами мелких объектов. Но и C++ тоже не сильно рулит, нужно много приседаний с кастомными аллокаторами, иначе стандартный механизм выделения памяти убивает все быстродействие
2) Там где нужно «пидарасить такты» — две известные мне задачи — разработка БД и HFT. Тут чем быстрее, тем лучше, достаточного быстродействия для таких задач не существует.
3) Всяческие COM-компоненты (плагины) для проводника, офиса, IE. Тупо уменьшают время загрузки.

Во всех остальных случаях востребованность C++ преувеличена.

Вкратце нужно просто посмотреть где «быстродействие» выше воспринимаемого человеком порога будет конкуретным преимуществом — там и нужен C++. В остальных случаях C# достаточно.

Хороший комментарий, отражающий давольно полно текущую ситуацию.
Я бы добавил еще один момент: кроме задачи стоящей в данный момент неплохо бы учитывать и перспективы приложения (что актуально в долгосрочных проектах и относительно крупных) — может стать что оно попадет например в одну из перечисленных категорий.
К счастью, не может. Такие вещи как базы, браузеры и hft не рождаются в процессе эволюции прикладных приложений, всякие плагины тоже. И вообще такие задачи редки, вот вы например что писали на c++?
Apache Cassandra? HBase? Hadoop?
Четкой линии водораздела не существует, выбор технологии решается для каждой задачи(проекта) отдельно. И для этого уж точно не нужно делать «анализ» на пятьсот пунктов. Если это конечно не троллинг ;)
Я часто сталкивался с ситуациями, где выбор падал на C#, даже без мысли относительно анализа и мне не кажется такой подход правильным.
С другой стороны, я сталкивался и с ситуациями, где С# проекты портировалисть на С++, хотя ранее выбор безоговорочно падал на C#.
Мне кажется портирование с C# на С++ может стать трендом будущих разработок.

Хотя конечно можете считать это троллингом:) Но я правда думаю что вероятность развития трэнда по переходу с С# на С++ достаточно высока.
Тренд по переводу проектов с шарпов на плюсы может возникнуть вследствие тренда бездумного выбора языка под проект. Сталкивался с ситуациями когда выбор падал на С++ просто «патамушта не люблю сишарп» или «не люблю языки с gc» или «проприетарщина отстой».
Видимо я сталкивался с ситуациями, где бездумно выбирали С# «патамушта можно писать быстрее», и вообще «все что надо есть».
И этот расчет был верен по своему. Если бы в 2000х годах производительность железа росла бы также как м в 90х, никаких С++ 0x мы бы не увидели. Но реальный рост производительности сильно замедлился…
Мне кажется портирование с C# на С++ может стать трендом будущих разработок.

Ох уж эти сказочки! Ох уж эти сказочники!

Вы как будто с другой планеты. Вряд ли заказчики будут платить за такое, дешевле докупить оперативки или уйти в облака, чем переписывать проект с одного языка на другой. Причем необходимость такая может понадобится только в реал-тайм системах требующих молниеносный отклик, но во первых такие системы скорей всего уже написаны на языке под конкретное железо, а если нет то их на столько малый объем, что назвать это портирование, с С# на С++, тредом язык не повернется сказать.

PS. Я все же допускаю, что вы из будущего. В котором к власти во всем мире пришел Тиран с фетишизмом к С++. Был издан закон об святой инквизиции неугодных языков.
Совсем не факт, что железо будет докупить дешевле. Например даже скромные +500$ на рабочее место в большой компании дадут десятки, а может и сотни тысяч, и это не говоря о потреблении энергии и других конкурентных преимуществах. А повально уходить в облака большие компании пока не торопятся…

Да и подумайте сами, что такое облако? Это в конечном счете это то же железо, но удаленное и в аренде, то есть проблемы с облаком те же, но лежат на компании которая держит облако и так или иначе будут отражены в стоимости аренды облака, а стоимость аренды будет влиять на затраты.

Таким образом перепись критичных к производительности компонентов вполне может стать экономический выгодной. Насчет «тренда», возможно я несколько преувеличил, но думаю что как минимум явление переписи библиотек с С# на С++ будет достаточно распространенным в будущем.
+500$ рабочее место(не знаю что за компания такая? со специалистами студентами?) * на количество месяцев потраченное на переписку продукта.
Как раз в современном мире как раз тенденция докупить железа. чем нанимать штат специалистов. Да еще и во время портирования не о каких новых фичах и быть не может, а бизнес к такому крайне скептично относиться.
Вы наверное неправильно поняли что я написал.
Я писал про затраты на железо в +500$ на рабочее место, а не про затраты на разработку. Затраты на разработку будут другими, но если разработчиком многократно меньше чем пользователей они вполне могут окупиться.

Да и по поводу переписи продуктов. Продукт может быть дешевле переписать, чем вообще остаться без ниши на рынке.
А какой смысл переписывать «библиотеку» с C# на С++? Большая часть внешних зависимостей в .net — инфраструктура, она ничего от этого не выиграет.
Зависит от интерфейсов библиотеки и того что именно делает библиотека.
Математика например слабо завязана ни инфраструктуру. Работа с файлами может сравнительно легко переведена на схожую C++ инфраструктуру. Работа с не-.net библиотеками «сама просится» к такому переводу.

Конечно для .net есть некоторая уникальная инфраструктура, но все-таки многое из .net инфраструктуры имеет адекватные аналоги для С++ (что не всегда верно в обратном направлении)
Математика например слабо завязана ни инфраструктуру.

И зачем переписывать математическую библиотеку с C# на C++ — на плюсах своих библиотек мало?

Работа с файлами может сравнительно легко переведена на схожую C++ инфраструктуру.

Весь «новый» I/O в .net сделан с учетом TPL, и переписать это на C++ (с сохранением внешнего интерфейса) просто не выйдет (точнее, будет неоправданно дорого).
И зачем переписывать математическую библиотеку с C# на C++ — на плюсах своих библиотек мало
Имеется в виду случай, если это ваша библиотека, которую разработали вы для ваших расчетов.

Весь «новый» I/O в .net сделан с учетом TPL
Проблема не в I\O, а в быстрой раскладке файла в тот вид с которым вы сможете работать.
Проблема не в I\O, а в быстрой раскладке файла в тот вид с которым вы сможете работать.

И это принципиально непотоковая задача?
При раскладке файла со ссылками между сущностными записанными в нем, часто нужно выполнять что-то вроде обхода сети.

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

Да и если все это удастся сделать, на потоках С++ параллельное решение все-равно будет работать быстрее…
Я не про те потоки, которые threads, я про те, которые streams — т.е., про чтение/запись файла.
Я чаще сталкивался с тем что производительность упирается не в скорость работы stream-a, а в скорость обработки прочитанного из него.

Поэтому и пишу что с файлами часто проблема в производительности обработки, а не в самом I\O.
Я чаще сталкивался с тем что производительность упирается не в скорость работы stream-a, а в скорость обработки прочитанного из него.

Ну вот а у меня в опыте ситуация обычно строго обратная (причем как в опыте программиста, так и в опыте пользователя). Отсюда и разница в подходах.
За время чтения с диска одного мегабайта можно около 1000 раз отсортировать этот мегабайт в памяти. Поэтому упереться в обработку можно только на очень маленьких файлах. Но тогда и время обработки очень маленькое будет.
Как правило, задачи стоят несколько сложнее чем сортировка мегабайта во время чтения.

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

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


Например?

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

Большинство алгоритмов архивирования потоковые, им не надо читать весь файл. То есть вполне можно разархивировать во время чтения.

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

Архивация — потоковый алгоритм, построение индекса — сортировка, которую за время чтения мегабайта можно успеть 1000 раз выполнить. Само чтение будет занимать малую долю только на очень маленьком файле. Но тогда вообще нет смысла говорить о времени работы.
Откуда вы взяли все эти цифры, как вы считали?
Почему вы пропустили этап создания объектов из прочитанных данных?
Потому что в среднем этот этап занимает пренебрежимо мало времени даже по сравнению с сетевом i/o, не говоря уже о дисковом.
Вот смотрите, HDD умеет отдавать данные со скоростью примерно 80 Mb/s, SSD так вообще 300 Mb/s, эта скорость вполне реальна если просто брать данные с носителя в память как есть.

И вы хотите сказать что сжатый структурированный структурированный поток данных распаковывается и раскладывается в объектную модель параллельно процессу чтения, с той-же скоростью? Если так, хотелось бы узнать, в каких именно задачах скорость обработки входного потока в 80 Mb/s-300 Mb/s вызывала проблемы?

И да, простой пример: по такой логике копирование архива и распаковка архива должны занимать почти одинаковое время, но это не так.
Вот смотрите, HDD умеет отдавать данные со скоростью примерно 80 Mb/s, SSD так вообще 300 Mb/s, эта скорость вполне реальна если просто брать данные с носителя в память как есть.

Только при последовательном доступе и если HDD/SSD не занят другими процессами. Если на сервере десятки приложений, sql база данных, nosql база данных и все терзают один жесткий диск, то цифры будут куда более печальными.

И вы хотите сказать что сжатый структурированный структурированный поток данных распаковывается и раскладывается в объектную модель параллельно процессу чтения, с той-же скоростью?

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

Если так, хотелось бы узнать, в каких именно задачах скорость обработки входного потока в 80 Mb/s-300 Mb/s вызывала проблемы?

Любые серьезные задачи интеграции, Big date и т.д. Из практики потоковое архивирование/разархивирование каким-нибудь gzip'ом выполняется намного быстрее чтения/записи неархивного файла.

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

Распаковка архива в памяти выполняется намного быстрее чтения с диска почти всегда (есть совсем уж медленные форматы, но их в интеграции не используют), основное замедление происходит когда пытаешься записать распакованный архив на диск.
> если HDD/SSD не занят другими процессами
Я именно об этом и говорю. Не надо занимать другими процессами — и у вас будет производительность, а если полезете в параллель — получите падение производительности везде, так как железо будет дольше переключаться, чем передавать вам данные. (кстати с SSD ситуация лучше в этом плане)

> Базы данных, интеграция, любые высоконагруженные приложения ВСЕГДА утыкаются в скорость чтения с диска
Я разбирал другой пример. Упакованный структурированный файл, который нужно разложить в объектную модель, а не storage базы данных формата оптимизированного до такой степени, что времени на его обработку практически не требуется. Конечно там будет все упираться в железо.

>Распаковка архива в памяти выполняется намного быстрее чтения с диска почти всегда (есть совсем уж медленные форматы, но их в интеграции не используют), основное замедление происходит когда пытаешься записать распакованный архив на диск.
Я согласен с тем что сравнение с копированием не совсем корректное, если объем распакованных данных много больше упакованных.

Но мы можем упаковать например какой-нибудь divx\xvid AVI — он практический не сожмется, поэтому разницы времени записи между копированием и распаковкой не будет. Однако почему-то он будет дольше распаковываться, чем просто копироваться…
Упакованный структурированный файл, который нужно разложить в объектную модель, а не storage базы данных формата оптимизированного до такой степени, что времени на его обработку практически не требуется. Конечно там будет все упираться в железо.

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

HDD 80МБ в секунду? Да вы оптимист, реально для HDD рассчитывать на 10мб в секунду в лучшем случае. А ssd вам еще никто не даст, все SSD давно под sql server задействованы.

10МБ в секунду не означает, что мы секунду ждем, в потом 10мб обрабатываем. Мы читаем 100КБ, а пока ждем буфера обрабатываем предыдущие 100КБ прочитанных.

То есть суммарное время при потоковой обработке растет незначительно.

И да, простой пример: по такой логике копирование архива и распаковка архива должны занимать почти одинаковое время, но это не так.

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

При копировании файла используется как раз потоковая модель, поэтому суммарное время возрастает не сильно (если диски разные).
>HDD 80МБ в секунду? Да вы оптимист, реально для HDD рассчитывать на 10мб в секунду в лучшем случае.
У меня HDD без проблем выдает 80МБ в секунду. Мне сложно представить где взять HDD, который выдаст только 10мб в секунду. Если только по USB 1.1 его подключить :)
Если так, хотелось бы узнать, в каких именно задачах скорость обработки входного потока в 80 Mb/s-300 Mb/s вызывала проблемы?

Чтение нежатого видео с диска. Чтение большого PSD с диска. Сканирование большого объема фотографий в поисках нужного тега.
>Чтение нежатого видео с диска.
Тут упремся в железо без вариантов. Если есть возможность видео лучше пожать.

>Сканирование большого объема фотографий в поисках нужного тега.
Есть смысл построить индекс на теги. Или хотябы испрользовать SSD, на HDD это будет работать более-менее быстро только на втором поиске, когда он прокэшируется.
Тут упремся в железо без вариантов. Если есть возможность видео лучше пожать.

Что камера отдала, с тем и работаем.

Есть смысл построить индекс на теги.

Есть-то есть, только индекс (а) тоже надо построить, это время и (б) он все равно будет ограничивающим фактором по скорости.
>Что камера отдала, с тем и работаем.
можно попробовать брать поток в память прямо с камеры по USB\Firewire (или как она подключается), сжимать и уже потом класть на диск…

>Есть-то есть, только индекс (а) тоже надо построить, это время и (б) он все равно будет ограничивающим фактором по скорости.
Индекс конечно решение неоднозначное. Если сканирование нужно проводить всегда для разных множеств фотографий — то лучше наверное просто взять SSD и все.

А если надо многократно сканировать надо одни и теже фотографии, которые могут немного меняться, то индекс должен бы окупиться, если правильно прописать его обновление.
можно попробовать брать поток в память прямо с камеры по USB\Firewire (или как она подключается), сжимать и уже потом класть на диск…

И мы будем ограничены в скорости сразу двух I/O, круто.

А если надо многократно сканировать надо одни и теже фотографии, которые могут немного меняться, то индекс должен бы окупиться, если правильно прописать его обновление.

Да какая разница, окупится ли он, достаточно того, что все равно скорость работы будет ограничена скоростью I/O, а не вычислений.
>И мы будем ограничены в скорости сразу двух I/O, круто.
Я не вижу вашей задачи полностью. Но если I/O камеры заметно быстрее чем I/O диска, то при надлежащем сжатии(если мы его потянем по cpu) мы будет ограничены только I/O камеры, так как количество данных для записи на диск станет многократно меньше и его I/O с этим легко справится.
И это разумеется позволит работать быстрее чем с диском.

Но все это только в случае если I/O действительно быстрее I/O диска.

>Да какая разница, окупится ли он, достаточно того, что все равно скорость работы будет ограничена скоростью I/O, а не вычислений.
Да, разумеется, но в этой задаче, и вычислений то особых нет, тут в основном только I/O и выполняется…
Типичная задача «открой видеоредактор и смонтируй что-нибудь». Но, собственно, вы просили привести пример, когда I/O — ботлнек. Вот вам их несколько не напрягаясь.

И я сегодня весь день на них натыкаюсь.
Такие задачи тоже бывают конечно, в основном при обработке сырых данных.

Кстати, если вы не выжимаете предельную скорость из вашего HDD, то С++ думаю помог бы ее выжать. А если выжимаете и так, то тут либо другое железо поможет, либо читать можно какнибудь с уровнем детализации «через кадр» (в несжатом стриме наверное достаточно просто пропустить кадр или несколько и добрать их когда они будут очень нужны)
Кстати, если вы не выжимаете предельную скорость из вашего HDD, то С++ думаю помог бы ее выжать.

Вот это ваше «думаю» — оно на чем основано? Почему вы думаете, что другие языки на это не способны?
С++ будет работать через меньшее количество прослоек, как с I/O так и с памятью, куда это I/O положит данные, это может помочь.

ReadFileEx например можно вызывать и из C# по
[DllImport(«kernel32.dll»)]
static extern bool ReadFileEx(IntPtr hFile, [Out] byte [] lpBuffer,
uint nNumberOfBytesToRead, [In] ref System.Threading.NativeOverlapped lpOverlapped,
ReadFileCompletionDelegate lpCompletionRoutine);

Но я честно говоря не уверен что byte [] lpBuffer отмаршалится без дополнительных издержек.

А нативные стримы С# до ReadFileEx идут через несколько оберток, чтобы убедиться — возмите рефлектор и посмотрите на реализацию System.IO.FileStream.Read, там давольно много возможно лишнего для вашего случая кода, до того как вызывается

[DllImport(«kernel32.dll», SetLastError=true)]
internal static extern unsafe int ReadFile(SafeFileHandle handle, byte* bytes, int numBytesToRead, IntPtr numBytesRead_mustBeZero, NativeOverlapped* overlapped);

Вы сможете сделать это вызов без выполнения этого кода, кроме того вы возможно сможете избежать вызова
Buffer.InternalBlockCopy(this._buffer, this._readPos, array, offset, byteCount);
в System.IO.FileStream.Read

Я незнаю сколько именно это добавит производительности в процентах, но точно знаю что прочитать файл на С++ можно меньшим количеством исполняемого машинного кода, чем будет выполнено в System.IO.FileStream.Read

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

Но самый, конечно, интересный вопрос — это какую именно долю производительности при потоковом чтении я буду терять на всех упомянутых вами «обертках».
Собственно говоря в ReadFileEx есть OVERLAPPED чтение и lpCompletionRoutine
msdn.microsoft.com/ru-ru/library/windows/desktop/aa365468(v=vs.85).aspx

Что, как я понимаю, тоже позволит активировать ваш обработчик.

На счет доли производительности… Смотря как часто этот код выполняется, чем чаще, тем больше будет доля…
Собственно говоря в ReadFileEx есть OVERLAPPED чтение и lpCompletionRoutine
msdn.microsoft.com/ru-ru/library/windows/desktop/aa365468(v=vs.85).aspx

Что, как я понимаю, тоже позволит активировать ваш обработчик.

Ну, во-первых, нет, completion routine — это не IOCP (что, кстати, показывает, что вы с этим не работали). А во-вторых, каково количество прыжков и ужимок, которое мне на это понадобится, по сравнению с простым async/await-кодом в C#?

Смотря как часто этот код выполняется, чем чаще, тем больше будет доля…

А вот и нет. Если время выполнения обработчика чанка будет значительно меньше времени чтения следующего чанка с диска, то общее время обработки будет лишь слегка превышать общее время чтения (если быть точным, на время обработки одного чанка). Просто потому, что я буду обрабатывать предыдущий чанк во время чтения следующего.

Если, конечно, выполняемая операция — потоковая.
>Ну, во-первых, нет, completion routine — это не IOCP (что, кстати, показывает, что вы с этим не работали).

C IOCP я и правда не работал — необходимости в этом не было… видимо имеется ввиду это
msdn.microsoft.com/ru-ru/library/windows/desktop/aa363862(v=vs.85).aspx

>А во-вторых, каково количество прыжков и ужимок, которое мне на это понадобится, по сравнению с простым async/await-кодом в C#?
Это уж вопрос к тому насколько вам принципиально написать этот кусок (чуть?) быстрее. Безусловно прыжков и ужимок будет больше, но это будут ваши прыжки и ужимки, о которых вы точно будете знать что они делают, а не прыжки и ужимки дотнета.

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

А это одного порядка вещи. Вы настолько же не знаете, что внутри себя делает ReadFile, насколько я — как именно ReadAsync делает свое волшебство.

Я имел ввиду количество вызовов необходимых для инициализации чтения чанка.

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

Нет, ну правда, сколько процентов от времени чтения мегабайтного чанка будет занимать оверхед? А десятимегабайтного?
>А это одного порядка вещи. Вы настолько же не знаете, что внутри себя делает ReadFile, насколько я — как именно ReadAsync делает свое волшебство.

C одной лишь разницей,- я знаю что ReadAsync(и любое другое дотнетовское чтение файла) в конечном счете вызовет ReadFile

>Нет, ну правда, сколько процентов от времени чтения мегабайтного чанка будет занимать оверхед? А десятимегабайтного?
При больших чанках процент очень малый. И если в работе с памятью оверхеда не будет, то смысла в переходе на С++ конкретно для этой задачи мало.
C одной лишь разницей,- я знаю что ReadAsync(и любое другое дотнетовское чтение файла) в конечном счете вызовет ReadFile

Ну да… наверное. В той версии, в которой вы посмотрели. Вы не знаете (а) с какими параметрами (б) от чего они зависят (ц) что будет в следующей версии (д) что будет на соседней платформе. И самое главное — вы все равно не знаете, что внутри ReadFile.

При больших чанках процент очень малый.

А малыми на таких задачах никто и не читает. Что, собственно, и показывает нам некоторое преувеличение важности C++.
ReadFileEx например можно вызывать и из C#

А думаешь FileStream.Read делает что-то сильно другое? Он проверяет состояние стрима, вызывает ReadFileCore, который уже вызывает нативную функцию.
Смотри сам referencesource.microsoft.com/#mscorlib/system/io/filestream.cs,9d70a9236f810fcb

Думаешь в STL обвязок меньше? Или ты под каждую платформу свои нативные методы вызываешь в кроссплатформенном языке?

Но я честно говоря не уверен что byte [] lpBuffer отмаршалится без дополнительных издержек.
А я уверен, тупо буфер пинится (выставляется флаг) и передается указатель.

Я незнаю сколько именно это добавит производительности в процентах, но точно знаю что прочитать файл на С++ можно меньшим количеством исполняемого машинного кода, чем будет выполнено в System.IO.FileStream.Read

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

Короче не думай что ты умнее людей, которые писали .NET, особенно BCL. Это не так с вероятностью 100%.
>А думаешь FileStream.Read делает что-то сильно другое?
Нет, не сильно, просто машинного кода в нем будет исполнено больше во время этого вызова

>Думаешь в STL обвязок меньше? Или ты под каждую платформу свои нативные методы вызываешь в кроссплатформенном языке?
В простом чтении из файла обвязок меньше. Еще меньше обвязок в вполне кросплатформенном fread.

Но конкретно IOCP в STL нет.
Возможно только в Boost.Asio будет что-то подобное.
Я думаю IOCP лучше прописать под каждую платформу, т.к. IOCP платформо-зависимая фича, которая в таком виде есть только в Windows, на других платформах есть схожие, но другие фичи.

Опять таки, реализация IOCP в Mono будет совсем другой и по всей видимости обернута еще большим количеством кода.

>Короче не думай что ты умнее людей, которые писали .NET, особенно BCL. Это не так с вероятностью 100%.
Я не спорю, конкретно BCL — действительно хорошо написан, но часто он решает более общую задачу чем требуется, что будет всегда немного отжирать дополнительного времени в рантайме.

Чем C++ поможет при работе с диском?
1. Сборщик мусора в С++ НЕ НУЖЕН! Точка.

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

Добавлю ещё к выводу: С++ и С# это разные языки с разными задачами. Их бесполезно сравнивать. Вот замените цвет текста у кнопки на С++ и С#. А после нажатия на эту кнопку, производится поиск обратной матрицы размером 100000*100000. И какой язык для этого лучше? ;)
Очевидно C, без плюсов ;)
Статья ниочем, аж 11 пунктов из пальца высосаны.
как-то на тостере я сравнивал оба языка ( toster.ru/q/80210#answer_262418 ) Прошел год, мое недовольство C# возросло, но для справедливости надо сказать, что используется устаревшая версия 3.5, на плюсах пишу для души с использованием последнего стандарта (C++14)

Хотя нельзя не отметить, что рефлексия это очень удобно и общение с БД в шарпе сделано лучше, чем тем ORM-библиотеки что я пробывал в свое время.Но на этом все.

Кстати, рефлексию обещают добавить в C++17, а сделать на основе этого удобную сеарилизацию и ORM уже труда не составляет. Так что это преимущество шарпа вскоре может быть съедено.

В итоге мой выбор это плюсы вот в такой связке: gcc 4.9 (на clang пару раз наскакивал, да в боевом режиме пока не пробовал — не сравнивал) + Qt + Boost + qbs + doxygen

Но на этом все.

Небесконечное время компиляции, отсутствие .h-файлов, несравнимая по человечности отладка и диагностика ошибок, LINQ в целом и применительно к БД и XML в частности, лямбды, итераторы, async/await, Unicode.
Будто в С++ нет лямбд, итераторов и юникода. Можно хоть по-русски, кроме здравого смысла никто слова против не скажет. async в новом стандарте подтягивают.
Про лямбды и итераторы сказал тут по соседству, а про Юникод даже не смешно. Думаю, было понятно, что Юникод должен поддерживаться не на уровне

ВыходнойПоток << "Меня зовут " << имя;

а таки на уровне поддержки его стандартной библиотекой и рантаймом. И вот тут все становится ожидаемо печальным.
в STL: wstring, u16string, u32string — все есть, все прекрасно.

В Qt Qstring поддерживает из коробки. Что вам еще надо?
в STL: wstring, u16string, u32string — все есть, все прекрасно.

Вы, наверное, издеваетесь:

typedef basic_string<char16_t> u16string


Что «прекрасного» есть в std::basic_string? Про Юникод она знает чуть меньше, чем ничего: ни Code Point'ов, ни графем, ни нормализации. Как «класс строка» она нежизнеспособна.
Ну и в string BP C# этого нет, а то, что вы хотите есть в ICU, Boost.Locale или Qt
В utf16 же не бывает суррогатных пар, правда?
Отношение к суррогатным парам неоднозначное, вот Javascript их не поддерживает
Какое может быть неоднозначное? Если используется utf16 и нет поддержки суррогатов — то unicode в полной мере не поддерживается.
LINQ-ORM, о нем уже говорил
.h -файл это большуй плюс к самодокументированности, мне не нужно пролистывать тысячи строк кода, чтоб понять с чем едят этот класс. Мое мнение — наличие .h -файлов это огромный плюс. Проблемы с сигнатурами в разных файлах решает IDE. Вот например в QT Creator написал сигнатуру объявления, нажал ALT+ENTR и пишишь код определения в cpp-файле.

Итератор в C# это вообще что-то:

var e = list.GetEnumerator()
и тадам e.Current ==null, а чтобы получить первое значение нужно сказать e.MoveNext(). Кто мне сможет чем разработчики руководствовались?
Если сказ про foreach — то уже в C++11 он есть, да и стандартный после введения auto уже не проблема
Лямбды — тоже есть, причем я могу укзать тип захвата: по ссылке или по значению. Если мне нужно захватить по значению в лямбде, то начинается стандартные проблемы с глубоким клонированием. Но это пол беды, беда начинается тогода, когда мне надо захватить по ссылке что-то из struct…

Async\await тыщу лет нету проблем в Qt и Boost, а как довесок — у них есть гораздо удобне организован проброс сигнала, в том числе в другой поток. Базу уже подтянули в стандарте

var e = list.GetEnumerator() и тадам e.Current ==null, а чтобы получить первое значение нужно сказать e.MoveNext(). Кто мне сможет чем разработчики руководствовались?

Тем, что (а) итератор может быть пустым и (б) первое значение еще сто лет может быть никому не нужно.
Если итератор пустой (сиречь ссылается на пустую коллекцию) то в C++ он равен end и проблем никаких. Получить итератор и не начать проход по коллекции — нарушение принципа объявление переменной там где это надо. но не раньше.

Поясню чуть шире: допустим мне по какой-то причине не подходит foreach и я вынужден использовать for,
Пишем такой код:
for (var iterator = list.GetEnumerator(); iterator.HasNext(); iterator.MoveNext()){
Обработка
}
На основе опыта, основанного на доступе по индексу я ожидаю, что если я попал в тело цикла, то для начало работы с элементом мне больше телодвижений делать не надо нарушается. Причины такой логической нестыковки не понятны.
Если итератор пустой (сиречь ссылается на пустую коллекцию) то в C++ он равен end и проблем никаких.

… кроме необходимости его на это проверить.

Получить итератор и не начать проход по коллекции — нарушение принципа объявление переменной там где это надо. но не раньше.

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

Пишем такой код:
for (var iterator = list.GetEnumerator(); iterator.HasNext(); iterator.MoveNext()){
Обработка
}
На основе опыта, основанного на доступе по индексу я ожидаю, что если я попал в тело цикла, то для начало работы с элементом мне больше телодвижений делать не надо нарушается. Причины такой логической нестыковки не понятны.

Просто ваш опыт здесь не применим (а должен быть?). В вашем коде есть две ошибки: (а) у итератора нет HasNext и (б) типизованные итераторы реализуют IDisposable, который надо не забыть обработать.

Enjoy:
using(var iterator = list.GetIterator())
{
  while(iterator.MoveNext())
  {
    //обработка
  }
}
>>Просто ваш опыт здесь не применим (а должен быть?).
Согласен, что да. может и не быть. Но это не упрощает написание кода, а только усложняет.

>> (а) у итератора нет HasNext
Посыпаю голове пеплом.

>>… кроме необходимости его на это проверить.
using(var iterator = list.GetIterator())
{
while(iterator.MoveNext())
{
//обработка
}
}
Да-да, но получается, что используете цикл с предусловием в любом случае, не всегда это идет коду на пользу. Ну и сама конструкция разрастается в монстра, если у меня коллекция из коллекций.

Иными словами, основной мой посыл: «работа с итераторами в C# проще, чем в C++» требует серьезных примеров.
Согласен, что да. может и не быть. Но это не упрощает написание кода, а только усложняет.

Это проблемы вашего опыта, а не C#/.net.

Да-да, но получается, что используете цикл с предусловием в любом случае, не всегда это идет коду на пользу.

«В любом случае» я использую foreach. Я просто показал вам, как решить вашу конкретную задачу.

Иными словами, основной мой посыл: «работа с итераторами в C# проще, чем в C++» требует серьезных примеров.

Вот вам один простой пример:

IEnumerable<ValidationError> Validate()
{
  if (Name == null) yield return ValidationError.FromProperty("Name");
  if (Text == null) yield return ValidationError.FromProperty("Text");
  if (Price < 0) yield return ValidationError.FromProperty("Price");
}


(да, я знаю, что есть валидационные библиотеки, атрибуты, блаблабла, но рано или поздно вам надо написать какой-то кусок такого кода руками)
>>Вот вам один простой пример:
М-да, тостер не торт, увы…

>>Это проблемы вашего опыта, а не C#/.net.
И да и нет. Да — это проблема моего опыта, тут спора нет. Но это и проблема и C#, т.к. нарушение общего стиля увеличивает количество ошибок в коде новичков, а мы вроде как хотим это избежать.
И да и нет. Да — это проблема моего опыта, тут спора нет. Но это и проблема и C#, т.к. нарушение общего стиля увеличивает количество ошибок в коде новичков, а мы вроде как хотим это избежать.

Нет никакого «общего стиля». Есть конкретный стиль C#, в котором итераторы обрабатываются единообразно, и там у новичков проблем нет. А если кто переучивается с другого языка, то это его дело — не тащить в новый язык нерелевантный опыт из старого.
В одном и том же языке схожие сущности должны обрабатываться схожим образом. Именно это понимаю под общим стилем. Индекс в цикле это такой же итератор.

Но ниже дали совсем схожий код. Так что и тут в целом серьезных вопросов нет
Индекс в цикле это такой же итератор.

Упс, нет. В этом ваша ошибка. Индекс в цикле — это не итератор (по крайней мере, в C#), это отдельная парадигма.
Индекс — это произвольный доступ. Он (предположительно) имеет сложность O(1), он повторяем, вы (обычно) можете как прочитать, так и записать элемент.

А перечислитель (раз уж мы полезли в терминологические тонкости) — это последовательный доступ, с непредсказуемой сложностью, и (в конкретном .net) — без возможности записи, т.е., вам выдали элемент из последовательности, и повлиять на саму последовательность вы не можете никак.
А так?
for (var iterator = list.GetEnumerator(); iterator.MoveNext();){
    ...
}

А, например, OData? Тот же LINQ, но поверх HTTP.

.h-файл — атавизм, который адепты C/C++ пытаются всячески оправдывать; пользы от них — ни на грош. а мороки — уйма: те же разъезжающиеся сигнатуры, нарушение DRY и вообще масса способов отстрелить разные куски комиссарского тела. (И позвольте, к слову, заметить, что класс «в тысячи строк кода» — явный антипаттерн; но да что уж). Так вот все современные IDE для современных статически типизированных языков умеют замечательно показывать публичный контракт класса вместе с документацией.

Про итератор сказали уже, но вообще странно слышать претензии к простым и понятным .NET'ным итераторам от C++-разработчика с зоопарком begin(), end(), iterator, reverse_iterator и т.д. И вообще — Iterators Must Go.

Лямбды с Dangling Reference'ами прэлэстны, право слово.

Ну и сравнивать библиотечную подпорку для асинхронного программирования в C++ со встроенной в C# поддержкой оного — несколько за гранью
>> А, например, OData? Тот же LINQ, но поверх HTTP.
не знал, можно по-подробнее?

>>И позвольте, к слову, заметить, что класс «в тысячи строк кода» — явный антипаттерн; но да что уж
В патерне MVVM Visual Model, как правило, наиболее сложный класс, где зачастую функционал легко разбивается на приватные методы, а вот развал их на классы может привести лишь к неоправданной усложнению.

>>.h-файл
Итого я сказал, что проблемы с оными решаются средствами IDE, вы сказали, что проблемы без оных решается средствами IDE. Концептуально баш на баш.
>> Про итератор сказали уже, но вообще странно слышать претензии к простым и понятным .NET'ным итераторам от C++-разработчика с зоопарком begin(), end(), iterator, reverse_iterator и т.д.
Я программирую и на том и на том. Что до итераторов в C++, то я не вижу там зоопарка, begin\end и const их вариации логично и понятно и использование. Что до зоопарка, то не вижу в этом проблем ( www.cplusplus.com/reference/iterator ) все особенности диктуются особенностями коллекции. Знаю и понимаю коллекцию => знаю и понимаю работу итераторов без лишнего напряга памяти.

>> Лямбды с Dangling Reference'ами прэлэстны, право слово.
Если ссылка повиснет, то в 90% случаев вы получите сегфолт при попытке вызова. А вот если вы в C# периодически добавляете лямбды, в качестве обработчика сигнала, то вы получаете тихую утечку памяти. Но и то и то на самом деле в рамках языка не являются проблемой, т.к. это ключевые особенности языка, которые должен отслеживать программист.

>> Ну и сравнивать библиотечную подпорку для асинхронного программирования в C++ со встроенной в C# поддержкой оного — несколько за гранью
Честно говоря async\await не пробывал и не по своей вине, но судя по этой ( habrahabr.ru/post/139734 ) статье разница в опыте с С++ ровно ноль:
Код вызова:

Task task = new WebClient().DownloadStringTaskAsync(«microsoft.com»);
task.Wait(); // Здесь мы ждем завершения задачи, что блокирует поток
TextBox.Text = task.Result;

Аналог в C++, например с Qt
auto task = QtConcurrent:run([&]()={WebClient().DownloadStringTaskAsync(«microsoft.com»)})
task.wait();
TextBox.Text = task.result();

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

Код вызова:
Task task = new WebClient().DownloadStringTaskAsync(«microsoft.com»);
task.Wait(); // Здесь мы ждем завершения задачи, что блокирует поток
TextBox.Text = task.Result;

Вот оно и видно, что не пробовали. Так на TPL писать противопоказано. Вот правильный вариант:

//на время вызова существующий поток, скорее всего, будет "отпущен" и сможет выполнять другие задачи
TextBox.Text = await new WebClient().DownloadStringTaskAsync(«microsoft.com»);


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

Вот только задачи (Task) в TPL — это не обертка над потоками, а абстракция уровнем выше, поэтому ваше рассуждение тут немного не применимо.
>>Вот оно и видно, что не пробовали. Так на TPL писать противопоказано. Вот правильный вариант:
Благодарю, добавил в избранное. Действительно проще.
>> Вот только задачи (Task) в TPL — это не обертка над потоками, а абстракция уровнем выше, поэтому ваше рассуждение тут немного не применимо.
Ну так и future это тоже абстракция уровнем выше.
Ну так и future это тоже абстракция уровнем выше.

По факту, future (скажем, в Scala) и task в TPL — это одно и то же.
И это только подтверждает мое утверждение, что в реализациях различий минимум. кстати, сейчас думаю, а можно ли конструкцию с await также элегантно сделать в плюсах. Но, покапавшись в доке
код на плюсах:

TextBox.Text = QtConcurrent:run([&]()={WebClient().DownloadStringTaskAsync(«microsoft.com»)}).result();
Можно сделать макрос:
#define await (func) QtConcurrent:run([&]()={func}).result()
и тогда код такой же, что и в C#
TextBox.Text = await (WebClient().DownloadStringTaskAsync(«microsoft.com»));

Вы не понимаете.

await в C# — это не синтаксический сахар к task.Result (который, в свою очередь, ведет себя так же, как QFuture::result()). Ваш макрос приведет к тому, что поток, в котором идет выполнение, будет заблокирован до получения результата из future. А await выпихивает весь остаток метода в continuation, причем аккуратно захватывая используемые объекты и следя за жизненным циклом.

(в этом, собственно, различия между реализацией во внешней библиотеке и поддержкой на уровне языка)
Понял. Согласен, это очень удобно. Для плюсов аналог еще надо придумать.
Утро вечера мудренее. На Qt это проблема решается, с единственным условием — после выполнения вызова кода поток попадает в цикл событий. Думаю, что для C# это тоже должно быть справедливо. Итоговый синтаксис будет выглядеть как-то так:

TextBox.Text << await (WebClient().DownloadStringTaskAsync(«microsoft.com»));

Есесно await определен существенно иначе, чем я делал до этого
Здесь есть ровно один важный вопрос: что происходит с потоком, в котором мы находимся до вызова этой строчки?
Вопроса не понял, что может происходить с потоком до того как вы сделали вызов?
Я имею в виду: вот у нас шел вызов метода до написанной вами строчки, он был в каком-то потоке. Вы вызвали ваш await — что стало с потоком?
Так это все-таки после. А ничего не происходит, поток не блокируется и продолжает исполняться, но в конце-концов должен попасть в цикл событий
А что в нем исполняется?
в нем это где? в потоке или цикле событий?
Для начала — в потоке.
Поток есть поток, как он дошел до вы зова не важно. Поток вызывает метод асинхронно и продолжает любую свою работу. По завершению асинхронной задачи он выстрелит сигналом в исходный поток. Этот сигнал попадет в очередь событий потока исходного.

Чтоб извлечь его надо попасть в цикл событий. Цикл событий это стандартный для Qt QEventLoop: бесконечный цикл с очередью событий, который он потокобезопасно извлекает.

Возможно, данный пример не совсем корректен, т.к. я представлял не проперти, а поле, т.е. переменную, у которой можно получить указатель.

Чтоб получить указатель на функцию, похоже, придется чуток повозиться, вытанцовывая вокруг std::function и, возможно, синтаксический сахар станет чуть горше. Но это надо обдумать.
Поток вызывает метод асинхронно и продолжает любую свою работу.

Что значит «поток вызывает метод»? Нет такой операции, поток может либо выполнять какой-то код, либо не выполнять его (сидеть в пуле).

Нет, я серьезно вас не понимаю.

void someFunc()
{
//some code
//мы в потоке 1
TextBox.Text << await (WebClient().DownloadStringTaskAsync("http://microsoft.com")); //что стало с потоком 1? какой конкретно код он выполняет? куда делся код, находящийся ниже по функции?
//some code
}
Мы выполняем операцию асинхронно, т.е. мы входим в тело макроса await, делает ряд подготовительных приседаний, а после вызова QtConcurrent:run мы выходим из макроса; дальше исполняется код ниже по тексту
Код «ниже по тексту» выполняется после завершения await или до него? Если после, то за счет чего останавливается выполнение кода между «до» и «после»?
WebClient().DownloadStringTaskAsync(«microsoft.com») выполняется в отдельном потоке. он не ждет родительский от слова вообше, Он может быть выполнен как «до» захода родительского в somecode, так и «после». Значение TextBox.Text будет инициализировано только после того, как попадет в eventloop, а попасть он может черт знает где: как в самом somecode, так и после него.
Code1();
TextBox.Text << await (WebClient().DownloadStringTaskAsync("http://microsoft.com"));
Code2();


В какой момент будет выполнено обращение к сайту по отношению к Code1 и Code2? Из ваших слов у меня создается ощущение, что после Code1, но в произвольный момент по отношению к Code2 (т.е., в том числе и после выполнения Code2). Я правильно вас понял, или как-то иначе это устроено?
Ну да, асинхронный вызов предполагает же, что основная работа идет в другом потоке со всеми вытекающими. Или я не прав?
Вы просто не понимаете, как работает async/await в C#. Там в аналогичном коде гарантируется строгая последовательность вызовов (Code1 — обращение к сайту — Code2), при этом на время обращения к сайту вызывающий код не блокируется, а полностью останавливается, не занимая потока, а само обращение, если оно правильно построено, тоже не блокирует поток на время собственно работы сетевого вызова.

Собственно, это позволяет делать вот такие прекрасные вещи:
var page  = await GetPageFromWikipedia(someterm);
var terms = page.GetOutgoingTerms();
var linkedPages = await Task.WhenAll(terms.Select(t => GetPageFromWikipedia(t)));


Ну и так далее, причем при каждом await система может полностью освободить поток для другой работы, что позволяет такие таски запускать сотнями и тысячами.
Более того, при вызове await еще и не создаются потоки, если все правильно написано: habrahabr.ru/post/216659
Там «все сложно». В зависимости от того, что у вас реально в операции, потоки могут создаваться, а могут не создаваться. Если у вас IO-bound, то скорее всего, потока — как и описанно по вашей ссылке — не будет. Но это не единственный сценарий.

Собственно, Стивен Клири именно поэтому предлагает разделять собственно асинхронность и параллелизм, и подчеркивает, что async/await в первую очередь направлен на асинхронность, но позволяет работать и с параллелизмом, что порождает кучу путаницы.
>>Вы просто не понимаете, как работает async/await в C#.
Я это честно признал, т.к. не щупал. А сейчас пытаюсь понять по вашему описанию
>>а полностью останавливается, не занимая потока
Эм… поток это набор инструкций, они либо выполняются либо нет и третьего не дано. Соответственно поток либо выполняется, либо блокирован.

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

p.S. Создание тысячи потоков и быстро можно только из пула потоков, тут все понятно.

Поток возвращается в пул. А работа которую он выполнял — останавливается. При получения события о завершении асинхронной операции — этот или другой поток могут продолжить выполнять работу.
Эм… поток это набор инструкций, они либо выполняются либо нет и третьего не дано. Соответственно поток либо выполняется, либо блокирован.

Либо в нем нет ни одной инструкции, и он тихо лежит в idle. Вот именно это и делает await в C# — он выходит из метода в этой точке, возвращая управление системе, и вешает «остаток» метода (в виде continuation) на «когда-нибудь потом».

Это уже сложнее, чем я думал, но если я снова придумаю ответ чамберлену, то это уже будет отдельная статья. Т.к. тут придется сидеть — думать.

Я искренне думаю, что без переписывания кода вам это не удастся. Компилятор C# генерит там большую и красивую стейт-машину с кучей деталей.
>>и вешает «остаток» метода (в виде continuation) на «когда-нибудь потом».
Т.е. код показанный вами выполняется после завершения await… но при этом, поток уходит в пул.

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

ну как варианты:
1) мы свершаем прыжок в конец функции, при это сохраняем состоянии стека и указатель на текущую инструкцию… Громоздко и сложно.
2) Проще блокировать поток, если за время блокировки пул потоков переполнится, то выводя такой поток из пула, а на его месте создаем новый, по окончании метода этот же поток убивается.
Т.е. код показанный вами выполняется после завершения await… но при этом, поток уходит в пул.

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

мы свершаем прыжок в конец функции, при это сохраняем состоянии стека и указатель на текущую инструкцию… Громоздко и сложно.

Вот поэтому и не получится без рерайтинга.

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

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


100к запросов к серверу в секунду с I\O? Что вы там будете блокировать?
100к запросов в секунду, это значит у нас на обработку операции отведено не более 10^-5с, в таком темпе попытка вызвать поток из пула — уже дорогая операция.
Да не. Вон новый asp.net 800к+ способен обработать до оптимизаций на 12 портах. Benchmarks. А теперь повторю вопрос — что вы собираетесь блокировать?
И вы считаете, что там такая ситуация:

Пришел запрос — вызывается поток из пула — обрабатывается запрос — возвращается поток в пул.

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

Если так, то получается, что мы дергаем пул 1.6 млн раз за секунду. Усатая сила, вместо того, чтоб чуток пораскинуть мозгами пользуем мощь компилятора.
Что значит «дергаем»? Пораскиньте и запилите pull-request. При чем тут .Net или C++ тогда?
Прошу прощения за то, что не ясно выразил свою мысль.

10^-5 c — это фактически стоимость вызова потока из пула. Соответсвенно, если мы в потоке идущей с частотой в 100 кГц запрашиваем поток из пула, то ничего другого мы сделать уже не сумеем. И если у нас именно такие нагрузки на сервер. то логичнее было бы не останавливать и возвращать их в поток, а брать запрос из очереди.

>>При чем тут .Net или C++ тогда?
Холивар здесь не причем. Любой язык это набор инструментов со своими границами применимости. И конкретно здесь мне интересно знать для await\async и рядом связанных.

Этот механизм, как мне показали, удобен для асинхронных вызовов. Целевая ниша асинхронных вызовов: не частые внешние запросы, но с возможной(!) длительной обработкой.

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

Массу нюансов, который при этом механизм поглощает, конечно, впечатляет. НО это означает, что перед программистом гайка и у него вместо целого набора ключей один универсальный. Удобно, согласен, но на основе этого заявлять, что инструментарий не сравним — нельзя.
Вы поставите 100к запросов в секунду в очередь и начнете ее последовательно разбирать?

С чего вы взяли что асинхронность для не частых внешних вызовов? Хитрости в примерах нет. В зависимости от таск шэдулера выполнение будет проходить в том или другом потоке.

Этот механизм позволяет писать код, для достижения производительности, поддерживаемости и общего качества которого, потребуется значительно больше ресурсов, а выхлоп от этого будет минимален и в текущих реалиях совершенно не рационален.
И конкретно здесь мне интересно знать для await\async и рядом связанных.

Этот механизм, как мне показали, удобен для асинхронных вызовов. Целевая ниша асинхронных вызовов: не частые внешние запросы, но с возможной(!) длительной обработкой.

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

Вот вы еще не разобрались в механизме, а уже делаете о нем выводы. Все, на самом деле, совсем не так.

Во-первых, сам по себе механизм async/await — это всего лишь синтаксический сахар вокруг продолжений (continuations). Да, он очень умный, да, он разворачивает эксепшны, следит за жизненным циклом объектов и контекстом синхронизации, но это всего лишь удобная обертка вокруг Task.ContinueWith().

(кстати, будем честными, тоже не уникально для C#: в F# есть совершенно свои async workflows, в Scala — for-comprehension for Futures).

Во-вторых, построен этот механизм вокруг реактивной парадигмы, которая радикально отличается от потоков. Смысл ее в очень простом — когда у нас есть потенциально долгоиграющая операция, мы оборачиваем ее в «нам нужен результат когда он будет» (Task в C#, Async в F#, Future в Scala, Promise/deferred в JS и так далее) и прекращаем текущее выполнение. Именно прекращаем (отдаем контроль внешнему фреймворку), а не блокируем — это важно.

А дальше у нас есть набор композиций, которые позволяют нам сказать «когда этот результат появится, мы хотим сделать с ним вот это» (а так же «если произошла ошибка, мы хотим сделать вот это» и так далее), и каждое «это» — это «продолжение» (continuation), очередная функция, которая может быть как синхронной (т.е. вернуть простой результат), так и асинхронной (вернуть обещание результата в будущем), и дальше эта картинка продолжается и продолжается и продолжается.

В C#, опуская детали, это без синтаксического сахара выглядит так:

webClient
  .ReadStringAsync()
  .ContinueWith(FindParent)
  .ContinueWith(parentUri => new Request(parentUri).ReadAndParse(n+1))


И так далее.

Самая прелесть этой системы в том, что она, на самом деле, абстрактна. Она не про потоки, она всего лишь про долгоиграющие операции (которые могут прятать потоки или что-то другое), и это делает ее более высокоуровневой, как следствие, более понятной, прозрачной и широкоприменимой.

Скажем, CalculateFibonacciAsync может внутри себя открывать другой поток, в нем запускать вычисление, а по его завершению возвращать поток в пул, а результат — потребителю. А уж упомянутая Stream.ReadAsync — открывать асинхронную операцию чтения, вешать делегат на ее завершение, и не трогать потоки вообще; причем в зависимости от нижележащей системы, того, что она поддерживает, и банально типа потока, эта асинхронная операция чтения может быть реализована через совершенно разные вызовы API — но для потребителя это все равно всего лишь обещание байтового массива когда-то в будущем. А при чтении из потока в памяти (который просто абстракция над буфером) результат будет просто синхронным — но пользователь снова не заметит разницы.

Прелесть .net не в том, что это единственная система, где есть реактивное программирование. Прелесть в том, что (а) оно есть в стандартной библиотеке (б) оно как можно больше опирается на возможности ОС (ц) оно продвигается фреймворками (стандартные интерфейсы в том же WebAPI почти все асинхронны, в OWIN — все асинхронны, в Windows Runtime, насколько я помню, вообще нельзя писать синхронный I/O код). Просто в MS однажды поняли, что для того, чтобы система была отзывчивой, нужно по максимуму избегать блокирующих операций — и решили сделать все, чтобы программисту (а) было удобно писать в неблокирующем стиле и (б) было сложно писать в блокирующем. Второе удалось хуже, чем первое, но мы только в начале пути.
>> Я это честно признал, т.к. не щупал. А сейчас пытаюсь понять по вашему описанию

Чтобы понять как это работает попробуйте пописать код через Task.ContinueWith, Microsoft.Async и т.п. в MSVS 2010.
Там нету ключевых слов async/await, что СИЛЬНО усложняет код, но позволяет понять что же все-таки за этими словами кроется (хотя бы приблизительно).
Да я, когда мне нужен контроль, и в свежей студии пишу с ContinueWith, это так… доставляет.

А вообще, у Липперта есть хороший цикл статей про continuations (на которых все это построено).
Поподробнее:

var selectedOrders = from o in context.Orders
                     where o.Freight > 30
                     orderby o.ShippedDate descending  
                     select o;

http://localhost:12345/Northwind.svc/Orders?Orderby=ShippedDate&?filter=Freight gt 30


Т.е. нарушение DRY (да, я ленив) при использовании .h-файлов — это нормально? Зачем сначала заставлять разносить объявление и определение, а потом подтыкать это подпорками в IDE?
Спасибо, добавил в избранное.

>>.Т.е. нарушение DRY (да, я ленив) при использовании .h-файлов — это нормально?
Давайте не будем молиться на эмперические правила. Если уж так, то partial классы в C#, которые генерируются Дизайнером на лету это тоже DRY.Основная цель DRY — избежать ошибок в рантайме. Разделение на объявление и определение к этому не способно привести.
>>Зачем сначала заставлять разносить объявление и определение, а потом подтыкать это подпорками в IDE?
Ну а не является ли подобной подпоркой контракт в IDE?
Время компиляции компенсируется временем в рантайме. В среднем .net приложение примерно на столько дольше запускается насколько быстрее компилируется, относительно соизмеримого нативного приложения.

Отладка и диагностика ошибок, как и писал безусловно лучше в C#, но только пока вы не вышли за managed код.

Остальные фичи в С++ на тоже есть, только в виде библиотек. Например все перечисленное вами легко покрывает boost. Не хотите boost? Есть много других.
Как вы лихо подменили время в рантайме временем запуска. И нет, прямой корреляции между «размером» приложения и временем запуска нет.

«Поддержка фич в виде библиотек» — это путь PHP. «У нас нет нормального синтаксиса создания массивов, но зато есть функция!». Так и в С++: «язык не поддерживает нормальную работу со строками, Юникод, итераторы и кучу всего еще, но зато у нас есть Boost!».
Вы правы, .net библиотеки не обязаны инициализироваться на старте приложения, и если так, то время старта .net приложения действительно может быть небольшим.

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

И все-таки С++ поддерживает работу со «строками, юникод, итераторы и кучу всего еще» в STL.
STL есть в базе, везде и никаких boost-ов для этого не нужно.
И все-таки С++ поддерживает работу со «строками, юникод, итераторы и кучу всего еще» в STL.
STL есть в базе, везде и никаких boost-ов для этого не нужно.


Напоминаю: мы сравниваем в первую очередь языки, а не библиотеки. Ну да ладно. Строки — ужасны, итераторы — покажите мне встроенный в язык foreach и yield.
Каким образом то, что строки и итераторы являются сущностями не языка, а библиотек делает их ужасными?
Таким, что разные библиотеки могут реализовывать их по-разному, и итератор из одной не запихнешь в другую.

(про yield уже все написали)
Это скорее вопрос к тому как написана конкретная библиотека.
В своем же проекте можно использовать те библиотеки и итераторы что устраивают вас.

Совсем не обязательно использовать свои строки если есть строки STL и уж точно плохая идея делать свои строки совсем не совместимыми со стандартными.

Я согласен с тем, что подключив произвольную библиотеку есть шансы на то, что там будут использоваться не стандартные строки и итераторы(об этом я писал в статье в соответствующем разделе), но это вопрос к тем, кто писал эти библиотеки и к истории, в своих же проектах вполне реально придерживаться стандартов.
В своем же проекте можно использовать те библиотеки и итераторы что устраивают вас.

Теперь мне надо сопрягать итераторы из одной библиотеки с теми, что устраивают меня из другой библиотеки. Заводно, правда?

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

А что такое «стандартный итератор» в C++? Или стандартная строка с поддержкой Unicode? Или стандартная многопоточность?
Да, решено использовать несколько библиотек с разными базовыми типами — их сопряжение достаточно неприятная вещь, и как я писал это недостаток выбора С++.

Стандартные итераторы и строки это строки STL.
Для стандартной многопоточности, есть например en.cppreference.com/w/cpp/thread,

Вообще например тут:
en.cppreference.com/w/cpp
Описаны основные стандартные библиотеки и типы, единственное что для поддержки части из них нужна поддержка С++11 компилятором.
Вот вам и ответ, почему то, что строки и итераторы — не сущности языка, ужасно.
Я бы все-таки не стал драматизировать и называть это ужасом:)

Конечно это неприятный момент, но формальный и вполне решаемый.
Если нужно — не так и сложно привести строку к подходящему типу, тем более, что делать это придется только работая со старыми библиотеками.
Да почти все в программировании «вполне решаемо», только зачем этим заниматься, когда можно решать конкретные прикладные задачи вместо борьбы с языком?
Борьба всетаки не с языком, а с некоторыми библиотеками, далеко не все из которых обязательно использовать.

Зачем с ними бороться? Ради производительности, ради кроссплатформенности, ради независимости от фреймворка.

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

Но если попробовать спрогнозировать развитие отрасли, то возможно ценность независимости от платформы и производительности окажется выше, чем быстрое решение прикладной задачи?
Борьба всетаки не с языком, а с некоторыми библиотеками, далеко не все из которых обязательно использовать.

А без них язык начинает проигрывать в легкодоступной функциональности.

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

Это же типичная предварительная оптимизация — вы не знаете ни понадобится ли вам отвязываться от платформы, ни понадобится ли вам такая производительности, ни куда будет развиваться отрасль, но предлагаете здесь и сейчас пожертвовать реальной скоростью разработки, которая позволит выйти на рынок и/или оценить жизнеспособность продукта.
Это страховка. Я предлагаю минимизировать риск закрытия проекта из-за изменившейся ситуации на рынке.
Возможно данная стратегия мало полезна в проектах до года, но в проектах время развития которых 3-5 лет и более, думаю стратегия впролне оправдана.
А вы способны предсказать такое изменение рынка через 3-5 лет, при котором ваш нынешний проект закроется из-за того, что он на C#, хотя сейчас он со всем справляется?

Мне вот что-то ни одного примера в голову не приходит.
Я могу нарисовать массу апокалиптических сценариев, если угодно:

1. Сильная реорганизация, смена приоритетов в Микрософте и следующая за ней заморозка развития .net. (MFC они неоднократно замораживали, некоторые платформы хоронили заживо, нельзя исключать что .net-у тоже достанется)

2. Переход заказчика на что-то вроде Эльбруса (сценарий конечно фантастический, но может когото он и постигнет) Да и кто знает какие платформы появятся через 3-5 лет…

3. Возросшие, со времянем эксплуатации, объемы данных и вычислений при недостатчном росте производительности железа (наиболее вероятный сценарий в случае если за эти 3-5 лет количество данных сильно увеличивается)

4. Желание заказчика перейти на «зеленые технологии» с потреблением 20w на рабочее место (а вдруг?)

Можно придумать и еще чтонибудь. Я бы дал примерно 30% на то что один из пунктов может случиться в течении 3-5 лет и нанести серъезный урон проекту.
Сильная реорганизация, смена приоритетов в Микрософте и следующая за ней заморозка развития .net.

Ну так mono же (да и вообще Open Source). А за время, за которое оно протухнет, можно успеть смигрировать куда угодно.

Переход заказчика на что-то вроде Эльбруса (сценарий конечно фантастический, но может когото он и постигнет) Да и кто знает какие платформы появятся через 3-5 лет…

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

Возросшие, со времянем эксплуатации, объемы данных и вычислений при недостатчном росте производительности железа (наиболее вероятный сценарий в случае если за эти 3-5 лет количество данных сильно увеличивается)

Такие вещи видны не вдруг, и решаются заранее. И да, .net-приложения прекрасно масштабируются горизонтально.

Желание заказчика перейти на «зеленые технологии» с потреблением 20w на рабочее место (а вдруг?)

.net тут никак не мешает.

Я бы дал примерно 30% на то что один из пунктов может случиться в течении 3-5 лет и нанести серъезный урон проекту.

Я вот в .net что-то вроде 12-ти лет, и за все это время ни с одним проектом ничего подобного не произошло. Более того, я в разное время имел дело с несколькими проектами возрастом более 5 лет, и с ними тоже ничего такого не происходило даже приблизительно.
mono — лучше чем ничего, но честно говоря немного страшновато использовать его в уомерческих проектах. Может это излишняя параноя.

А разработчику на C++ этот переход обойдется бесплатно?

нет, но заметно дешеале.

.net-приложения прекрасно масштабируются горизонтально
Тут вопрос куда упремся и того насколько верно мы предсказали изменение объемов данных у заказчика.

.net тут никак не мешает.
Вы возможно не часто пользовались .net приложениями на какихнибудь Atom-ах…

Я вот в .net что-то вроде 12-ти лет, и за все это время ни с одним проектом ничего подобного не произошло.

У вас очень удачная статистика, у меня есть другая. Например года 3 назад в моей статистике прошла волна закрытий ASP.NET проектов, предназначенных для «внутреннего пользования» и некоторые библиотеки были переписаны с C# на С++ в целях повышения производительности и совместимости с iOS\MACOS.

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

На основании чего вы делаете этот вывод? Вы лично делали такие миграции для обоих языков?

Тут вопрос куда упремся и того насколько верно мы предсказали изменение объемов данных у заказчика.

А это в любом случае произойдет, вне зависимости от платформы.

Вы возможно не часто пользовались .net приложениями на какихнибудь Atom-ах…

Зато я пользуюсь ими на телефоне.

Например года 3 назад в моей статистике прошла волна закрытий ASP.NET проектов, предназначенных для «внутреннего пользования» и некоторые библиотеки были переписаны с C# на С++ в целях повышения производительности и совместимости с iOS\MACOS.

В разных компаниях или в одной?

И я пока не уверен, что все худшее для .net, в моей статистике, уже позади.

Эта уверенность — как и моя — ни на чем не основана. Мы можем только смотреть на то, что делает MS, а делает он многое.
>На основании чего вы делаете этот вывод? Вы лично делали такие миграции для обоих языков?

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

>Зато я пользуюсь ими на телефоне.
У вас наверное WinPhone)

> В разных компаниях или в одной?
Закрытие ASP.NET проектов в двух разных, миграция C# на С++ в другой.

>Мы можем только смотреть на то, что делает MS, а делает он многое
Да, это безусловно важно. Мне кажется они будут пытаться увеличить прибыль, которая падает уже несколько кварталов подряд

www.microsoft.com/investor/EarningsAndFinancials/Earnings/PressReleaseAndWebcast/FY15/Q3/default.aspx

Это показывает, что-то неправильно в их стратегии развития, и они безусловно как-то попытаются это исправить, вопрос в том как именно…
У вас наверное WinPhone)

Да, у меня Windows Phone, и у меня нет ни одного нарекания на его производительность.

Закрытие ASP.NET проектов в двух разных

Чем это было обосновано?
>Чем это было обосновано?
В обоих случаях ASP.NET приложения были слишком ориентированы на исползование в Windows окружениии под IE.

И когда доля Windows и IE в целевом сегменте начала резко падать, оказалось не рентабельным делать эти приложения работающими на остальных браузерах, включая мобильные платформы.
То есть можно сказать что развитие мобильных платформ явилось причиной по которой данные приложения потеряли свою долю на рынке.
В обоих случаях ASP.NET приложения были слишком ориентированы на исползование в Windows окружениии под IE.

Ээээ, внезапно выясняется, что asp.net в частности и .net вообще тут ни при чем, потому что они вообще никак не влияют на то, в каком браузере используется результат. Более того, и три, и пять лет назад уже вовсю был asp.net mvc, в котором вообще полный контроль за получающимся HTML (и в нем же, кстати, есть серверная адаптация под браузер, включая мобильные платформы).

Так что конкретно эта судьба могла бы постигнуть любую (подчеркиваю, любую) серверную платформу. А конкретный C++, как вы же признались, для веба еще и не подходит…
> внезапно выясняется, что asp.net в частности и .net вообще тут ни при чем,
Не совсем, на сколько я понял, asp.net был одной из немногих технологий позволявших завязаться на IE на столько сильно. Хотя конечно, никто не заставлял использовать такие его «приемущества», но видимо из-за них asp.net и был выбран.

> Так что конкретно эта судьба могла бы постигнуть любую (подчеркиваю, любую) серверную платформу. А конкретный C++, как вы же признались, для веба еще и не подходит…
Я ни где и не рекомендовал использовать С++ для веба. Однако, если бы эти проекты были реализованы ввиде клиентов и сервера например на С++, а не в виде интернет приложений, то они имели бы намного больше шансов ожить на мобильных платформах в виде отдельных приложений.
Другое дело, что это абсолютно другая ветка развития и в крайне сослагательном наклонении.
Не совсем, на сколько я понял, asp.net был одной из немногих технологий позволявших завязаться на IE на столько сильно. Хотя конечно, никто не заставлял использовать такие его «приемущества», но видимо из-за них asp.net и был выбран.

Типичная ошибка архитектуры, не имеющая отношения к выбранной технологии.

Однако, если бы эти проекты были реализованы ввиде клиентов и сервера например на С++, а не в виде интернет приложений, то они имели бы намного больше шансов ожить на мобильных платформах в виде отдельных приложений.

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

А чем, по-вашему, серверная часть на C++ отличается от веб-бекэнда на C++, что первое на нем писать можно, а второе — нет?

В общем и целом этот ваш пример вот никак не показывает ущербность C# с точки зрения перспектив (он вообще не был ограничивающим фактором в этом случае, ошибка была совершенно в другом).
>Типичная ошибка архитектуры, не имеющая отношения к выбранной технологии.
Скорее ошибка оценки перспектив рынка. Если бы мобильные платформы не развились, проекты вероятно жили бы и по сей день.

>А чем, по-вашему, серверная часть на C++ отличается от веб-бекэнда на C++, что первое на нем писать можно, а второе — нет?
Серверная часть С++ может быть написана со своим протоколом, это может сильно снизить трафик и упростить «парсинг» пакетов.

>В общем и целом этот ваш пример вот никак не показывает ущербность C# с точки зрения перспектив
Да, но пример и не был призван иллюстрировать ущербность C#. Пример показывает риски связанные с завязкой приложения на одну платформу.

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

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

Серверная часть С++ может быть написана со своим протоколом, это может сильно снизить трафик и упростить «парсинг» пакетов.

Очередной велосипед? Чем вам существующих протоколов мало, вот уж нужды типовых приложений они покрывают с головой.

Пример показывает риски связанные с завязкой приложения на одну платформу.

То, что вы описываете — не технологическая проблема.

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

И опять-таки, мобильное приложение к существующему сайту написать несложно, WebAPI из asp.net выставляется легко, все мобильные клиенты умеют есть REST API.
>Чтобы получить такое веб-приложение, которое нельзя легко адаптировать под другой браузер, нужно долго и последовательно совершать ошибки.
Да. Либо выбрать стратегию, которая из «кривой архитектуры» извлекает экономию в краткосрочном периоде.

>Очередной велосипед? Чем вам существующих протоколов мало, вот уж нужды типовых приложений они покрывают с головой.
Если подходящий протокол с его реализацией найдется — конечно стоит взять его.

> То, что вы описываете — не технологическая проблема.
И да и нет. Это проблема затачивания приложения под фичи, которые существуют только на одной платформе. Она может возникнуть конечно не только с ASP.NET, это проблема подхода. Просто ASP.NET тогда оказался самым дешевым способом

> И опять-таки, мобильное приложение к существующему сайту написать несложно, WebAPI из asp.net выставляется легко, все мобильные клиенты умеют есть REST API.
Вероятно когда спохватились, было уже недостаточно ресурсов для адаптации. Да и приложение похоже было слишком ориентировано на работу в локалке с большим трафиком и хорошим пингом к серверу, что не хорошо для мобильной версии.
Если подходящий протокол с его реализацией найдется — конечно стоит взять его

… а учитывая, что для веба все подходящие протоколы давно реализованы под все приличные языки, я что-то не вижу отличий для C++ в этом разрезе. Не сходится.

В общем, все это возвращает нас к началу дискуссии: при правильных архитектурных решениях C# сейчас является не более «опасным» с точки зрения будущего языком, чем C++.
>В общем, все это возвращает нас к началу дискуссии: при правильных архитектурных решениях C# сейчас является не более «опасным» с точки зрения будущего языком, чем C++.

Язык сам по себе не причем, но выбор С# часто тянет за собой выбор инфраструктуры и библиотек, которые «внезапно» оказываются существуют только под Windows. И это уже ведет к рискам.

Например: я собираюсь писать на С#, но не хочу завазываться на Windows. На чем мне писать UI? Если я из-за красивостей и биндинга (выгодных моей разработке) выберу WPF, то путь на другие платформы у меня будет отрезан, с Winforms ситуация не на много лучше, только без красивостей и биндинга и с некой реализацией winapi на mono, в 100% идентичность оригиналу которой я не верю.
Gtk#? Как-то страшновато, да и функционал до WPF не додягивает, хорошо если покроет Winforms.

И кроме UI можно найти еще направления, где для С# есть инфраструктура под Windows, для которой нет аналогов на других платформах.
Но парадокс в том, что именно ради нее часто и выбирают C#, отрубая путь на другие платформы.

Например вы выбрали IOCP. Замечательная штука, но на других платформах ее нет в таком виде, и она будет реализована через другие механизмы(по сути будет эмулироваться) поэтому будет по-другому работать.
Для вашей задачи это «по-другому» возможно будет приемлемо, но когда таких «по-другому» накапливается критическая масса, то это может вызвать критические проблемы.

Вы можете сказать, что на С++ тоже можно завязаться на платформо-зависимую и все проблемы будут теже самые.
Да, это правда, но разница в том, что для С++ есть практики и рекомендации как писать «кросплатформенно», а для C# такие практики не пропагандируются (разве что не тянуть импорты из dll) потому что такого рода пропаганда не выгодна Microsoft. Выгода Microsoft в максимально глубоком и сильно связанном подсаживании на свою платформу.
И это уже ведет к рискам.

Риски надо осознавать.

Но парадокс в том, что именно ради нее часто и выбирают C#, отрубая путь на другие платформы.

Во-первых, а зачем не в UI многоплатформенность? Во-вторых, как раз не в UI .net ведет себя лучше (а теперь — еще лучше) на других платформах.

Например вы выбрали IOCP. Замечательная штука, но на других платформах ее нет в таком виде, и она будет реализована через другие механизмы(по сути будет эмулироваться) поэтому будет по-другому работать.

Вы не понимаете. Я не выбрал IOCP, я выбрал асинхронный I/O. На вин-платформе (причем не на каждой) это будет сделано через IOCP, а на других платформах — через другие механизмы. Не эмуляцию IOCP, а именно нативные механизмы нижележащей системы, дающие асинхронный I/O.

для C# такие практики не пропагандируются (разве что не тянуть импорты из dll) потому что такого рода пропаганда не выгодна Microsoft.

То-то MS официально объявила о выходе .net для других платформ, разбиении фреймворка и так далее. Наверное, чтобы усилить то, что им не выгодно.

Выгода Microsoft в максимально глубоком и сильно связанном подсаживании на свою платформу.

Вопрос в том, что считать платформой MS.
>как раз не в UI .net ведет себя лучше (а теперь — еще лучше) на других платформах.
Как же без UI на десктопе?

>Вы не понимаете. Я не выбрал IOCP, я выбрал асинхронный I/O.
То есть вы в целом были готовы к тому что работа асинхронного I/O может отличаться на разных платформах.
В конкретно вашем случае это отличие скорее всего вполне приемлемо, но врядли так будет во всех платформо-зависимых решениях…

>То-то MS официально объявила о выходе .net для других платформ, разбиении фреймворка и так далее.
Прошло 15 лет с появления .net и первого обещания MS о том что кросплатформенность будет и вот уже «MS официально объявила».
Объявление конечно это не может не радовать, но когда же уже он выйдет и какие библиотеки в нем будут? Почему именно сейчас?

> Вопрос в том, что считать платформой MS.
Думаю это в первую очередь то что приносит продажи MS
как раз не в UI .net ведет себя лучше (а теперь — еще лучше) на других платформах.

Как же без UI на десктопе?

Так я не про десктоп.

То есть вы в целом были готовы к тому что работа асинхронного I/O может отличаться на разных платформах.

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

Объявление конечно это не может не радовать, но когда же уже он выйдет и какие библиотеки в нем будут? Почему именно сейчас?

Если честно, то мне все равно. Лично меня устраивает тот факт, что конкретно используемый мной сервис работает и на Windows, и на Linux, причем на втором чуть ли не лучше. При этом он (сервис) написан на .net (с небольшими вкраплениями JS).
Ну скажите пожалуйста где вы видели нормальный кроссплатформенный UI который поддерживает все фишки любой платформы? И не надо сейчас про QT с его QML, там тоже есть костыли и не все так идеально.
>Ну скажите пожалуйста где вы видели нормальный кроссплатформенный UI который поддерживает все фишки любой платформы?

А мне не нужны ВСЕ фишки ЛЮБОЙ платформы. Мне нужно чтобы у UI было низкое время отклика и достаточное количество контролов в базе. Поддержка биндингов была бы плюсом, но жить можно и без нее (биндинги всеравно тянут MVVM, который хотя и приносит свои плюсы, но сильно раздувает код)

Для десктопа же очень много вариантов кросплатформенного UI.
Мобильный UI (и только UI) не вижу смысла делать кросплатформенным
А, кстати, о кросс-платформенности.

If it isn't tested, it's broken.

Если вы не тестируете приложение регулярно на всех платформах — оно не кроссплатформенное. Вы готовы каждый раз, когда вы пишете UI, запускать его в двух-трех-пяти ОС?
Тестировать приложение надо перед релизом.
И да — конечно надо, на каждой платформе, если релиз на несколько платформ.

Однако это не значит что во время разработки вы должны каждое изменение проверять на всех платформах. Если писать более менее кросплатформенно, то этапа тестирования перед релизом должно бы хватить.
Тестировать приложение надо перед релизом.

С какой частотой у вас «релизы»?

Если писать более менее кросплатформенно,

А как определить, кроссплатформенно ли вы пишете?
>С какой частотой у вас «релизы»?
Зависит от проекта и продукта, как правило от 4 месяцев до года, иногда больше.

>А как определить, кроссплатформенно ли вы пишете?
Есть некоторые стандарты и правила. Если коротко, суть их в том, что на С++ вы должны использовать только библиотеки включенные в стандарт С++ и кросплатформенные библиотеки, а всякие API операционной системы не использовать.
Зависит от проекта и продукта, как правило от 4 месяцев до года, иногда больше.

Предположим, раз в год. А сколько у вас период тестирования «перед релизом»?

Если коротко, суть их в том, что на С++ вы должны использовать только библиотеки включенные в стандарт С++ и кросплатформенные библиотеки, а всякие API операционной системы не использовать.

Для GUI работает? Например, high-DPI в Windows и MacOS одинаково себя ведет?
>Предположим, раз в год. А сколько у вас период тестирования «перед релизом»?
Месяца 3-4.

>Для GUI работает? Например, high-DPI в Windows и MacOS одинаково себя ведет?
Например для Qt должно бы работать…
doc-snapshots.qt.io/qt5-5.4/highdpi.html
Предположим, раз в год. А сколько у вас период тестирования «перед релизом»?

Месяца 3-4.

Угу. Восемь месяцев что-то писали, потом выяснили, что не работает под линуксом, на исправление нужно, скажем половина от этого — это четыре месяца. Когда будем тестировать то, что исправили?

(короткие итерации и CI не просто так придумали)

Например для Qt должно бы работать…
doc-snapshots.qt.io/qt5-5.4/highdpi.html

Вот то-то и оно, что «должно». А в реальности там танцы с бубнами.

(или, скажем, обнаружение removable drives — тоже совершенно по-разному себя ведет)
3. Возросшие, со времянем эксплуатации, объемы данных и вычислений при недостатчном росте производительности железа (наиболее вероятный сценарий в случае если за эти 3-5 лет количество данных сильно увеличивается)

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

Ну и за остальные «апокалиптические сценарии» я бы не дал и процента.
Мне кажется некорректно противопоставлять высокоуровневую оптимизации и низкоуровневую. Они не исключают друг друга, а дополняют.
Аналог foreach из С++11

std::vector result;
for (auto x: result)
Строго говоря, строк в языке C# тоже нет, это системная библиотека. Различайте язык и стандартную библиотеку и для C# тогда тоже.
Когда серия конкатенаций оператором + компилируется в один вызов Concat с соответствующим числом параметров, это уже поддержка на уровне языка, а не библиотека…
А еще и foreach по строке компилируется в for.
С# с огромным опозданием, но делает шаги в кроссплатформенность. Когда прибудет? Пока сложно сказать