https://fusion-samples.servicetitan.com/ - режим Blazor Server там делает все, о чем пишет автор. Режим Blazor WASM делает пререндеринг на сервере, а все остальное - на клиенте.
Более того, все это обновляется в real-time, и все это делает один и тот же код, в котором вы не увидите практически ничего про real-time - там нет событий и т.п., но обновляется только то, что нужно.
Привет, думаю, вам стоит посмотреть Fusion — она решает массу проблем, описанных здесь, и делает это несколько более элегантно: github.com/servicetitan/Stl.Fusion
P.P.S. The funny part is: I actually spent some time to find out why missing tail / prologue Task.Yield() triggers recursion in this example. And my original plan for that post was to share stack traces to show where exactly it happens, why it happens, and why this optimization in TPL actually makes a lot of sense. But I ended up explaining only the side effect of that and cut the rest — solely because of a lack of time. And now I see why it looks like I didn’t dig deeply enough into why it happens, esp. taking into account the title. So maybe it’s a good lesson for my future posts :)
Hi, the author of two original posts is here. I speak Russian, but unfortunately, I don't type well in Russian, so:
Hi, thanks for looking into this! First, let me comment on a few points you’ve mentioned:
— “The example uses a kind of anti-pattern for async usage in C#” — that’s true, and I’ve mentioned it’s an unfair benchmark for C#. I intentionally took a well-known benchmark for goroutines knowing it’s highly disadvantageous for C# to demonstrate that async/await should be comparable even in this case in terms of performance.
— This explains why I didn’t try to use other schedulers — frankly, I should, but that’s not what you normally do by default.
— This also explains why I had to use Task.Yield(). It was clear to me that you can get rid of it w/ your own scheduler, and moreover, it will also improve the speed a lot.
— I am also 90% sure that getting rid of “await Task.Yield()” is the main driver of performance improvement in your version.
— As for GC.Collect() after warmup, true, it’s really not that important, all you might expect is a bit better + more consistent timings if your working set is fully fitting into CPU caches. Unfortunately, I’ve forgot to do the same in Go test — clearly, it has to be done the same way at least.
As a side note, I never used StaTaskScheduler before — this is also why I was hesitant to invest into researching on what can be achieved with other schedulers. But thanks to you, I’ll take this into account next time, though I still lean to implementing a “perfectly slim” scheduler + probably, tasks as well. Based on your research, this should demonstrate that in this case C# should be light-years ahead, which is actually what I’d love to show: the asynchronous computation model there is way more extendable than in Go, so if it’s also better in terms of performance — even though you need some special tuning — this basically undermines the core promise Go makes.
Finally, performance isn’t the only focus point in this article. I mostly wanted to show how these languages differ in terms of their approach to asynchronous computation, and obviously, you can’t do this w/o such benchmarks.
No matter what, thanks a lot for quite useful feedback!
P.S. If you don’t mind, I’d love to reference your post if I’ll decide to publish another post on async/await vs Go here. I plan to do this closer to .NET Core 2.1 release — likely, with more benchmarks in general. Based on what’s known so far, we should expect pretty dramatic improvements in speed for C# with this release.
Отличная аналогия про ДНК и среду обитания. В общем, вы правы в том, что говорить об оценке идей в отрыве от всего остального просто бессмысленно. Фраза «идея не стоит ничего» этого в полной мере не передает, потому лучше её не использовать. А если использовать, то расшифровывать, что на самом деле имеется ввиду, т.к. в ином случае большинство людей поймут эту фразу совершенно прямолинейным образом.
Вопрос о том, что более важно\первично, здесь никто не ставил. Но если его поставить, + считать меру качества идеи мультипликатором — вы будете правы (вопрос не будет иметь смысла).
Я вложил в эту фразу стандартный для стартапов смысл. В оригинале идея 9facts казалось достаточно хорошей, и в результате я добился относительно высокой pre-money valuation во время инвестирования. И тем не менее, все это оказалось неважным, т.к. проект был закрыт.
Через 3-4 года сказать о том, какие из проектов успешены, будет очень просто — они либо закроются, либо нет. Интереснее же получить какую-то информацию о них уже сейчас :)
Я слегка поанализировал один из упомянутых проектов — TagBrand. Раз уж зашла речь, хочется понять, как идут дела у наиболее известных проектов (TagBrand — один из победителей TechCrunch Startup Battle).
Его текущую аудиторию можно оценить, поиграв с tagbrand.com/users?page=1 (пользователи там отсорт. по числу бренд-инов)
— всего зарег. пользователей — около 15К (видимо, те, что скачали и запустили приложение)
— пользователей с 1+ бренд-ином: ~ 1500 (реально воспользовались iPhone-риложением)
— пользователей с 3+ бренд-инами: ~ 950 (те, кто пользовались им неск. раз)
— есть пользователи, которые сделали почти 300 бренд-инов — т.е. есть фанаты.
На меня самого все это производит двоякое впечатление:
— Если они не рекламировались, все это выглядит очень хорошо. Мне кажется, для веб-приложения это было бы 100% неплохим результатом.
— С другой стороны, AppStore при первом размещении дает отличный толчек, если с приложением все хорошо. Но т.к. сам я там ничего не размещал, судить могу только по тому, что пишут другие.
Если здесь есть эксперты по продвижению на AppStore — отпишитесь, пожалуйста.
Для параметризации классами все медленнее потому, что для них работает type erasure с заменой на __Canon, и в результате соотв. код часто использует словари.
Ну, это не наш случай. Я понимаю, что оригинальная концепция явно не так хороша, как мне казалось, но не представляю пока, как её изменить таким образом, чтоб новая концепция мне нравилась.
Нет — когда мы делали поддержку Stack Exchange, у них еще не было authentication. Потому мы валидируем там аккаунт несколько иначе.
И про обновления: а данные соотетвствуют действительности? Автообновляемые факты у нас не «всплывают» в лентах вверх (так же вроде-бы нет смысла, хотя и спорно).
Если нет — попробуй пройти авторизацию заново, или включить\выключить факт профейдер. Если не поможет — напиши мне, пожалуйста. Крит. ошибки я буду исправлять.
Просто отмечу, что будущее давно наступило :)
https://fusion-samples.servicetitan.com/ - режим Blazor Server там делает все, о чем пишет автор. Режим Blazor WASM делает пререндеринг на сервере, а все остальное - на клиенте.
Более того, все это обновляется в real-time, и все это делает один и тот же код, в котором вы не увидите практически ничего про real-time - там нет событий и т.п., но обновляется только то, что нужно.
Демка сделана с:
Blazor: https://blazor-university.com/overview/what-is-blazor/
Fusion: https://github.com/servicetitan/Stl.Fusion
Disclaimer: я - автор Fusion.
Примеры на Fusion: github.com/servicetitan/Stl.Fusion.Samples
Hi, thanks for looking into this! First, let me comment on a few points you’ve mentioned:
— “The example uses a kind of anti-pattern for async usage in C#” — that’s true, and I’ve mentioned it’s an unfair benchmark for C#. I intentionally took a well-known benchmark for goroutines knowing it’s highly disadvantageous for C# to demonstrate that async/await should be comparable even in this case in terms of performance.
— This explains why I didn’t try to use other schedulers — frankly, I should, but that’s not what you normally do by default.
— This also explains why I had to use Task.Yield(). It was clear to me that you can get rid of it w/ your own scheduler, and moreover, it will also improve the speed a lot.
— I am also 90% sure that getting rid of “await Task.Yield()” is the main driver of performance improvement in your version.
— As for GC.Collect() after warmup, true, it’s really not that important, all you might expect is a bit better + more consistent timings if your working set is fully fitting into CPU caches. Unfortunately, I’ve forgot to do the same in Go test — clearly, it has to be done the same way at least.
As a side note, I never used StaTaskScheduler before — this is also why I was hesitant to invest into researching on what can be achieved with other schedulers. But thanks to you, I’ll take this into account next time, though I still lean to implementing a “perfectly slim” scheduler + probably, tasks as well. Based on your research, this should demonstrate that in this case C# should be light-years ahead, which is actually what I’d love to show: the asynchronous computation model there is way more extendable than in Go, so if it’s also better in terms of performance — even though you need some special tuning — this basically undermines the core promise Go makes.
Finally, performance isn’t the only focus point in this article. I mostly wanted to show how these languages differ in terms of their approach to asynchronous computation, and obviously, you can’t do this w/o such benchmarks.
No matter what, thanks a lot for quite useful feedback!
P.S. If you don’t mind, I’d love to reference your post if I’ll decide to publish another post on async/await vs Go here. I plan to do this closer to .NET Core 2.1 release — likely, with more benchmarks in general. Based on what’s known so far, we should expect pretty dramatic improvements in speed for C# with this release.
Его текущую аудиторию можно оценить, поиграв с tagbrand.com/users?page=1 (пользователи там отсорт. по числу бренд-инов)
— всего зарег. пользователей — около 15К (видимо, те, что скачали и запустили приложение)
— пользователей с 1+ бренд-ином: ~ 1500 (реально воспользовались iPhone-риложением)
— пользователей с 3+ бренд-инами: ~ 950 (те, кто пользовались им неск. раз)
— есть пользователи, которые сделали почти 300 бренд-инов — т.е. есть фанаты.
На меня самого все это производит двоякое впечатление:
— Если они не рекламировались, все это выглядит очень хорошо. Мне кажется, для веб-приложения это было бы 100% неплохим результатом.
— С другой стороны, AppStore при первом размещении дает отличный толчек, если с приложением все хорошо. Но т.к. сам я там ничего не размещал, судить могу только по тому, что пишут другие.
Если здесь есть эксперты по продвижению на AppStore — отпишитесь, пожалуйста.
И про обновления: а данные соотетвствуют действительности? Автообновляемые факты у нас не «всплывают» в лентах вверх (так же вроде-бы нет смысла, хотя и спорно).
Если нет — попробуй пройти авторизацию заново, или включить\выключить факт профейдер. Если не поможет — напиши мне, пожалуйста. Крит. ошибки я буду исправлять.