4 ms·
I broadly agree with your comment but want to correct some misconceptions: - If we're going to talk about benchmarks games I'd need to see evidence, it's hard
by yawaramin 5y ago
I broadly agree with your comment but want to correct some misconceptions:
- If we're going to talk about benchmarks games I'd need to see evidence, it's hard to believe .NET can offer anything more performant than say Vert.x or Micronaut :-)
- Scala has type inference (not HM, but then again almost as good)
- Futures/async/await are ubiquitous in Scala, the standard library ships with a very reasonable implementation of Future, and there is no shortage of third-party async libraries/runtimes, even leaving aside Akka which has actually been ported to Akka.NET
- Scala has value types
- No compile-time generics but powerful equivalent capabilities like type classes
- Scala has tail (self-)recusion
- JVM has plenty of low-level performance tricks
- Scala is plenty close to the JVM, I don't know how it is with F# but I know for sure e.g. things like Scala lambdas map exactly 1-1 to JVM lambdas
- Not sure when C# got 'self-packaged bundle' capabilities but if we're talking about that kind of thing, there is GraalVM and you can compile Scala apps to native binaries (as long as they don't use runtime reflection and a couple of other restrictions). E.g. https://cloud.google.com/blog/topics/developers-practitioners/modern-web-architecture-jigsaw-puzzle-made-easy-you https://cloud.google.com/blog/topics/developers-practitioner...
- the_only_law 5y ago> you can compile Scala apps to native binaries I was actually rather disappointed after looking at Scala native. From what I gathered you can’t create libraries (shared or static) only direct executables.
- yawaramin 5y agoI wasn't referring to Scala Native, I was talking about GraalVM. But either way, compiling to native executables is a huge deal for simple deployment, even without being able to create libraries.
- throw868788 5y agoA bit late but I can comment to be informative. > I'd need to see evidence, it's hard to believe .NET can offer anything more performant than say Vert.x or Micronaut :-) Benchmarking is interesting because it depends on your case, and the tricks used in the benchmark. Techempower has proxy benchmark at https://www.techempower.com/benchmarks/#section=data-r20&hw=ph&test=plaintext https://www.techempower.com/benchmarks/#section=data-r20&hw=... for just the web layer which shows aspcore quite high. https://benchmarksgame-team.pages.debian.net/benchmarksgame/fastest/fsharpcore-java.html https://benchmarksgame-team.pages.debian.net/benchmarksgame/... I note it isn't as good with DB queries (DB framework) than Vert.x which gives points to Scala for db like APIs but there's tricks there too. Benchmark Game seems to have F# compare well with Java and OcAML (low level non-idiomatic code there I'm sure too). Been meaning to try Vert.x. - Futures/async/await are ubiquitous in Scala I need to look into this more but using them in the past it seems very library based (map/foreach/for comprehensions/flatMap/etc) whereas the .NET implementations tend to be like co-routines (state machine) that are compile time constructs with associated perf benefits. It adds a lot to performance; you want the async primitive to be as cheap especially if doing them in hot loops - .NET articles are full of Task/Async patterns and their benchmarks and optimizations to Tasks are constantly ongoing. > - Scala has value types Not in a way that I use them I guess. https://docs.scala-lang.org/overviews/core/value-classes.html https://docs.scala-lang.org/overviews/core/value-classes.htm... shows quite a few limitations. They may be overcome with Project Valhalla? but it isn't there yet - its a JVM limitation not a Scala one. They seem to be extremely limiting compared to .NET types where you can compose things together (more than one value, etc). I use this for math ALL the time avoiding any GC events at all - there's a lot of cases for quick stack allocated values that can cross function boundaries. I've worked on the JVM - its possible but much harder with uglier code. .NET seems to have many more ways to avoid "boxing" than the JVM when the JIT doesn't catch it. Especially with generic methods (unless inlined). Basic tuples, ValueTasks (like futures) and such all use this construct at times. - JVM has plenty low level performance tricks Sure it does. I'm liking the new things in .NET Core like Span making it "safe" to do them vs Unsafe and interop. Re-using memory (slicing parts of strings without cloning chars), etc in a safe manner is a simple example but there are others. > Scala is plenty close to the JVM Plenty of its abstractions however however require allocations and objects (e.g. implicits everywhere) - futures being one. IMO maybe its just me but it is easier to reason about F# performance. An example in F# would be that many allocations are only allowed explicitly (e.g. math conversions) - it actively discourages implicit behaviour for simplicity I feel. e.g. Auto-Boxing in erased generics has caused perf problems in some JVM programs I used to work on. Both platforms are capable and have their own pitfalls of course. - self-packaged bundle' capabilities .NET Core feature.