Not sure which benchmarks you have in mind. Could you provide a link to any of those? .NET's standard library never calls into anything C aside from kernel APIs and certain runtime helpers which is a given.
If you meant BenchmarksGame, then it's the other way around - Java is most competitive where it relies heavily on GC[0], and loses in other areas which require capability to write a low-level implementation[1] that C# provides.
The only places where there are C calls are pidigts[2] and regex-redux[3] benchmarks, in both of which Java submissions have to import pre-generated or pre-made bindings to GMP and PCRE2 respectively. As do all other languages, with varying degrees of "preparation".
Im sorry, but calling out to C libraries — regardless of the language — is cheating. Just because everyone in the competition is on steroids doesn’t mean you got there legitimately.
This is a strange reply given that sibling comment points out it's only 2 out of 10 benchmarks where this is allowed because all languages end up calling out to the same libraries.
Even if you prohibit PCRE2, the .NET submissions using out-of-box Regex engine end up being about 4 times faster than Java.
Surprisingly, even though .NET's BigInteger is known for its inefficiency, it ends up being more memory efficient and marginally faster at pidigits than a Java submission that does not use GMP. The implementations are not line-by-line equivalent so may not be perfectly representative of performance of each BigInt implementation.
My point being - if you look at the submissions closer, the data gives much clearer picture and only supports the argument that C# is a very usable language for solving the tasks one would usually reach for C, C++ or Rust instead.
Its not a strange reply at all. _All_ of those languages are cheating. Those benchmarks are junk because they don't test implementations in the language.
Look at all the programming language implementations that provide big integers by calling out to GMP. Why would it be "cheating" when available to all and done openly? Libraries matter.
No, they do not "frequently just call out to C libraries".
2 of 10 (pidigits and regex-redux) allow use of widely available third party libraries — GMP, PCRE, RE2 — because there were language implementations that simply wrapped those libraries.
Cool! I didn’t see it before, maybe because I mostly use the language vs. language feature. There is no such section there, but it would be very helpful IMO, instead of clicking every solution to check which one is intrinsics free.
Well, it's your site, so you can do what you want with it, but I don't believe what you just wrote is logical at all. Sometimes, you just want to see, in general, how one language compares to another when one uses intrinsics and the other doesn't, without having to click through every single benchmark across multiple versions to find one without intrinsics. This is just bad UX and waste of time.
Look at all the programming language implementations that provide big integers by calling out to GMP. Why would it be "cheating" when available to all and done openly? Libraries matter.
>Most the Debian benchmarks for C# are cheaty too.<
In any case, because the charts are frequently cut & pasted out-of-context they should not include pi-digits and regex-redux data. Now they don't, so thank you.
If you don't think it's appropriate to compare the pi-digits and regex-redux programs, simply ignore them and compare the other 8!
I have friends who work in InsuranceTech and they use satellite images of houses when someone apply for home owners insurance. They've said it flags people with trampolines all the time.
My insurance company asked about that when I got the policy, I said Yes we have one and it was not an issue. Perhaps they are charging me a higher premium, but not enough that I noticed.
Though we no longer have it, so perhaps I should mention that next time I meet with my agent.
You can't compare 10 years ago Java to current Go. 10 years ago was Java 8, we are currently on Java 23. The performance difference is massive between these 2 runtimes especially between the available garbage collectors.
Hazelcast has a good blog [0] on their benchmarks between 8 and some of the more modern runtimes, here is one of their conclusions:
> JDK 8 is an antiquated runtime. The default Parallel collector enters huge Full GC pauses and the G1, although having less frequent Full GCs, is stuck in an old version that uses just one thread to perform it, resulting in even longer pauses. Even on a moderate heap of 12 GB, the pauses were exceeding 20 seconds for Parallel and a full minute for G1. The ConcurrentMarkSweep collector is strictly worse than G1 in all scenarios, and its failure mode are multi-minute Full GC pause
Sometimes barrier to entry is good. For example, both npm and cargo struggle with package name squatting and malicious packages that are miss spellings of common packages.
Pedantically, that's only one way to resolve a go package - and for sure the more obvious[1] - but the most famous one I know of is gopkg.in/yaml.whatever that uses a <meta> tag to redirect to its actual GH repo, which only the deepest golang ninja would know how to use: compare view-source:https://gopkg.in/yaml.v3 with view-source:https://gopkg.in/yaml.v3?go-get=1
I know this is a troll comment, but the situations you see these variables are in highly-polymorphic( generic ) code in which there are no more descriptive names.
It’s like the use of `T` as a name in most Java or C++ generics.
This stuff is utterly incomprehensible to me as well, but I don't think Haskell is trying to be a mainstream use-it-for-everything language. It does get plenty of real-world usage and the people who like it really like it, so for a language so complicated to get as much use as it does sounds like it "took off" perfectly fine
Exceptions are great. Whats not great is not having them expressed in the type system via checking. I think Kotlin's greatest mistake is not improving upon checked exception handling. Though it looks like they're going to be moving forward in the future with errors as values via union types [0]. Scala also has some experimental work around putting exceptions into the type system via capabilities [1]. I really like Scala's solution because it lets checked exceptions work across higher order functions and Scala has enough syntax sugar to make handling exceptions pain free.
I have LOTS of opinions about this topic, but I'll try not to ramble.
I always found checked exceptions (Java) to be mostly fine/good. I sincerely believe that a lot of the hate for them in the last decade is just cargo culting. I get a small dose of schadenfreude when I see someone doing mental contortions to simultaneously explain why Rust's Result type and handling (and similar features in other langs) is awesome, and Java's checked exceptions are terrible and definitely not 95% similar in DX and semantics...
The one point against checked exceptions for me is that if I'm trying to model a domain failure, it really doesn't make sense to collect a stack trace. For example, if I'm writing a logIn function that takes a username and password, then it's totally normal for the username and password to be invalid. Why would I want to spend the CPU time collecting a stack trace when someone simply typed in an incorrect password? Do we want to collect a stack trace when the password is correct and the user gets logged in?
So, in that sense, I do have a small preference toward expected failure modeling to be somehow different from "true" "exceptions".
I do also agree with you that Kotlin's biggest original sin was to throw away checked exceptions without replacing the concept with ANYTHING. Of course, as you've pointed out, they're backtracking on that somewhat by trying to add this concept of errors as a kind of ad-hoc union type. (aside: they also backtracked on their choice to not have type classes because "extension functions are good enough" by trying to do context receivers, which is ending up being really hard and probably more complex than just doing damned type classes in the first place...)
I do kind of like the direction that Swift is moving with finally adding specifically typed throw signatures (essentially Swift now has checked exceptions, but they're aren't actually traditional exceptions because they don't collect stack traces and unwind the stack- they're just syntax sugar around a Result/Try type).
But, my prediction is that the pendulum is starting to swing back in favor of checked exceptions. In the next decade we'll continue seeing languages adopt mechanisms that are essentially checked exceptions. But, they will be slightly different and definitely called something else so that we don't have to admit that we were wrong to shit on the idea for 15 years.
EDIT: Also, I do follow Kotlin developments closely, but I haven't actually worked in Scala for several years, so I had no idea about this capabilities idea. Thanks for the link.
I have a ton of opinions on exceptions too, mostly because I love them.
FWIW you can override the stack trace collecting behaviour of Java exceptions. Not collecting the stack trace makes exceptions really fast and thats actually how Scala is implementing their boundary/break feature. I do kind of wish that Java could backtrack and that the stack trace would only be filled in on RuntimeExceptions that are true panics.
I really feel like Java just needs investment on the language syntax to make checked exceptions good. Things like `try!` or `try?` from Swift would be nice and taking Scala's try { as an expression with case catch blocks would make it really fluent. I think most devs can agree that they want to know what errors can happen, but currently in Java its just a pain to deal with them. Brian Goetz originally had some ideas around evolving the switch construct for this [0] so at least we know making exceptions better is on his radar.