[HN Gopher] .NET 6 vs .NET 5 speedup
___________________________________________________________________
.NET 6 vs .NET 5 speedup
Author : dgellow
Score : 285 points
Date : 2021-11-21 11:16 UTC (11 hours ago)
(HTM) web link (alexyakunin.medium.com)
(TXT) w3m dump (alexyakunin.medium.com)
| Ygg2 wrote:
| Do be warned that .Net 6 did cause some regressions, in
| reflection at least
|
| https://github.com/dotnet/runtime/issues/61486
| vadfa wrote:
| Isn't reflection by definition unstable?
| GordonS wrote:
| Not so it would crash the entire app with an uncatchable
| exception, no.
| dtech wrote:
| No. Reflection is a program accessing or modifying its own
| program structure. There's not need for it to be unstable,
| languages like Lisp, Java and I assume C# have clearly
| defined semantics for it.
| SideburnsOfDoom wrote:
| Correct.
|
| Perhaps parent comment meant "unstable" in the sense that
| it turns compile time failures into runtime ones:
|
| e.g. without reflection, if you type "customer.GetOrders()"
| then it either compiles or does not, whereas reflection
| code that finds a method called "GetOrders" can compile
| just fine but you won't know if it finds a method of that
| name or returns null, until runtime.
| phillipcarter wrote:
| > There's not need for it to be unstable
|
| In practice there is though, it just depends on what you
| choose to take a dependency on.
|
| For example, a few years ago the C# compiler did some
| lambda function optimization work. This broke someone's
| code because they were using reflection, and ultimately
| depended on how lambdas were getting optimized prior to the
| performance improvement in the compiler. The team by-
| designed that regression, since they make no guarantees
| that you can depend on a particular implementation detail
| of how the compiler optimizes things.
|
| That said, when people use reflection in .NET, they're
| almost always programming against something that is stable
| and has likely worked the same way for a decade.
| phillipcarter wrote:
| Also, I can't believe I didn't mention this already:
|
| Reflection in .NET lets you dynamically invoke anything
| declared internal or private as well. I think it goes
| without saying that your code can be broken in the future
| if you do this.
| lvass wrote:
| How safe, audited and non-invasive is .net core by now? There's a
| .net program I have a VM for and that's kind of a pain. Since
| .net had telemetry by default, running bare on my machines was
| never an option, and Mono wouldn't even work.
| tasogare wrote:
| In which kind of world do you live that setting a single
| environment variable is too much technical work?[0] I have the
| feeling your post is more about shitting on .NET with a low
| effort excuse than genuine interest.
|
| [0] set DOTNET_CLI_TELEMETRY_OPTOUT environment variable to 1
| or true
| tester756 wrote:
| >Since .net had telemetry by default, running bare on my
| machines was never an option
|
| Why?
|
| I don't see anything weird in data collected
|
| https://docs.microsoft.com/en-us/dotnet/core/tools/telemetry...
| AlexanderDhoore wrote:
| Medical, military, industrial... Not everything is a webapp.
| tester756 wrote:
| OP wrote about his private machine.
|
| Anyway, OP was worried about installing .NET because it has
| telemetry by default, meanwhile you can disable telemetry
| before running your war-app or just ship standalone? idk.
| lvass wrote:
| I never said what "my machines" do. Don't assume everyone
| has the same lax safety necessities as you have.
| tester756 wrote:
| Fair, that's why I asked which specific telemetry is
| weird/insecure in your opinion
| nojito wrote:
| It's downright impossible find a situation where .NET is
| not approved for use because of "security".
| brushfoot wrote:
| .NET doesn't have telemetry. The .NET SDK does by default, but
| that's for developing, not running, .NET apps. You don't need
| to (and shouldn't) install the SDK on a production machine.
|
| In other words, if you just downloaded the .NET or .NET Core
| runtime to host an app, there's no .NET telemetry.
|
| As far as the .NET SDK, you can disable telemetry by setting
| the environment variable `DOTNET_CLI_TELEMETRY_OPTOUT` to `1`
| or `true`.
| kolleykibber wrote:
| Are there any figures available for .net usage outside of large
| organisations?
| Rochus wrote:
| The speed-up very much depents on the (micro)benchmark in use. I
| did some measurements using the Are-we-fast-yet benchmark suite
| which includes both micro and larger benchmarks and got an
| overall speed-up (geometric mean of factors) of only 2% on x86
| and even a little speed-down on x64.
|
| See https://www.quora.com/Is-the-Mono-CLR-really-slower-than-
| Cor... and http://software.rochus-keller.ch/Are-we-fast-
| yet_results_win... for the details.
| ripley12 wrote:
| It looks like you're not using the new dynamic PGO
| functionality (the OP is). I've seen throughput gains of ~15%
| from that.
| rndgermandude wrote:
| You're cross-compiling from the Oberon+ language to CLR IL
| bytecode using your own compiler... This isn't exactly
| something a lot of people would do. Most people would write
| more or less idiomatic C# and have the "official" compiler
| (Roslyn) produce the byte code.
|
| What I am saying, I guess, is that I am not quite sure how much
| of your benchmark results come down to the quality of IL your
| custom compiler spits out.
| munchler wrote:
| As an F# developer, I find it a little frustrating when
| people assume.NET = C#. If the blog post is about the speed
| of IL generated by the latest C# compiler, it should say so
| in the title instead of claiming to measure the performance
| of .NET in general.
| ygra wrote:
| The runtime team certainly looks at discrepancies where C#
| and F# generate different IL that should still run about
| the same when JIT-compiled. So while C# is the main focus
| (also since the runtime libraries are written in C#), F# is
| not forgotten and benefits from a lot of those improvements
| as well.
| Rochus wrote:
| > _You 're cross-compiling from the Oberon+ language to CLR
| IL bytecode ..._
|
| It's just "compiling", not "cross-compiling"; using CLR/CIL
| as a language backend is an intended feature, that's why the
| CLR and IL are standardized in ECMA-335 and ISO 23271, and
| that's why it is called "common language infrastructure".
|
| > _Most people would write more or less idiomatic C#_
|
| You are welcome to write a C# version of the benchmark.
|
| > _have the "official" compiler (Roslyn)_
|
| It's not the "official" compiler, but just the C# compiler
| implemented by MS and community; there are a lot of other
| compilers too.
| justin66 wrote:
| > It's not the "official" compiler, but just the C#
| compiler implemented by MS and community
|
| That sounds pretty official.
| infogulch wrote:
| You're arguing semantics. GP's point is that the compiler
| shipped with the platform may produce better byte code,
| which could have an affect on the benchmark results. This
| seems like a reasonable point to make.
| Rochus wrote:
| Don't forget that IL is not executed, but is just an
| intermediate representation, and optimizations are done
| by the CLR; e.g. Mono does the following optimizations
| (according to e.g.
| https://man.archlinux.org/man/mono.1.en), regardless
| which compiler generated the IL: branch
| Branch optimizations cfold Constant folding
| cmov Conditional moves [arch-dependency]
| deadce Dead code elimination consprop
| Constant propagation copyprop Copy propagation
| fcmov Fast x86 FP compares [arch-dependency]
| float32 Perform 32-bit float arithmetic using 32-bit
| operations gshared Enable generic code sharing.
| inline Inline method calls intrins Intrinsic
| method implementations linears Linear scan
| global reg allocation leaf Leaf procedures
| optimizations loop Loop related optimizations
| peephole Peephole postpass precomp Precompile
| all methods before executing Main sched
| Instruction scheduling shared Emit per-domain
| code sse2 SSE2 instructions on x86 [arch-
| dependency] tailc Tail recursion and tail
| calls
| forrestthewoods wrote:
| I don't think you're being very reasonable here.
|
| You made a claim. Someone disputed the validity of your
| evidence. And your response is "well you can
| rewrite/replicate my entire project if you like".
|
| I think most people are going to assume your claim is
| bullshit and move on with their lives. You made the
| unconventional claim so the burden of proof is on you.
| Rochus wrote:
| > You made the unconventional claim so the burden of
| proof is on you.
|
| My assertion is supported by sufficient evidence. The
| criteria of scientificity are fulfilled. You can repeat
| the experiment on your system yourself if you wish. Under
| the referenced links you will find everything necessary
| to do so.
| fabian2k wrote:
| You're arguing a very specific subset, which is a
| completely different thing than what essentially every
| article on .NET 6 performance claims. The performance
| claims are almost always about the whole thing, including
| various parts of the framework, the standard library and
| lots of low-level optimizations.
|
| Microsoft published an enormously long article detailing
| many of the optimizations that were done
| (https://devblogs.microsoft.com/dotnet/performance-
| improvemen...). And it is not very suprising that pure
| number-crunching benchmarks only using the .NET IL would
| not gain very much. As much as I hate to discuss what
| "real world" applications are, the claims Microsoft and
| others are focusing on are much more relevant for typical
| applications where .NET is used than your examples.
| forrestthewoods wrote:
| The community clearly disagrees.
|
| No one is disputing the results of your test. The
| question is will those results be replicated under
| conditions that are relevant to people writing code in a
| mainstream language under a much more prevalent compiler?
|
| The answer might be yes! Everyone should always be
| suspicious of microbenchmarks. However people are also
| wise to be suspicious of benchmarks in obscure languages.
|
| Your results introduce too many new variables for anyone
| to be comfortable to use it as a data point to inform
| their decision making.
| infogulch wrote:
| Nobody is arguing against the results that you got. The
| question is if the results are applicable to the wider
| ecosystem or if there is another confounding variable
| that explains the outcome. Your experiment hints in this
| direction, and maybe someone should create another one
| that teases this apart, but definitive arguments either
| way are premature.
| NationalPark wrote:
| Maybe consider changing the title? I think most people
| are reading it as a much stronger claim (applying to
| Roslyn) than you intended.
| jmkni wrote:
| Would be interested to see this benchmark on M1 (Apple
| Silicon), are there instructions on how to run it on that?
| Rochus wrote:
| If you want to compare different .NET versions running
| natively on M1 such versions must be available as a
| precondition. If so, just download e.g.
| http://software.rochus-keller.ch/Are-we-fast-
| yet_CLI_2021-08..., update the included runtimeconfig.json
| file to the .NET version in use and run it (dotnet Main.exe).
| jmkni wrote:
| Ok nice, will give that a go, cheers :)
| btrask wrote:
| I might be the last person to realize this, but did Microsoft
| name it .NET because they already had COM?
| oaiey wrote:
| It was the year 2000, web services was the hype of the .com
| bubble. So Microsoft pushed the web services in the net. Hence,
| all the products .NET. Windows Server .NET, Visual Studio .NET,
| .NET Framework etc.
|
| It was marketing.
| ygra wrote:
| .NET actually was known as COM+ for a time before public
| release. Environment variables for tweaking internal behaviour
| still retain that moniker.
| randerson wrote:
| COM+ was basically Distributed COM, and was available for
| years before .NET. .NET Framework was implemented built on
| existing Win32 and COM/COM+ calls though, which is why you
| might see that.
| DenisM wrote:
| Distributed COM was known as DCOM, COM+ became known as
| CLR.
| phillipcarter wrote:
| https://en.wikipedia.org/wiki/Microsoft_.NET_strategy
| jmnicolas wrote:
| I was so happy with upgrading one of my app to .net 6: I saw
| perfs gains from 10 minutes execution time on .net 4.8 to 1'30
| minutes on .net 6.
|
| Then my boss reminded me that we had new hypervisors with SSD
| (the old one had still spinning platters) so now I'm not so sure
| the .net 6 upgrade really made my app faster.
| mihular wrote:
| Highly unlikely that you would gain that much just by
| upgrading. What kind of an app is anyway?
| dgellow wrote:
| The library benchmarked in the article is Stl.Fusion:
| https://github.com/servicetitan/Stl.Fusion. I've only learned
| about it today, and the documentation is a bit messy, but that
| seems to be a really interesting project. The author describes it
| as a .Net library to quickly develop efficient, distributed,
| real-time web applications.
| Shadonototra wrote:
| improvements for typical benchmark code
|
| nothing for common user code
|
| why?
|
| because benchmarking JIT code is cheating, nobody runs THE SAME
| code path 1_000_000 times in a row to warmup the JIT
|
| you run something here, then there, then over there, then
| sometimes there, this is not JIT proof and you constantly get the
| JIT to do work
|
| that's part of the reason Go became popular, on top of the single
| binary and the cloud native libraries story
| notanaverageman wrote:
| Note that most of the performance improvements come from PGO,
| which is enabled with following environment variables. PGO is not
| enabled in .NET 6 by default, but will be in .NET 7 IIRC.
| set DOTNET_ReadyToRun=0 set DOTNET_TieredPGO=1 set
| DOTNET_TC_QuickJitForLoops=1
|
| Here are my own benchmarks from a CPU intensive application
| without any IO and already optimized for allocations. Application
| runs a task graph either serially or in parallel.
| .NET 5 -------------------------- | Method |
| Mean | |------------ |---------:| | RunParallel |
| 473.4 us | | Run | 513.5 us | .NET 6
| -------------------------- | Method | Mean |
| |------------ |---------:| | RunParallel | 452.5 us |
| | Run | 499.8 us | .NET 6 PGO
| -------------------------- | Method | Mean |
| |------------ |---------:| | RunParallel | 381.8 us |
| | Run | 412.2 us | .NET 5 - .NET 6 -> ~5%
| .NET 5 - .NET 6 PGO -> ~20%
|
| Here is what I learned from micro-optimizing a .NET application:
|
| - Use BenchmarkDotNet[0] for general measurements and Visual
| Studio profiler tools for detailed inspection. They help a lot.
|
| - Memory allocations matter. Using capturing lambdas, LINQ, even
| foreach on interfaces introduce allocations and slows down the
| application. You can use ClrHeapAllocationAnalyzer[1] to find
| these hidden allocations.
|
| - Using abstractions with interfaces and casting back to concrete
| types cause some overhead, though PGO will probably eliminate
| most of these.
|
| - Use LINQ cautiously as its variants are mostly slower than
| explicit coding. E.g. .Any() vs .Count == 0
|
| - Checking Logger.IsEnabled() before calling Logger.Debug() etc.
| helps a lot. You can even automate this with Fody [2], but it
| breaks Edit&Continue and possibly .NET Hot Reload too, so it may
| hinder your productivity.
|
| [0] https://github.com/dotnet/BenchmarkDotNet
|
| [1] https://github.com/microsoft/RoslynClrHeapAllocationAnalyzer
|
| [2] https://github.com/jorisdebock/LoggerIsEnabled.Fody
| vips7L wrote:
| FYI your chart is very unreadable on mobile.
| notanaverageman wrote:
| Thanks, I removed unnecessary parts. It should be better now.
| foepys wrote:
| > - Use LINQ cautiously as its variants are mostly slower than
| explicit coding. E.g. .Any() vs .Count == 0
|
| When using LINQ also be aware that .First(predicate) is
| significantly slower than .Where(predicate).First() when called
| on List<T> and T[]. This is true for essentially all methods
| like Last, Single, Count etc. Don't trust Visual Studio when
| it's telling you to "optimize" this.
|
| But if you want the last bit of performance, you shouldn't use
| LINQ anyways.
| joe_guy wrote:
| Do you know why that is? That's very interesting.
| tluyben2 wrote:
| We are testing on .NET 6 now with a large LoC monolithic asp.net
| system and the results indeed again have improved. We already
| rewrote a lot when we moved to .net 5 core to be more idiomatic
| so I guess those things were optimized more. It is not a huge
| jump but definitely nice work!
|
| Edit; will try to post some numbers when all tests succeed; it is
| closed source but for a large (millions LoC) codebase I think it
| is nice to see how it performs under the same conditions compared
| to our current prod.
| DeathArrow wrote:
| Quite interesting, but I would like to also see other benchmarks
| as the author said that the speed is constrained by the DB, ORM
| and other stack choices.
| mjburgess wrote:
| In the same vein as what Linus is trying to do now at LTT, it
| would be useful if there was a "programming journalism" lab which
| builds "test benches" to create canonical benchmarks and verify
| the claims made on tech blogs (etc.).
|
| Eg., highly standardised docker builds, on highly standardised
| hardware, running popular tasks using popular libraries for each
| "programming tech" (eg., website, stat modelling, event system,
| ...).
| gostsamo wrote:
| Usually the setups and architectural choices are so different
| that it would make more sense for everyone to get a good stat
| on which functions they are calling and how much and to make a
| prediction on the individual stats of each function. This does
| not take into account caching and multithreaded scenarios, but
| the map can never be the territory.
| okl wrote:
| Like pts that https://www.phoronix.com/ uses?
| littlecranky67 wrote:
| There are these: https://www.techempower.com/benchmarks/
| cies wrote:
| These are some microbenchmarks at best. Still nice to know
| who wins, but not representative of any real work scenario.
| Hnus wrote:
| What would be representation of some real work scenarios? I
| think their test suite covers wide spectrum of operations
| enough so to be able to draw conclusions from them.
|
| https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Pro
| j...
| fenring wrote:
| Unfortunently, after looking at the .net core
| implementation of this benchmarks, I wouldn't trust it at
| all. The code is just overengineerd to perform best at
| benchmark - everything hardcoded, custom routing to cover
| 2-3 routes with minimal overhead etc. It has nothing in
| common with real world code.
| the_duke wrote:
| The Techempower entries are heavily gaming the system.
|
| They often strip out framework functionality and hyper-
| optimise for the specific benchmark, including things
| like pre-allocating the exact amount of memory needed to
| serve the request, not doing route matching et all, etc.
|
| They are basically an exercise in "how clever can we be
| to win the benchmark" rather than a realistic portrait of
| real world performance.
| fabian2k wrote:
| at least for .NET the versions that strip out framework
| functionality are marked separately, though this part is
| not that easy to understand if you don't know about it.
| There are several .NET entries from very low-level
| without MVC and without ORM up to the full stack.
|
| But still, these benchmarks have their uses but there are
| a lot of caveats you need to consider when looking at the
| results.
| The_rationalist wrote:
| The rust and c++ implementations are only on the top 10
| because they use PostgreSQL pipelining/batching
| Philip-J-Fry wrote:
| I think people should just bench their own code and measure
| their own performance increases.
| [deleted]
| GuB-42 wrote:
| It is hard to do relevant tests of which language is the
| fastest.
|
| Really, writing fast code is mostly down to the programmer. For
| example C is widely recognized as the fastest non-assembly
| language simply because it leaves a lot to the programmer, C
| won't magically make your terrible code fast, unless you are
| using time-to-segfault as a metric. Assembly is the fastest if
| you know what you are doing, very few know what they are doing.
|
| So, what kind of code are you going to use for your benchmark?
| Highly optimized code written by experts spending way too much
| time, the "most idiomatic" code, code written by an average
| skilled programmer picked at random, code extracted from a big
| open source project? This can drastically change the ranking,
| so which one is the most relevant? If you go with the "most
| idiomatic" for instance, you miss out on the idea that parts
| can be optimized if needed, and that in real life, programmers
| aren't perfect and can write suboptimal code by mistake.
|
| There is also a cultural aspect to languages that may not be
| caught in benchmarks. For example, C programmers tend to have a
| culture of performance, they tend to know about their hardware,
| will try to save memory, make data structure efficient, etc...
| Python programmers, not so much, instead they tend to value
| readability and development time.
|
| You can't test languages like you test CPUs for instance. With
| CPUs, you just run the same code on them and time them. You
| can't do that for obvious reasons: your C compiler won't accept
| your Python code, it is necessarily an apples to oranges
| comparison.
| DeathArrow wrote:
| In general the speed is lost because we make the CPU consume
| cycles to do things that are not necessary in order to solve
| a particular problem:
|
| -unneeded allocations
|
| -boxing/unboxing
|
| -garbage collection
|
| -interpreting
| kaba0 wrote:
| > Assembly is the fastest if you know what you are doing,
| very few know what they are doing.
|
| Just a nitpick but for any reasonably sized code, no. While
| some people can indeed do impressive optimizations on small
| segments of assembly, they are humans and they will fail to
| do trivial optimizations that are reliably done by compilers.
| buryat wrote:
| why someone would do it fo free? with journalism you have
| advertiser that sponsor investigations albeit undirectly
| Dayshine wrote:
| LTT is a perfect example of how you can do it without any
| particularly plausible conflicting sponsorships.
|
| Do you really believe that Merch sales and sponsorship by
| Squarespace, VPN providers, sys-admin software, etc influence
| their coverage of CPUs?
| mikewarot wrote:
| What does .NET actually do?
| cyral wrote:
| It is basically the standard library for C#/F#/VB.NET
| applications.
| mikewarot wrote:
| I've never had to use it in my code, but I've had plenty of
| problems with its use in applications. It always seemed to me
| that it was Microsoft's attempt to lock people into Windows
| forever.
| hu3 wrote:
| .NET Linux support was announced a few years ago.
|
| > It always seemed to me that it was Microsoft's attempt to
| lock people into Windows forever.
| cyral wrote:
| > It always seemed to me that it was Microsoft's attempt to
| lock people into Windows forever.
|
| It has had first-class support for Linux and MacOS for the
| past five years so that certainly isn't the case these
| days. actually develop C# applications on Mac and run them
| in production on Ubuntu, no Windows involved in the
| toolchain anymore.
| Rapzid wrote:
| .NET is an umbrella term for the platform ecosystem that
| includes, among other things:
|
| * Common Language Runtime(aka CLR, aka runtime) and its JIT
| compiler RyuJIT
|
| * The C# language and it's compiler Roslyn
|
| * The base class library and framework class libraries(aka BCL
| and FCL)
|
| * ASP.NET the flagship web application framework
|
| * F# the platforms flagship functional language
|
| * etc etc
|
| It's all ".NET"
| creamytaco wrote:
| Is .NET relevant even on Windows these days? With MSFT's Linux
| embrace ever tightening, why would anyone without sunk costs
| invest in .NET when every alternative seems to be better (or
| quickly getting there)?
| [deleted]
| Beltiras wrote:
| Those sunk costs are sometimes a dev team. Not just a matter of
| spent money.
| jcims wrote:
| That's exactly the issue I'm facing now. Have a team of .NET
| devs who feel like the walls are closing in because the
| corporate strategy is clearly elsewhere. My goal for now is
| to focus on moving off of Windows because that's actually
| where all of our pain comes from.
| Beltiras wrote:
| I'm leaving my current workplace because we are making the
| switch the other way around. Having spent 3 years retooling
| everything for Docker and containers we just got a new boss
| that's slowly moving more in the Windows direction.
| Sometimes it's also just a case of being too entrenched.
| And then there are all the stakeholders that don't
| understand the tech but have way more say in what gets
| chosen than us techies.
| quietbritishjim wrote:
| The developer experience for .NET is pretty incredible. Have
| you tried it? I don't think you would be dismissing it like
| this if you had.
| xbar wrote:
| I, for one, have not, but I keep hearing this from HN.
| Perhaps the next project....
| 9wzYQbTYsAIc wrote:
| For real, .NET's problems these days are mostly related to
| being controlled by Microsoft and the .NET Foundation.
|
| Definitely some room to grow in the technical respects, but
| the .NET ecosystem is pretty decent, as it is.
| gameswithgo wrote:
| Better how? C# is probably the best performing gc language
| there is, and F# probably the most interesting.
| thrower123 wrote:
| If you're doing Windows development, you'd be foolish not to
| use dotnet. It's pretty good off Windows now, with all the
| massive efforts they've put in making it run on Linux better
| than Mono did the past years.
| GordonS wrote:
| > when every alternative seems to be better
|
| Eh?
|
| C# and F# are fabulous languages - it's a huuuge stretch to
| claim that almost anything else is "better".
| thepra wrote:
| I have a web app running on it on Linux :)
| jb_s wrote:
| As a .NET veteran, if anything .NET is 10x more relevant now
| that it's cross-platform... you don't need Windows to develop,
| you can containerise your apps and run it anywhere, it's
| _significantly_ better now than in the old days (anyone
| remember debugging GAC issues?)
|
| C# is still one of the best languages I've used, which is the
| reason why I've kept at it for so long - e.g. it got
| async/await semantics in like 2012 (just after F# did). I'm
| about to switch jobs to a company that uses Typescript/Node
| after years in .NET and I feel like I'm going to miss quite a
| lot of the development experience. I'm not sure which
| alternatives are necessarily better but again I haven't spent a
| significant amount of time with, for example, Golang or Scala.
| Swift was kind of equivalent but (AFAIK) missing some features
| and the vastness of the nuget package ecosystem.
| ozim wrote:
| I would say that you see it from different perspective.
|
| It is Windows/Linux that are becoming irrelevant.
|
| Future is about browser applications/mobile applications and
| cloud workloads.
|
| Yes of course there are uses for desktop computing but those
| are specialists.
|
| While general public will be using phones and tablets not even
| owning a laptop. On the phone/tablet people don't even care
| what is the OS.
|
| I already know people who don't have computers at home, only
| tablets/phones/gaming consoles. Normal people want to play
| games, message each other, no one cares about OS an Microsoft
| knows that.
| pjmlp wrote:
| Yes it is, even with all the COM love, there were only three
| C++ talks on the VS2022 release party, .NET stole the show for
| everything else.
|
| Most desktop applications targeted at Windows are written in
| .NET and C++ only comes into the picture via COM/DLLs, hardly
| anyone writes pure Windows applications in straight C or C++,
| unless we are talking about games.
| Aerroon wrote:
| And even Unity games are C#.
| ClumsyPilot wrote:
| "NET when every alternative seems to be better"
|
| Better how? There are people convinced that C is the best
| because it's the fastest, and if that the only thing thst
| matters to them, they aren't wrong.
| kaba0 wrote:
| But not even that is true. C is not any closer to metal than
| C++, or bunch of other languages that compile to native code
| are, hell, it can't even do proper threading natively, nor
| SIMD, which is just a bunch of compiler specific pragmas.
| Semaphor wrote:
| .NET nowadays runs on Linux. Even SQL Server does.
| creamytaco wrote:
| Running on Linux doesn't tell us much in itself. Can it
| compete with long-established alternatives on that platform?
| Does it have adoption? I think the answer to both these
| questions is a strong no.
| Rapzid wrote:
| I know the answers are yes.
|
| Since we are on the topic of Linux so something exciting
| was merged for .Net6 that wasn't talked about; the new file
| interface with support for symbolic links. That sounds a
| bit absurd but it's been a long standing issue with
| challenges you wouldn't expect..
|
| https://github.com/dotnet/runtime/pull/54253
| nycdotnet wrote:
| At Namely our payroll and benefits systems run on .NET in
| Linux containers on k8s talking to Postgres, SQL Server,
| Redis, and Kafka, and we integrate between these services
| and others via gRPC. Some of these services' endpoints are
| exposed via GraphQL using a Node service running the Apollo
| server and some are called directly via gRPC by Go, Ruby,
| and Python services. All of this is on Linux in k8s. The
| .NET services integrate with the same ELK stack and things
| like Jaeger. It has adoption, it is competitive, and it
| integrates really nicely.
| strikelaserclaw wrote:
| do u guys use ef?
| Semaphor wrote:
| I'm not sure if that's what you mean, but your comments
| sound like "I have absolutely no idea, but I'm going with
| my unfounded gut feeling"
| fabian2k wrote:
| Why shouldn't it be able to compete there? It works very
| well on Linux and modern .NET is a pretty good platform in
| many regards.
| 9wzYQbTYsAIc wrote:
| It certainly has the potential for both.
|
| There are scores of Windows developers who's skills are now
| transferable to Linux, Apple, and Android development
| (albeit with some caveats).
| kreeben wrote:
| I had to raise two kids so I couldn't find time to master
| both the Linux and Windows ecosystems so I chose the one
| they use at work. These days Microsoft has made me think
| more carefully about choosing platform and with their new
| proposals, Win11 and Edge The E-commerce Browser, I'm
| ready to jump onto Linux but how would I program that
| environment, when I have almost no experience in C? For
| me, the answer is .net.
|
| Thank you, Microsoft, for showing me a way out.
| 5e92cb50239222b wrote:
| Eh? you don't have to know C to develop for Linux. Most
| of us don't write C at all. I've written maybe a few
| thousand lines in all my life, the vast majority of them
| for ESP32.
| kreeben wrote:
| Of course one doesn't have to program one's environment
| but I would never be on one where I couldn't.
| ogogmad wrote:
| I think you misunderstood the parent commenter. He said
| that he hasn't programmed much _in C_ , but that doesn't
| mean he hasn't done much programming altogether. He's
| wondering why you ever felt that programming in Linux
| meant you had to use C. Many of the Linux APIs are
| written in C but there are wrappers for countless other
| languages, no?
|
| Many Linux people like to use Python, for instance.
| Unfortunately, it's a slow language for all sorts of
| incidental but hard-to-fix reasons. This has led people
| to look for alternatives. I think Go is increasingly used
| as an alternative, but it lacks features like operator
| overloading which are a necessity in certain areas.
| There's JVM languages like Java, Kotlin and Scala as
| well. Nim is up-and-coming. Some people use functional
| languages like Haskell and Common Lisp. C++ is widely
| used but not much loved.
| kreeben wrote:
| Thx, yes I might have. I know enough about all of those
| languages that you mentioned to realize, as a c-sharper I
| have it good. Java is a bit too weird for me. Python a
| bit too slow. C++ too hard, Haskel too functional ;)
|
| I realize of course that not all Linux users are C
| programmers.
|
| Given the opportunity to transfer my C# knowledge over to
| Linux, I'll take it.
| oaiey wrote:
| Check the techempower benchmarks mentioned all over any
| .NET performance article. They beat on Linux nearly any
| other tech stack in the performance game. NFRs like
| debugging, monitoring, etc are all there.
|
| From my personal perspective, roughly 75% of all applicable
| (non-Windows-UI) .NET greenfield project go straight on
| Linux. The brownfield/maintenance situation is surely
| different. Companies are not married to the Windows stack
| when you get the alternative for free. And R&Ds just follow
| that.
|
| .NET is on Linux and performs excellent there.
| 5e92cb50239222b wrote:
| Those benchmarks are a joke. Did you look at the source
| code? Nobody is writing real applications like that. Most
| of them do a single select and push the results out to
| the client.
|
| (FWIW, I spend about 40% of my working time dealing with
| dotnet).
| sp33der89 wrote:
| And how has your experience with dotnet been?
| cyral wrote:
| Yes, I run it in production on Linux and develop on Mac and
| the experience is great. You would be correct making this
| statement 5 years ago before they re-wrote everything to be
| cross platform (that is what .NET Core is vs the old .NET)
| sp33der89 wrote:
| I've seen the posts about all the speedups each new version of
| .NET gets and I'm just wondering, was .NET just alright in
| performance before all this? Is that the reason they can get all
| these speedups? :P
|
| I'd be interested in some JVM vs .NET 6 benchmarks too, which
| platform to chose when.
|
| EDIT: I know about the benchmarks and I also feel like sometimes
| these benchmarks are really optimized in a non-idiomatic way. I
| would love to know how performance idiomatic Java/.NET code is
| and if one is to start a new project today why one would choose
| the JVM over .NET or when someone would chose .NET over JVM.
| Semaphor wrote:
| It's not the same, but there is this well-known framework
| benchmark [0], it always had the .net frameworks close to the
| top.
|
| I'm guessing a lot of the speedups come from getting rid of
| legacy cruft. With .net core/.NET 5/6 they got rid of a lot of
| things compared to .NET Framework 4.8 and could play with
| optimizations that simply weren't doable before. That's just me
| guessing, though ;)
|
| [0]: https://www.techempower.com/benchmarks/
| rndgermandude wrote:
| It's that in part. Here are some of my additional
| observations and or guesses.
|
| They invested a lot of time adding language features with
| compiler and runtime support to avoid e.g. heap
| allocations/copying, like Span<> and friends, (readonly) ref
| structs, in/ref/out parameters (ref and out parameters
| existed before but were used a lot less in the runtime), or
| ValueTasks to some degree. This in turn enabled a lot of
| potential for optimizations in the compiler (aside from
| essentially writing an entirely new bytecode compiler with
| Roslyn and entirely new JIT with RyuJIT, throwing out the
| crufty old compilers), in the general runtime, and in the
| specific runtimes/frameworks e.g. ASP.NET. Those
| optimizations have to be implemented first however, and more
| and more get implemented with each new version.
|
| I have a project I maintain that sees an almost 50% speedup
| from net48 to net5, and another 10-15% speedup from net5 to
| net6 (based on the time it takes to run the extensive test
| suite). It isn't even that compute heavy. From profiling it
| appears that a lot of these speedups are due to internal
| copies of data being avoided, and a lot of additional fast-
| paths in the runtime (e.g. fast-paths for byte-arrays or
| character-arrays as opposed to taking the generic array slow
| paths).
|
| Another thing of note is that they added a lot of `bool
| Try*(..., out result)`-style APIs meant to avoid exceptions
| and the associated handling, and switched a lot of internal
| code to use these functions. E.g. in the reference source of
| the net48 runtime I think there are still a lot of instances
| of try { var number =
| int.Parse(value); } catch { // slow
| path/error path }
|
| instead of the new-idiomatic .netcore and later style of
| if (!int.TryParse(value, out var number)) { // slow
| path/error path }
|
| try-catch was/is slow-ish, and throwing exceptions is too,
| aside from it preventing inlining by the JIT a lot of times.
|
| And while #nullable (source annotations for what is nullable
| or not) and associated annotations such as MaybeNullWhen()
| had no direct influence on how the compiler could optimize,
| it probably helped people a lot writing correct code and as a
| side effect a lot more code became compile-time provable non-
| nullable which enabled further optimizations e.g. generating
| code that skips redundant null checks.
| chrisoverzero wrote:
| > the new-idiomatic .netcore and later style
|
| `Int32.TryParse` has existed since .NET Framework 2.0,
| which was released on February 13, 2002:
| https://docs.microsoft.com/en-
| us/dotnet/api/system.int32.try...
| rndgermandude wrote:
| Right, this one has, a lot of other public or runtime-
| internal Try* methods have not.
|
| And even tho this particular one has existed for a long
| time, that doesn't mean it was used consistently in the
| runtime or in the popular first and third party
| frameworks.
|
| I'd argue the Try*-style, while artifacts of it were
| present before already, only really became widely
| idiomatic with dotnetcore.
| cyral wrote:
| Surprising that in 2021 Java still doesn't have this in
| its standard library
| CornCobs wrote:
| Honestly I really like C#'s outvar and return success
| idiom. It's soooo ugly and yet slick at the same time. C
| does the same thing but I think the inline out var
| declarations make a huge difference to using them. Of
| course you miss out on error context an Exception or
| Result<T, Err> gives you but for many of the Try* functions
| it really doesn't matter.
| foepys wrote:
| .NET Core also introduced some new CLR features that are
| incompatible with the CLR used in .NET Framework. Span<T> for
| example.
|
| This has happened before with .NET Framework 2, 3, 4 etc. but
| instead of making a .NET Framework 5 they rather made .NET
| Core cross-plattform and threw backwards-compatability-at-
| all-cost out of the window. While all .NET Framework
| applications (except the ones that do naughty stuff with
| reflection) that were compiled for .NET Framework 4.5 behave
| the same way on .NET 4.8, .NET (Core) got rid of this and
| lets developers bundle the CLR directly, giving them more
| leeway for incompatible changes.
| 9wzYQbTYsAIc wrote:
| .NET used to be considered a little bit slow, especially when
| using the Reflection related features, but not nearly as slow
| as interpreted languages.
| Bayart wrote:
| Most of the performance gains are really in the middleware (for
| example Entity Framework) and getting rid of pre-.NET Core
| legacy cruft rather than the VM, AFAIK.
| gameswithgo wrote:
| .NET has been faster than Java on most of the benchmarkgame
| benchmarks for a while, since .net core 3 or so.
|
| More specifically though the JVM has tended to be better about
| optimizing naive code than .net while .net has tended to offer
| more tools to do your own optimizing (unsafe, simd, value
| types, etc). So it would be interesting to see if the
| performance of naive code has improved relative to Java lately
| Mikeb85 wrote:
| > benchmarkgame benchmarks
|
| Lol look at the code. N-body for example, the C# is horrific
| C-in-C# code with a million optimizations (just read the
| comments lol), the Java code is idiomatic and not optimized
| at all.
| symbol-mason wrote:
| Well the fastest C# entry for n-body looks like a
| translation of the C/C++ versions. It is a meaningful
| result that the primitives of the language allow for it to
| hang in that company. The absence of a Java version using
| numerics is unfortunate, that'd be a nice addition.
|
| A lot of the coding style seems optimized around copy-
| pasting the C code, e.g. trying to alias the Vector methods
| (Vector256.Create) to their instruction name
| (_mm256_set1_pd). That makes the code non-idiomatic, but it
| also doesn't really help performance, just makes the
| porting easier.
|
| The F# example is on the same runtime and a better view of
| using the numerics directly. As a trade-off of performance,
| memory, and code complexity it is actually a pretty solid
| balance, which I wouldn't have expected.
|
| https://benchmarksgame-
| team.pages.debian.net/benchmarksgame/...
| Mikeb85 wrote:
| How is it meaningful?
|
| I can inline C code in Ruby, does that mean Ruby is as
| fast as C now?
|
| I'd much rather see a comparison of idiomatic code in
| different languages. When I choose a language to build
| something in I'm not thinking "How can I write C in this
| language?"...
| sp33der89 wrote:
| Yeah, I would love it if I could just write idiomatic code
| for the platform and it'd be just fast enough!
| kasperni wrote:
| > .NET has been faster than Java on most of the benchmarkgame
| benchmarks for a while, since .net core 3 or so.
|
| And which benchmarks games are those? If I go to to the
| Techempower benchmark and select only C# + Java. Java comes
| on top in every individual category of all the benchmarks.
|
| I'm not claiming that Java is faster than .NET. Just that I
| don't believe one platform is significantly faster than the
| other.
|
| [1] https://www.techempower.com/benchmarks/#section=data-r18&
| hw=...
| grumpyprole wrote:
| Such programs are often specially and painstakingly
| constructed to avoid all the commonly used language
| features that are inefficient. For example, in Java, user-
| defined data types are heap allocated and generic code
| boxes everything, even primitive types (an ArrayList of
| ints becomes unfortuately an array of pointers).
|
| Are these programs benchmarking typical idiomatic Java, or
| just some subset of the language?
| CraigJPerry wrote:
| >> Are these programs benchmarking typical idiomatic Java
|
| https://benchmarksgame-
| team.pages.debian.net/benchmarksgame/...
|
| c# regex redux - 1.42 seconds
|
| java regex redux - 5.31 seconds
|
| Ok... but looking at the code:
|
| https://benchmarksgame-
| team.pages.debian.net/benchmarksgame/...
| import java.io.*; import java.util.*;
| import java.util.concurrent.CompletableFuture;
| import java.util.Map.Entry; import
| java.util.function.*; import java.util.regex.*;
| import static java.util.stream.Collectors.*; ...
|
| It's only using vanilla Java features.
|
| c# ? ... using
| System.Runtime.InteropServices; ...
|
| Interesting, why does it need that?
| [DllImport("pcre2-8", EntryPoint = "pcre2_compile_8",
| CharSet = CharSet.Ansi)] extern static IntPtr
| PcreCompile(string pattern, long length, uint options,
| out int errorcode, out long erroroffset, IntPtr
| ccontext); [DllImport("pcre2-8",
| EntryPoint = "pcre2_jit_compile_8", CharSet =
| CharSet.Ansi)] extern static int
| PcreJitCompile(IntPtr code, uint options);
| [DllImport("pcre2-8", EntryPoint = "pcre2_jit_match_8",
| CharSet = CharSet.Ansi)] extern unsafe static
| int PcreJitMatch(IntPtr code, byte* subject,
| long length, long startoffset, int options, IntPtr
| match_data, IntPtr mcontext);
| [DllImport("pcre2-8", EntryPoint =
| "pcre2_match_data_create_8", CharSet = CharSet.Ansi)]
| extern unsafe static IntPtr PcreMatchDataCreate(uint
| ovecsize, IntPtr mcontext);
| [DllImport("pcre2-8", EntryPoint =
| "pcre2_get_error_message_8", CharSet = CharSet.Ansi)]
| extern unsafe static int PcreGetErrorMessage(int
| errorcode, StringBuilder buffer, long bufflen);
| [DllImport("pcre2-8", EntryPoint =
| "pcre2_get_ovector_pointer_8", CharSet = CharSet.Ansi)]
| extern unsafe static IntPtr PcreGetOvectorPointer(IntPtr
| match_data); [DllImport("pcre2-8",
| EntryPoint = "pcre2_substitute_8", CharSet =
| CharSet.Ansi)] extern unsafe static int
| PcreSubstitute(IntPtr code, byte* subject,
| long length, long startoffset, int options, IntPtr
| match_data, IntPtr mcontext, byte*
| replacement, long rlength, byte* outputbuffer, out long
| outlength);
|
| Aha! It's because the c# impl is really just a wrapper
| round a native C impl of the problem.
|
| In what world is this a useful comparison?
|
| The fastest "real" c# solution is still faster than the
| java one though:
|
| c# (real) - 3.1 seconds
|
| https://benchmarksgame-
| team.pages.debian.net/benchmarksgame/...
| grumpyprole wrote:
| I agree it's not a useful comparison. That's why I don't
| give much weight to statements such as "Java comes on top
| in every individual category of all the benchmarks".
| zigzag312 wrote:
| I agree. That's really not usefull comparision. They
| should create categories for each benchmark, like:
| - very naive code (shortest, most readable & easy to
| write code) - idiomatic code -
| optimized code without other-language-libs wrappers and
| without SIMD, single threaded - optimized code
| without other-language-libs wrappers and without SIMD,
| multi-threaded - optimized code without other-
| language-libs wrappers and with SIMD and/or multi-
| threaded - optimized code with other-language-
| libs wrappers allowed and any other optimization
| technique
| gameswithgo wrote:
| Yes any benchmark will be invalid for some people, such
| is life. If you want to claim or know something specific
| you will have to so your own painstaking investigation or
| find someone who has done that work.
|
| benchmarkgame does not attempt to compare idiomatic
| solutions for languages, it is closer to a "what is the
| best you can do" benchmark
| grumpyprole wrote:
| > It is closer to a "what is the best you can do"
| benchmark
|
| As I suspected. So of course this tells us very little
| about how fast idiomatic code is relative to other
| languages. "The best I can do" is to invoke hand
| optimised assembly language, but rarely is that the right
| choice.
|
| A much more useful test would involve benchmarking some
| similar real world apps that solve the same problem.
| vips7L wrote:
| Generic boxing should be fixed "soon" if they ever
| release Valhalla.
| torginus wrote:
| While I'm not super familiar with the Java world, none of
| the frameworks that have a significant advantage sound
| familiar to me - I'm not sure how mature are they, whereas
| Asp.NET is _the_ solution for writing servers under .NET.
| zigzag312 wrote:
| > And which benchmarks games are those?
|
| https://benchmarksgame-
| team.pages.debian.net/benchmarksgame/...
|
| Be aware that many implementations on benchmarksgame are
| much lower-level and using all kind of performance tricks
| than what you would normally write.
| merb wrote:
| well the same for techemporer benchmarks. sorry but some
| of that stuff is as shady as the benchmarksgame. I really
| don't get it, why people don't create 100% benchmarks
| instead of specialized ones.
| DonHopkins wrote:
| Java's performance hasn't really mattered since Oracle took
| it over. There are things MUCH worse than poor performance,
| and being owned by Oracle is one of them.
| ptx wrote:
| Ownership by Microsoft isn't great either, unless you
| enjoy jumping through hoops to disable their
| telemetry[1].
|
| [1] https://github.com/dotnet/sdk/issues/6145
| jayd16 wrote:
| IMO that link makes .NET look very good. Aspcore, the
| straight off the shelf, obvious choice, is the best
| performing .net server? It beats Jetty and Spring but loses
| to a long tail of less popular frameworks
| symbol-mason wrote:
| You're looking at pretty old results, round 18 was in 2019.
| I also don't think that boutique web frameworks say much
| about the strength of the underlying language or runtime
| (e.g. look at just.js).
|
| What in the Java world is in the same maturity tier as
| ASP.NET is open to opinion, but at least local Java devs
| seem to consider Spring or Micronaut as sane defaults, and
| of course modern ASP.NET runs circles around those.
|
| https://www.techempower.com/benchmarks/#section=test&runid=
| 9...
| gameswithgo wrote:
| This: https://benchmarksgame-
| team.pages.debian.net/benchmarksgame/...
|
| techempower is isolated to web framework testing as far as
| I know
| thrower123 wrote:
| One SQL query going over the network will so dominate any
| micro-optimizations in the framework that it's a little silly
| for most of us to listen too closely when the ASP.NET team says
| they've sped up request processing another 40%. If JSON parsing
| request bodies and reading headers are significant, an API
| generally isn't doing very much.
| oaiey wrote:
| There are two things:
|
| (1) .NET Framework was slow and had some bad habbits (e.g. heap
| allocations, reflections, little optimizations, etc) ...
| especially the web stack. .NET Core/.NET fixes that, issue by
| issue. And since .NET is historically very close to the
| underlying platforms, we now see competitive outcomes (to e.g.
| Go, C++, etc).
|
| (2) Performance = lower CPU/Memory Allocation = more throughput
| = lower Cloud costs. At scale, that makes a huge difference.
| bob1029 wrote:
| > was .NET just alright in performance before all this
|
| For some niche applications (i.e. financial exchanges), .NET 5
| [was/is] arguably the fastest way to implement certain ring
| buffer abstractions because of its interesting blend of
| performance and safety. There is a variant of the LMAX
| Disruptor developed for .NET which leverages the value
| semantics of the C# struct to push things beyond what the Java
| implementations are capable of [0].
|
| Certainly, with enough resources and manual memory management,
| you could best the C# implementations using a C/C++/ASM
| codebase, but this is a tenuous tradeoff with practical risks
| that must be accounted for. [0]
| https://medium.com/@ocoanet/improving-net-disruptor-
| performance-part-3-introducing-the-valuedisruptor-5b467730bbe
| fnord123 wrote:
| Software benchmarks are super subjective. Michael Larabel at
| Phoronix and Isaac Gouy of the benchmark game have done a lot
| in this area. But everyone says you need to take it with a gain
| if salt (which is often true).
|
| There's also TPC-C benchmark suites where people benchmark
| their own software and claim results. Not really independent
| journalists there.
| Rochus wrote:
| > Software benchmarks are super subjective.
|
| No, they are not, but they are just a measurement tool, not a
| source of absolute truth. When I studied engineering at ETH
| we learned "Who measures measures rubbish!" ("Wer misst misst
| Mist!" in German). Every measurement has errors and being
| aware of these errors and coping with it is part of the
| engineering profession. The problem with programming language
| benchmarks is often that the goal is to win by all means; to
| compare as fairly and objectively as possible instead, there
| must be a set of suitable rules adhered to by all benchmark
| implementations. Such a set of rules is e.g. given for the
| Are-we-fast-yet suite (https://github.com/smarr/are-we-fast-
| yet).
| fnord123 wrote:
| It's subjective because it can't be used as a source of
| truth. Of course "I measured X and my results were Y using
| methodology Z" can be a statement of fact but X and Z are
| where the subjectivity lie.
|
| For example, benchmark game allows for warmups and so does
| awfy. This favors jits because it allows them to warm up
| when they would otherwise be slower. This might give the
| mistaken impression that java is a great choice for command
| line tools due to the performance characteristics.
|
| In contrast, most benchmarks I've seen don't use profiler
| guided optimizations for C or C++. Hence the subjectivity.
|
| And the claim of only wanting idiomatic code in awfy. This
| is, of course, subjective as well.
| kaba0 wrote:
| Last I checked benchmark games didn't care about warmups.
| fnord123 wrote:
| You could be correct. The point doesn't rely on what a
| specific benchmark collection in particular does but that
| there is an open discussion on what is appropriate in the
| context of what people using the results find important.
| [deleted]
| jb_s wrote:
| C# was never _really_ slow in the same way as python, etc. And
| anyway 99% of the time you 're gonna be slow because the sack
| of meat writing the program screwed up some aspect of the
| system design or the code. Unless you're using something really
| shit-tier for perf.
|
| The gap closed significantly with .NET core, which is why
| everyone was quite surprised when .NET 5 (the next iteration)
| had a fairly significant speedup in many scenarios.
|
| For reference, Stack Overflow was running on .NET MVC on like 2
| servers pretty recently (with some auxiliary infrastructure for
| CDN and search) and using MS SQL.. I think it might still be
| running on this setup but not 100%. Honestly I have no idea how
| they do it on a .NET monolith but there you go.
| [deleted]
| deanward81 wrote:
| Stack Overflow runs on 9 web servers with (iirc) 48 logical
| cores (2 x 12-core Xeons) and 64GB RAM. Those servers are
| shared by a few apps (Talent/Job, Ads, Chat, Stack
| Exchange/Overflow itself) but the main app uses, on average,
| ~5% CPU. Those machines handle roughly 5000 requests/sec and
| were running .NET 5 as of September 2021 (when I moved on).
| That's backed by 2 v. large SQL clusters (each consisting of
| a primary read/write, a secondary read-only in the primary DC
| and a secondary in the failover DC). Most traffic to a
| question page directly hits SQL - cache hit ratio tends to be
| low so caching in Redis for those hits tends to be not
| useful. As somebody mentioned below, being just a single
| network hop away yields really low latency (~0.016ms in this
| case) - that certainly helps being able to scale on little
| hardware - typically only 10 - 20 concurrent requests would
| be running in any instance at any one time because the
| overall request end-to-end would take < 10ms to run.
|
| Back in full framework days we had to do a fair bit of
| optimisation to get great performance out of .NET, but as of
| .NET Core 3.1 the framework _just gets out the way_ - most
| memory dumps and profiling subsequent to that clearly
| pinpoint problem areas in your own app rather than being
| muddied by framework shennanigans.
|
| Source: I used to work on the Platform Engineering team at
| Stack Overflow :)
| jorams wrote:
| > cache hit ratio tends to be low
|
| That's surprising to read. Is that because of the sheer
| volume of question pages? I don't think I've ever been on
| an SO page that couldn't have been served straight from
| cache.
| tomc1985 wrote:
| Is it? Most people come to SO from Googling their random
| tech problems/questions. Not sure how much value there is
| in caching my random Rails questions, etc
| setr wrote:
| I would expect SO usage to follow a distribution like
| Zipfs -- most visits hit a small subset of common Q/A,
| and there's a ridiculously long tail of random questions
| getting a few visits where caching would do next to
| nothing. I'm fairly positive I've seen some post showing
| this was true for atleast answer-point distributions.
|
| Though I guess it's possible for a power distribution for
| page-likely-to-be-hit to still be useless for caching,
| because I think you could still get that distribution if
| 99% of hits are on nearly-unique pages; with a long
| enough tail, you'd still have only relatively few pages
| worth bothering to cache, but by far most visits are in
| the tail
| sp33der89 wrote:
| That's some great info, thank you!
| foepys wrote:
| > Honestly I have no idea how they do it on a .NET monolith
| but there you go.
|
| Low latency in a single rack can work wonders for
| performance. All those cloud services talk to each other over
| miles of cables and if you can slash latency to
| submillisecond regions, you get less wait time and free
| resources quicker. If you don't distribute your state across
| multiple Microservices, you can also save quite a bit of
| overhead.
|
| Plus hardware is just wicked fast nowadays and SO has a model
| of millions of reads for a single write.
| orra wrote:
| > Stack Overflow was running on .NET MVC on like 2 servers
| pretty recently (with some auxiliary infrastructure for CDN
| and search) and using MS SQL.
|
| They are absolute _beasts_ of machines. But yes, it's
| incredible what you can do with just a few colocated physical
| servers.
|
| It suggests to me lots of dev shops pay the IaaS or PaaS
| cloud tax, long before they would have hit any scaleabilty
| walls with a non-cloud setup.
| danachow wrote:
| A poster above claimed the servers were "48 logical cores
| (2 x 12-core Xeons) and 64GB RAM", which really isn't what
| I would consider such a "beast" of a machine when the RAM
| is in laptop territory, and a modest number of cores for a
| server.
| smackeyacky wrote:
| Nowdays you can purchase that machine on the second hand
| market for something like $200-$300.
|
| They are measurably faster than even contemporary laptops
| though plus you often get ECC ram and raid disk setups
| and the good old Xeon didn't used to ramp up and down in
| speed, it just ran fast all the time. I'd still
| characterise that as a beast, especially on $/performance
| terms (although the power consumption is a worry).
| toast0 wrote:
| Xeon covers a pretty wide variety of chips. Of course,
| the Pentium II Xeons didn't have speedstep either.
| 12-core tells us either fairly high end but older or kind
| of medium-low but newer. Dual socket tells us not the
| really low end Xeon that shares a socket (and probably a
| lot more) with the high end enthusiast desktop chips.
| SideburnsOfDoom wrote:
| > And anyway 99% of the time you're gonna be slow because the
| sack of meat writing the program screwed up some aspect of
| the system design or the code. Unless
|
| Or in my experience, most of the time a service's latency is
| dominated by out-of-process calls, e.g. the time taken to
| talk to other services over http, or to retrieve data from a
| data store. Speeding up the runtime is welcome, but even a
| massive 40% speedup of something that constitutes 10% of your
| total latency is ... closer to a 4% reduction in latency.
| Design matters more.
| emteycz wrote:
| If your program is slow because it's waiting for external
| service response, you're doing programming wrong. Your
| program should do other work in the meantime. I guess
| you're already doing that, but if so, doesn't that
| invalidate your reply here?
| SideburnsOfDoom wrote:
| > you're doing programming wrong. Your program should do
| other work in the meantime.
|
| It's not always true that there is other work to do in
| the meantime. In fact in my experience, it seldom is.
| "you're doing programming wrong" is a very strong
| statement, and not one that I take seriously in this
| context.
|
| Typically you "await" the external service response, so
| that it is not using a thread to do that, and "other
| work" in the form of starting to deal with other requests
| can happen in the meantime, thereby increasing service
| throughput.
|
| But that won't speed up a given request - you can wait
| for an external service more efficiently, but you can't
| wait faster.
|
| Services that do not depend on any other http services or
| any data store do happen, but they are rare in my
| experience (calculation engines, I suppose). So for
| almost every service, when thinking about response time,
| you have to, first and foremost, think about the latency
| of the data stores or upstream services.
| emteycz wrote:
| That is all true, but in the context of .NET performance,
| it's not relevant.
| DeathArrow wrote:
| >If your program is slow because it's waiting for
| external service response, you're doing programming
| wrong. Your program should do other work in the meantime.
|
| What work? Mine bitcoins while you wait the result for an
| API call?
| emteycz wrote:
| Usually processing other requests
| atraac wrote:
| I think any sane person here assumes any IO, especially
| in .NET is already async and allows other requests to use
| that time... Most web apps are still IO constrained.
| DylanSp wrote:
| Looks like SO's architecture is still pretty simple, yeah.
| https://stackexchange.com/performance
| txdv wrote:
| .NET has the ability to handle your memory layout explicitly
| with structs.
|
| They expanded on that functionality with span and made sure
| that the common libraries is implemented using this.
|
| If you do textbook OOP development for everything, you will end
| up with a lot of allocations and what not, which was the case,
| so they went through the entire base class library and rewrote
| all often used methods to be faster.
|
| they even posted a bunch of posts with all their improvement
| tricks: https://devblogs.microsoft.com/dotnet/performance-
| improvemen...
| DeathArrow wrote:
| >If you do textbook OOP development for everything, you will
| end up with a lot of allocations and what not, which was the
| case, so they went through the entire base class library and
| rewrote all often used methods to be faster.
|
| They forgot to tell the others that there is life beyond OOP
| and GoF design patterns.
| mdoms wrote:
| C# is filled to the brim with functional programming
| features. Much of the base class library is somewhat
| functional (although obviously not all or even most, given
| the age of the BCL and stability of the API).
| jayd16 wrote:
| I assume temp solutions and low hanging fruit was added in the
| move to .net core and the new compiler. Now that it's more
| stable, things can get tightened up.
___________________________________________________________________
(page generated 2021-11-21 23:00 UTC)