The future of .NET
haacked.com
haacked.com
The default configuration for Mono is a blend of fast startup, and decent code speed. You can tune these parameters depending on your use profile which can range all the way from: startup is the most important factor to high performing code at any cost.
In general the language Shootout compares the default configuration of Mono vs all kinds of other configurations.
Those interested in Mono for High Performance Computing will be interested in some options:
* LLVM: passing the --llvm flag to Mono instructs Mono to pass the code to the LLVM optimizing compiler, and will run your program through every heavy weight optimization that LLVM supports. This comes at the price of slow startup times (much slower), but for HPC or server loads, the extra time it takes to JIT is worth it.
* Unsafe mode. If you have battle tested your application and you never get an IndexOutOfRange exception, you can instruct Mono to never perform array-bounds checking. Arrays bounds checking basically ensures that every time you do array [i] that the value of "i" is within the range 0..array.Length. This can be expensive, but makes your program safe.
Passing -O=unsafe basically gives you the same semantics of C or C++: you know what you are doing, and you really are not too much into safety.
With LLVM + unsafe access, as far as the LLVM optimizer is concerned, there is really no difference between C# and C++ code, and you will get the same performance for compute intensive tasks. The only case where the dynamic of performance would come into play is when the garbage collector kicks-in, vs manual memory management. That in general depends a lot on the kind of app you are building. Many HPC applications preallocate all of their memory before large computations anyways, so in those apps the GC makes no difference.
The third optimization is to use Mono's new garbage collector, which gives in general a nice 2x performance boost to memory intensive applications. In general, the new GC is great for memory intensive applications, while the old one is better for pure computational applications that are not memory allocation bound.
With Mono 3.0, we also have implemented the inlining attribute (new in NET 4.5), which developers can use to force a function to be inlined, something that before was entirely based on JIT heuristics.
And of course, you can tune the individual Mono or LLVM optimization options.
Is .NET really that great a platform that these OSS devs will continue to support and improve it after it's been abandoned by Microsoft?
Not saying that's going to happen—but as a .NET dev myself, I'm curious. If it did go that way, I think my only motivation to continue using .NET would be that I don't want to rewrite years worth of code.
However I think that is extremely unlikely, no doubt it will be evolved in that annoying Microsoft way but completely abandoning it would make no sense at all.
Right now tho probably the only popular use of non-ms .net (mono) is Unity (which is btw a pretty big deal in the games industry).
Still though, this means that Mono is being used with Unity on Linux. Unfortunately not the development part.
Mono, I'm guessing you mean. Mono's not great for server applications, it's best used for desktop apps. If you want to write server apps, you need to be using the official Microsoft implementation. (Which is becoming the red-headed stepchild platform in Microsoft's strategy apparently?)
> Second, performance is as good or better than pretty much anything else that is not optimized C or C++
Lets find out:
http://shootout.alioth.debian.org/u64q/which-programs-are-fa...
List of things that are faster than C#:
Fortran, Ada C, C++, ATS, Java, Scala, Common Lisp (SBCL), and Go.
List of things that aren't faster than C#, but are close enough to call it a wash:
Haskell, Ocaml, Clojure, Pascal, Racket
I'd say you have some choices if performance is an issue yet C#'s is acceptable.
>It's a very beautiful language, much nicer than Java used to be
No, yes. It's nicer than Java, it's not "very beautiful". Try working through the Little Schemer to see a beautiful language.
>And innovation continues: If you've worked with node.js for some time, you will see how ugly code becomes where everything is done using callbacks.
Bizarre strawman? What? I don't like Node.js either, but what's your point? A lot of languages that aren't C# have better concurrency idioms than Node. You know, like all of them that aren't C#.
> C# just now introduced new syntax where you can basically write code in a linear way and the nesting of callbacks is done by the compiler.
Yeah, uh, Scala has had this since forever. And Lisp. And Scheme. And Clojure. And C++. And Node.js (ugh).
For a C++ example, look at Tame/Tamer, SFSLite, etc.
For anything else, google "promises".
There is nil that is special about C#, it's a slightly nicer Java without a home or a stable implementation. If neither of those things matter to you and you wanted a Java++ that wasn't as ambitious or intellectually challenging as Scala, then you've found your language. Godspeed.
Your comment just tries to derail the discussion by bringing up Scheme or Lisp in a context where only languages are considered that are widely used in the industry. Otherwise, how could the word "abandon" possibly apply?
This language shootout has been criticized before. Except for optimized C and C++ there is no popular language (I'm talking about the performance that is due to the design of the language, _not_ a particular implementation. For example dynamic typing is necessarily slower.) that is faster than C#. Try unsafe C# and you know what I mean.
Bringing up Scheme here is entirely inappropriate. It's common wisdom that Lisp and Scheme are more beautiful, but this article is about a language that is supposedly "abandoned", because it may not be mainstream enough anymore at some point. If C# is abandoned, then what can you say about Scheme?
As far as node.js is concerned, it's not a strawman: In fact, the people who claim that MS abandoned C# think that they want to replace it by Javascript. MS even supports node.js in Azure.
"concurrency" is not the same as asynchronicity, which is what I was talking about. And promises are not even close what C# 5.0 tries to achieve. In fact, promises have been present since .NET 4.0.
Finally, please explain how Scala is "intellectually challenging". This is not my experience.
(throwaway account due to procrastination setting)
Criticism can be uninformed, out-of-date, self-serving, mistaken... ;-)
Er, but you can't just completely disregard implementation, because it really matters in practice. You're not going to get a lot of adoption simply because your language is theoretically better/faster/...
In these language shootouts, Lua, a dynamically-typed language aimed at small size and simplicity, regularly beats out C#, because Lua has LuaJIT[+], which is a really good implementation, whereas C# for many people means Mono, which is at best an "OK" implementation.
It's the same as with algorithms: big-O complexity is obviously important, but it isn't everything; for real-world uses, the constant factors may make all the difference...
[+] The standard Lua implementation is also very good, but it's a more typical VM, and while very fast for a non-JIT VM, can't match LuaJIT in many cases.
C# has one of the best standard libraries out there (well documented, rather well designed, batteries-included, etc)
C# has a decent set of relatively modern language constructs, yet is easy enough to learn for a very large group of programmers.
C# is faster than most (but not all) languages sporting a comparable set of high-level features.
C# has excellent tool support, and was designed for enabling such tool support, making refactoring and code navigating easier than in any other language except Java.
C# has a large ecosystem and user-base, making it easy to find answers to problems and components that solve problems not covered by its standard library.
None of these items, in isolation, are special. Java arguably has a stronger ecosystem, but is a less powerful language. C++ is faster, Scheme is more elegant (according to many), and so on. But I know of no other language that has all these areas covered so well simultaneously. Scala comes close, but is arguably more difficult to learn, and lacks on the ecosystem area (not in terms of library support, but in terms of best practices and large user base). This might change, which would be lovely.
All other languages you mentioned strongly lack on at least one of the above-mentioned aspects.
I'm not saying that C# is god's gift to mankind and the only good thing out there. I'm only saying that you're dismissing it too easily.
There are sufficient people out there who really like this combination of features to support a vibrant open source community. Which is why this community exists. Why dismiss something that exists and works well?
In fact, if MS were ever to make .NET/C# legacy like some people seem to believe "WinRT allows horribly HTML5 apps" implies, I bet JetBrains would just bolt ReSharper onto IDEA and off we all go.
Please tell us specifically which Java programs in the benchmarks game, you say, are written directly on top of primitive arrays.
That doesn't seem much more than a big fat assumption - aren't there also going to be many situations when the right thing to do is use an array?
Sure, with a language that has super slow boxing semantics....
Just look at BinaryTree. The benchmark would show a very different picture if it would compare Tree<Integer> implementations instead of allowing a primitive int.
What I'm doing is responding to your claim -- write everything directly on top of primitive arrays (as is done on the shootout).
>> When you need a hash table <<
Task description from the home page -- "Repeatedly update hashtables and k-nucleotide strings"
fannkuch-redux is all about "Indexed-access to tiny integer-sequence" so it really is all int[]
meteor-contest int[] byte[] OkPieces[] SPiece[] Piece[]
fasta byte[] double[] frequency[]
spectral-norm double[] Approximate[]
reverse-complement byte[] int[] ArrayList<byte[]> LinkedList<Integer>
mandelbrot byte[][] double[] Thread[]
and then the ones you didn't mention:
binary-trees custom binary trees
chameneos-redux ArrayBlockingQueue<Creature> Creature[] Thread[]
knucleotide byte[] int[] LinkedBlockingQueue<AbstractCounter> ArrayList<LinkedBlockingQueue<WorkChunk>> AbstractCounter[] ArrayList<CountString> StringBuilder TreeMap<Integer, Map<Byte, AbstractCounter>> HashSet<AbstractCounter> ByteBuffer ArrayBlockingQueue<Runnable>
pidigits long[] Semaphore[] exec[]
regexdna Thread[] StringBuffer HashMap<String, String>
thread-ring custom ring (also Node[] LinkedList<Node>)
c# is easy to learn, easy to implement, and easy to handover, to a team, a junior etc.
It is easy to wrap up dev of an application in .net. Super easy. I've done some awesome things in c#, and love the language. Why, cause when it is easy to ship working software, what's better than that.
So add "ATS, Java, Scala, Lisp, Go" to "a wash" and we're left with "Fortran, Ada, C, C++" as "faster".
It is a "very objective view of what is possible" now on Ubuntu.
It will also likely do poorly, because LLVM is slow to startup, but the resulting code is nothing short of God's own fine tuned code.
Alternatively, you can pre-compile the code with AOT:
mono --aot --llvm -O=unsafe sample.exe
But AOT code requires the sacrifice of a register to the gods of position independent code. Kind of the same perf hit you get from gcc -fPIC foo.c
/usr/local/src/mono-2.11.4/bin/mono --gc=sgen --llvm spectralnorm.csharp-2.csharp_run 5500
As you can see --llvm is used.
(Since June 27, 2012)
This sample shows the startup cost of LLVM. It is not ideal for short-running tasks, as just JITing this code with LLVM increases the overhead for this test by 0.42 seconds on my machine (iMac, 2010).
Might be worth running this for a longer period of time, they will basically converge.
LLVM is great for HPC, when this startup cost is not a problem.
The Mono 3.0.0 measurements are made with LLVM enabled.
Let me help you.
He is talking about C# async, you can read more about it here:
https://github.com/okws/sfslite
http://www.read.cs.ucla.edu/tamer/
http://stackoverflow.com/questions/5579602/what-is-the-scala... You will note that it's a comparison between F# and Scala.
http://dispatch.databinder.net/Dispatch.html The standard HTTP client of choice is async, although the simple API wouldn't necessarily tell you as much.
https://github.com/ztellman/lamina From the clojure people. Agents bear mentioning too.
The Scala question seems to have too many caveats, you should read the comments as there is no full translation of the F# async translation in the stackoverflow question. The answer with the most question states "with some important features lost". The comments on the question and answers should be read as well.
Cute Http Stack though.
The lamina code runs the code on a separate thread (https://github.com/ztellman/lamina/wiki/Introduction) hardly what C#'s async does. Not that I care that much, but that is what the docs say.
You forgot to show us how Node.js is supposed to support async-like programming without callbacks. I suspect in a rush to enumerate a bunch of languages, you merely listed everything you could think of and hoped some of it would stick?
You are kind of overlooking the JVM here.
Also Mono is kind of portable, and .Net on windows is fast, but you can't really have both (even if Mono performance is decent)
I did criticize OP too, but you'll note that he made a point of saying that C# was nicer than Java. The fact that he isn't aware the JVM has more than just Java, is an issue I attempted to redress.
The difference should be visible in practice, though. AFAIK, it is not really visible, though. That probably is because the JVM has been tuned longer.
That is why even the simplest benchmarks involving value types tend to beat Java's optimized code gen.
We cheat, because we are able to use the work of the brilliant hackers over at LLVM.
So in addition to Mono's code gen, you can opt into using LLVM, like this:
mono --llvm myBenchmark.exe
It take a lot longer to start, compared to Mono's fast-JIT, but for any long-running HPC, financial simulation or physics simulation, you can not get better than this.
The speed of LLVM, the safety and productivity of C# (or F#)
The big promise of .net, though, is better cross-language integration. Scala is in some sense compatible with Java, but a lot of the library is different (e.g. collections); in practice interop is full of awkward edge cases. F#/C# should behave better, though I haven't used them enough to say how true this is in practice.
If you need to get a prototype up and running quickly, you can do that with a minimum of fuss. Plus, C# is actually a pretty solid language.
I haven't heard that anywhere. They are tightening the APIs for security and there is the usual rebranding (Silverlight apparently is out) together with the addition of 'our new things are brilliant, unlike the things that we, lasy year, called our new brilliant things', but AFAIK, Microsoft bet and is still betting heavily on .NET.
Anybody know what this statement is based on?
Looking at the apps in the Store though, and talking to insiders, and the picture is clear that over 80% of the apps in the Windows 8 Store now are XAML/C#. I've been tracking this for the last few months, and the trend is continuing.
This is currently not possible using mono develop; the portable library support doesn't exist, which means your 'shared' libraries can't do things like use sqlite or linq; in fact, they can't have references to anything other than other portable libraries at all. Like, for example, system.collections.generic.
It's possible to build applications without using visual studio at all (minus winrt apps, you need VS for that).
I know you're wrong about sqlite and linq as I've used them on both .net and mono. I think you're using the phrase "portable library" incorrectly. In the .net world, these are libraries created by microsoft that use the more limited version of the framework on their other platforms. For example, windows phone 7 and win rt use different portable libraries (a pain to manage, admittedly).
(ie. PCL --> One code base that compiles and runs on multiple c# runtimes; a key feature of writing cross platform c# applications)
Support is currently limited, see: http://docs.xamarin.com/ios/tutorials/Cross_Platform/Buildin...
Of course you can copy and paste your code into different projects manually, and compile it for a specific runtime. Or... you can use visual studio.
My personal preference is to just link source files and use partial classes (very much like the Linux kernel uses "pluggable" files to create a kernel) to create a product.
The problem is that there is no "Portable Class Library", there are dozens of profiles, and you need to pick the subset you want, for example: "Desktop and Windows8" is a much larger profile than "XBox and Silverlight", the subsets are different.
If you ignore Xbox and Silverlight, you pretty much have the whole stack everywhere.
Because I use LINQ and Sqlite on my shared code between Android and iOS. And you can even use Sqlite on Windows Phone (using Sqlite-cs) and Win8.
There's the [P/Invoke interop assistant](http://clrinterop.codeplex.com/) which can help you create a wrapper for C APIs, and the mono team have created [Cxxi](https://github.com/mono/cxxi), a binding generator for C++ APIs.
There is a whole new set of framrworks for building web applications. My favorite frameworks include:
* ServiceStack: everything you need to build sophisticated web apps with a clean, beautiful API.
* WebAPI: if you want to get a more "Enterprisey" set of APIs
* ASP.NET MVC: .NET's approach to Ruby-on-Rails-esque development.
* SignalR: real-time web applications.
But some people never learn :-)
The fact is that as a C# developer currently focusing on mobile development, I am very happy these days.