Видимо, это сильно зависит от того, что разрабатывать. У меня это asp.net mvc 5.
Да, тоже постоянно в углу всплывают всякие ошибки, но чего-то фатального обычно не происходит. Бывает, что автодополнение подглючивает или подстветка, и действительно очень многое пока сыро. Но из двух зол я выбрал rider именно потому, что в нем все-таки продуктивнее работается. Лично мне проще, когда какая-то фича не работает (привыкаешь и не замечаешь), чем когда все работает правильно, но регулярно виснет на 3-10 секунд, даже когда ты просто пишешь код. Неимоверно раздражает.
Но все равно долго ведь. И все равно есть проблемы в процессе самой работы (падает, виснет, тормозит...)
В rider же можно полноценно работать через минуту после запуска, и на работу не влияет ни сборка всего проекта в фоне, ни запуск тестов, ни checkout. И я совершенно не понимаю, какая разница, что оно работает наполовину на джаве. Работает же.
И, честно говоря, не думаю, что все легковесные загрузки и отложенные подгрузки расширений улучшат работу в студии до такого уровня.
Чего бы MS занимались оптимизацией загрузки R#? Тем более что R# нужен всегда и почти сразу, а Xamarin только тем, кто с ним работает. Так что это правильно, что они его загрузку оптимизируют. Мне, например, он совсем не нужен, а ресурсы отжирает.
Даже по сравнению с 2013 студией с решарпером, без всякого рослина, Rider уже прекрасен. С вашего позволения, пример с рабочего проекта.
На солюшне, в котором примерно 200 проектов, во время загрузки студии можно уходить пить чай. В процессе работы она тоже частенько подвисает и периодически падает. При билде сложно даже ходить по коду. При необходимости сделать pull или checkout — почти гарантированная необходимость перезагружать солюшн или студию. И даже в фоне, когда я сижу в другом приложении, студия что-то делает и периодически выжирает 80-90% процессора.
Пробовал студию 2015; субьективно, стало еще хуже.
Rider уже сейчас не страдает ни одной из этих проблем. При его пока еще многочисленных детских болезнях и большом количестве всяких багов и нереализованных фич, работать в нем уже гораздо удобнее и приятнее. За последние полторы недели вообще не было необходимости запускать студию.
Наверное, если выключить половину фич решарпера, то и в студии можно было бы работать, но в Rider все то же самое летает.
Только до этого аутентификация шла через все провайдеры по-очереди, до первой успешной. А в вашей реализации — пройдут все сразу.
Как бы вы сделали генерацию бесконечной последовательности случайных чисел только на linq? Чтобы можно было написать, например, RandomNumbers().Take(1000)
Да, паттерн распространенный, но получается, что сравнивается не «работа yield в сравнении с реализацией „в лоб“, а скорость создания одного массива со скоростью создания и копирования семи, т.е. „manual vs. LINQ“.
Возможно, то, во что разворачивается yield, в этом эксперименте укладывается в 1% от общего времени выполнения, а 99% съедает создание массива. Хотя, конечно, я не проверял и думаю, что разница все равно будет в разы.
Первый тест абсолютно некорректен.
1. Метод Array() — не аналог Range и его результаты отличаются от Iterator() при одинаковых входных данных. В том числе и длиной конечного массива.
2. Скорость Iterator() сильно страдает за счет ToArray(), который будет создавать массивы длиной 4, 8 16, ..., 128 элементов, и потом в конце еще один длиной 90. Если уж замерять «цикл vs. итератор», то хотя бы сумму элементов считать.
Малозначительной вещью это является для той довольно небольшой части населения, которая понимает, что ей вешают лапшу на уши. Сидят, паразиты, в интернетах своих и телевизор не смотрят. Вот среди них шутки хотят, да. Но это не целевая аудитория.
А вот целевая аудитория поверит, что покемоны нужны, чтобы их двор фотографировать и пересылать в ЦРУ. Вот так поймают во дворе покемона — и все, где-то уже разведчик вылетает в Россию, чтобы придти в этот двор, сломать качели и испачкать подъезды. И им не объяснишь, что в России приложение вообще не доступно официально, ничего никуда не пересылается и т.п. Потому что «по телевизору сказали».
Ну, те, кто повыше, проехались на тему того, что ЦРУ шпионит, разрашует и разлагает. Профит как раз понятен — население в очередной раз узнало, что вокруг враги, и еще сильнее поддерживают главного спасителя страны и укрепителя скреп.
А те, кто пониже, под шумок получат новые звездочки за победу над очередным случаем экстремизма.
Подумалось, что на шарпе этого добиться не так сложно с использованием дженерик-методов. Тогда не надо на каждую комбинацию требуемых интерфейсов создавать новый класс.
public interface IReadable { }
public interface IWriteable { }
public class ReadableWriteable : IReadable, IWriteable { }
public void ReadWrite<T>(T stream) where T : IReadable, IWriteable
{
...
}
void Call()
{
ReadWrite(new ReadableWriteable());
}
Думаю, скорее раньше было так, как вы описали, но сейчас поведение поменялось )
Да, глотание исключений — это неприятно. Тут стоит разделять две вещи: если в подписчике предполагается возможность возникновения исключения, то от синхронных команд стоит отказаться. Но вот если вдруг при разработке где-то прокосячили и примитивный код типа установки свойств в синхронной команде стал падать с исключением, такое обнаружить будет непросто.
Можно, правда, схитрить и синхронные команды создавать асинхронными внутри. То есть вместо ReactiveCommand.Create() + command.Subscribe(action) вызывать что-то типа своего MySyncReactiveCommand.Create(action), который обернет ваш action в асинхронный вариант команды (получится синтаксис как в reactiveui 7). Оверхед на асинхронность остается, но он весь скрыт внутри и в случае чего не придется чистить все эти костыли во всех местах, где есть синхронные команды.
На релиз седьмой версии в ближайшее время, думаю, надеяться не стоит. Каких-то даже примерных сроков я не нашел, и судя по всему, еще есть приличный объем не сделанных задач.
Спасибо за развернутый комментарий! А вы не могли бы привести пример кода, в котором в ответ на исключение при вызове команда окончательно подыхает? В том примере, который есть в статье, код подписчика в Subscribe() бросает исключение, но повторный вызов Execute() возможен и CanExecute() возвращает true.
Реактивные команды реализованы так, что в команде как в IObservable не предполагается возможность возникновения OnError(), потому что тогда после первой же ошибки команда отваливалась бы и нужно было бы создавать ее снова. Каждый запуск команды внутри должен создавать новый IObservable, результат которого при успехе прилетает через саму команду. Если же что-то упало, то исключение либо проглотится (самый неприятный вариант), либо вылетит при вызове метода запуска команды, либо придет через ThrownExceptions. Сама же команда не должна пострадать.
Как ловить исключения в синхронных командах — хороший вопрос. По идее их просто не должно быть. Вот тут создатель фреймворка говорит, что сложный код и код, который бросает исключения — это не для синхронных команд и Subscribe().
In ReactiveUI, you should never put Interesting™ code inside the Subscribe block — Subscribe is solely to log the result of operations, or to wire up properties to other properties.
По-хорошему стоит использовать асинхронные команды для всего сколько-нибудь сложного и/или потенциально падающего. Для синхронных команд же можно попробовать сделать обертку над ReactiveCommand и реализовать Execute по-своему, чтобы каждый раз не оборачивать код в обработчик исключений, и команды громко падали в случае чего. Но я думаю, что в первую очередь стоит стремиться к тому, чтобы подписчики вообще не могли упасть.
То, что можно не писать геттеры-сеттеры и оставить просто автосвойство — действительно здорово. Надо будет попробовать… А вот что касается магии цепочек эвентов: полагаю, это работает только в самых простых случаях, когда я использую первое свойство в геттере второго?
Вы не испытываете проблем с тем, что если надо немного усложнить логику изменения Output Property, приходится отказываться от автосвойсв и начинать руками триггерить эвенты? И не получается ли в итоге непонимания, что в коде происходит автоматически, что делается руками и как оно вообще работает в целом?
Это, безусловно, полезный сайт, но он про Reactive Extensions. ReactiveUI — сторонняя библиотека с кучей своих функций, и вот по ней с документацией все плохо.
Будьте аккуратнее с аксиомами, а то если воспринимать их слишком буквально, придется комментировать i++.
Писать комментарии нужно там, где они действельно нужны. То есть в сложных системах, про которые вы упоминаете. И только если код не документирует сам себя.
Вы ссылаетесь на Алена Голуба. Если вы перевернете страницу, то увидите правило «Комментарий не должен подтверждать очевидное». Вот вы написали комментарий: ///@brief Главная функция, непосредственно выводящая в консоль приветствие. По коду же очевидно, что это главная функция и что она выводит текст в консоль, и второй раз повторять это нет смысла. Ваш код не буфетчица будет читать, а другие программисты, и уж если они это понять без комментария не могут, то проблемы тут явно не в отсутствии комментариев.
Да, есть какой-то разрешенный вариант без браузера для особых случаев, но я на самом деле не очень понимаю это ограничение правил ВК. В рамках своего приложения у разработчика полный доступ к браузеру, он может и отображаемый контент подправить, и введенные пользователем данные посмотреть, и вообще что угодно. Непонятно, какой профит от ограничения.
На мой вкус, c использованием [Flags] enum более просто и наглядно. Задать нужные флаги — mask = Permissions.Offline | Permissions.Notify | Permissions.Friends |… В строку отформатировать — тоже одна-две строки кода.
Да, тоже постоянно в углу всплывают всякие ошибки, но чего-то фатального обычно не происходит. Бывает, что автодополнение подглючивает или подстветка, и действительно очень многое пока сыро. Но из двух зол я выбрал rider именно потому, что в нем все-таки продуктивнее работается. Лично мне проще, когда какая-то фича не работает (привыкаешь и не замечаешь), чем когда все работает правильно, но регулярно виснет на 3-10 секунд, даже когда ты просто пишешь код. Неимоверно раздражает.
В rider же можно полноценно работать через минуту после запуска, и на работу не влияет ни сборка всего проекта в фоне, ни запуск тестов, ни checkout. И я совершенно не понимаю, какая разница, что оно работает наполовину на джаве. Работает же.
И, честно говоря, не думаю, что все легковесные загрузки и отложенные подгрузки расширений улучшат работу в студии до такого уровня.
Чего бы MS занимались оптимизацией загрузки R#? Тем более что R# нужен всегда и почти сразу, а Xamarin только тем, кто с ним работает. Так что это правильно, что они его загрузку оптимизируют. Мне, например, он совсем не нужен, а ресурсы отжирает.
На солюшне, в котором примерно 200 проектов, во время загрузки студии можно уходить пить чай. В процессе работы она тоже частенько подвисает и периодически падает. При билде сложно даже ходить по коду. При необходимости сделать pull или checkout — почти гарантированная необходимость перезагружать солюшн или студию. И даже в фоне, когда я сижу в другом приложении, студия что-то делает и периодически выжирает 80-90% процессора.
Пробовал студию 2015; субьективно, стало еще хуже.
Rider уже сейчас не страдает ни одной из этих проблем. При его пока еще многочисленных детских болезнях и большом количестве всяких багов и нереализованных фич, работать в нем уже гораздо удобнее и приятнее. За последние полторы недели вообще не было необходимости запускать студию.
Наверное, если выключить половину фич решарпера, то и в студии можно было бы работать, но в Rider все то же самое летает.
Как бы вы сделали генерацию бесконечной последовательности случайных чисел только на linq? Чтобы можно было написать, например, RandomNumbers().Take(1000)
Который внутри через yield написан, к слову.
Возможно, то, во что разворачивается yield, в этом эксперименте укладывается в 1% от общего времени выполнения, а 99% съедает создание массива. Хотя, конечно, я не проверял и думаю, что разница все равно будет в разы.
1. Метод Array() — не аналог Range и его результаты отличаются от Iterator() при одинаковых входных данных. В том числе и длиной конечного массива.
2. Скорость Iterator() сильно страдает за счет ToArray(), который будет создавать массивы длиной 4, 8 16, ..., 128 элементов, и потом в конце еще один длиной 90. Если уж замерять «цикл vs. итератор», то хотя бы сумму элементов считать.
А вот целевая аудитория поверит, что покемоны нужны, чтобы их двор фотографировать и пересылать в ЦРУ. Вот так поймают во дворе покемона — и все, где-то уже разведчик вылетает в Россию, чтобы придти в этот двор, сломать качели и испачкать подъезды. И им не объяснишь, что в России приложение вообще не доступно официально, ничего никуда не пересылается и т.п. Потому что «по телевизору сказали».
А те, кто пониже, под шумок получат новые звездочки за победу над очередным случаем экстремизма.
Да, глотание исключений — это неприятно. Тут стоит разделять две вещи: если в подписчике предполагается возможность возникновения исключения, то от синхронных команд стоит отказаться. Но вот если вдруг при разработке где-то прокосячили и примитивный код типа установки свойств в синхронной команде стал падать с исключением, такое обнаружить будет непросто.
Можно, правда, схитрить и синхронные команды создавать асинхронными внутри. То есть вместо ReactiveCommand.Create() + command.Subscribe(action) вызывать что-то типа своего MySyncReactiveCommand.Create(action), который обернет ваш action в асинхронный вариант команды (получится синтаксис как в reactiveui 7). Оверхед на асинхронность остается, но он весь скрыт внутри и в случае чего не придется чистить все эти костыли во всех местах, где есть синхронные команды.
На релиз седьмой версии в ближайшее время, думаю, надеяться не стоит. Каких-то даже примерных сроков я не нашел, и судя по всему, еще есть приличный объем не сделанных задач.
Реактивные команды реализованы так, что в команде как в IObservable не предполагается возможность возникновения OnError(), потому что тогда после первой же ошибки команда отваливалась бы и нужно было бы создавать ее снова. Каждый запуск команды внутри должен создавать новый IObservable, результат которого при успехе прилетает через саму команду. Если же что-то упало, то исключение либо проглотится (самый неприятный вариант), либо вылетит при вызове метода запуска команды, либо придет через ThrownExceptions. Сама же команда не должна пострадать.
Как ловить исключения в синхронных командах — хороший вопрос. По идее их просто не должно быть. Вот тут создатель фреймворка говорит, что сложный код и код, который бросает исключения — это не для синхронных команд и Subscribe().
По-хорошему стоит использовать асинхронные команды для всего сколько-нибудь сложного и/или потенциально падающего. Для синхронных команд же можно попробовать сделать обертку над ReactiveCommand и реализовать Execute по-своему, чтобы каждый раз не оборачивать код в обработчик исключений, и команды громко падали в случае чего. Но я думаю, что в первую очередь стоит стремиться к тому, чтобы подписчики вообще не могли упасть.
Получилось как раз как в вашем примере.
Вы не испытываете проблем с тем, что если надо немного усложнить логику изменения Output Property, приходится отказываться от автосвойсв и начинать руками триггерить эвенты? И не получается ли в итоге непонимания, что в коде происходит автоматически, что делается руками и как оно вообще работает в целом?
— для классического INPC: https://github.com/Fody/PropertyChanged
— для ReactiveUI: https://github.com/kswoll/ReactiveUI.Fody
Но я не пользовался ни той, ни другой, не могу сказать, насколько это удобно и есть ли какие-то подводные камни.
public class ShortName: List { }
Конечно, с sealed классами не прокатит, но в большинстве случаев применимо. Хотя очень сомневаюсь, что стоит так делать.
Писать комментарии нужно там, где они действельно нужны. То есть в сложных системах, про которые вы упоминаете. И только если код не документирует сам себя.
Вы ссылаетесь на Алена Голуба. Если вы перевернете страницу, то увидите правило «Комментарий не должен подтверждать очевидное». Вот вы написали комментарий: ///@brief Главная функция, непосредственно выводящая в консоль приветствие. По коду же очевидно, что это главная функция и что она выводит текст в консоль, и второй раз повторять это нет смысла. Ваш код не буфетчица будет читать, а другие программисты, и уж если они это понять без комментария не могут, то проблемы тут явно не в отсутствии комментариев.
На мой вкус, c использованием [Flags] enum более просто и наглядно. Задать нужные флаги — mask = Permissions.Offline | Permissions.Notify | Permissions.Friends |… В строку отформатировать — тоже одна-две строки кода.