Performance: Compile in VS, Run in Mono on Windows and Linux - c#

I have the following questions:
Is it possible to compile a C# project using VS.NET, and run it on mono?
Are there any performance benefits associated with approach 1 (vs compiling with the mono compiler)?
What about running the output .exe/.dll on linux? And what are the associated performance characteristics?
Thanks

Yes, you can do that. It should work unless the code uses some framework elements that are not implemented on mono.
Not that I am aware of.
Not sure what the difference between #3 and #1 is. If you are referring to using mono to compile on Windows, then porting it to linux, it should still work the same. Both compilers generate essentially the same IL code.

1:
Yes. The compilers compile into IL code, which runs in either system.
Not every library is implemented in Mono, but those that are should work seamlessly. Also, the code has to be written to be independend of the system to work properly, for example:
Use Path.DirectorySeparatorChar and Path.Combine to form file paths, instead of using the string literal "\" or "/".
Use the BitConverter class to do byte manipulation that is independend of big-endian / little-endian achitecture.
2:
There may be some differences in what code the compilers generate, but as almost all optimising is done by the JIT compiler that should rarely make any measurable difference.
3:
The exe and dll files does not contain native code, they contain IL code. The native code is generated by the JIT compiler when the exe/dll is loaded.

To expand on others answers:
For point 3. Yes there will be a performance difference when using MSCLR vs Mono, and no, I don't know what it will be. Maybe nothing, maybe little or perhaps one is vastly faster - you'll have to profile your specific application.
Note also, that notwithstanding the speed of the code made by the JIT compiler, the libraries will be implemented very differently and will almost certainly have varying performance characteristics.
If you plan on supporting your application under Mono, you will need to run performance testing there as well as MS CLR.

I don't know about the performance but this article attempts to show how to compile the MonoDevelop tool under vs. This should give you some idea as to what the differences will be.

Related

Why is difficult to disassemble native Win32, but easy to disassemble .NET app?

Why is the process of disassembling a native Win32 image (built in C/C++ for e.g.) miles more difficult than disassembling a .NET app?
What is the main reason? Because of what?
A .net assembly is built into Common Intermediate Language. It is not compiled until it is about to be executed, when the CLR compiles it to run on the appropriate system. The CIL has a lot of metadata so that it can be compiled onto different processor architectures and different operating systems (on Linux, using Mono). The classes and methods remain largely intact.
.net also allows for reflection, which requires metadata to be stored in the binaries.
C and C++ code is compiled to the selected processor architecture and system when it is compiled. An executable compiled for Windows will not work on Linux and vice versa. The output of the C or C++ compiler is assembly instructions. The functions in the source code might not exist as functions in the binary, but be optimized in some way. Compilers can also have quite agressive optimizers that will take logically structured code and make it look very different. The code will be more efficient (in time or space), but can make it more difficult to reverse.
Due to the implementation of .NET allowing for interoperability between languages such as C#,VB, and even C/C++ through the CLI and CLR this means extra metadata has to be put into the object files to correctly transmit Class and object properties. This makes it easier to disassemble since the binary objects still contain that information whereas C/C++ can throw that information away since it is not necessary (at least for the execution of the code, the information is still required at compile time of course).
This information is typically limited to class related fields and objects. Variables allocated on the stack will probably not have annotations in a release build since their information is not needed for interoperability.
One more reason - optimizations that most C++ compilers perform when producing final binaries are not performed on IL level for managed code.
As result something like iteration over container would look like couple inc /jnc assembly instructions for native code compared with function calls with meaningful names in IL. Resulting executed code may be the same (or at least close) as JIT compiler will inline some calls similar to native compiler, but the code one can look at is much more readable in CLR land.
People have mentioned some of the reasons; I'll mention another one, assuming we're talking about disassembling rather than decompiling.
The trouble with x86 code is that distinguishing between code and data is very difficult and error-prone. Disassemblers have to rely on guessing in order to get it right, and they almost always miss something; by contrast, intermediate languages are designed to be "disassembled" (so that the JIT compiler can turn the "disassembly" into machine code), so they don't contain ambiguities like you would find in machine code. The end result is that disassembly of IL code is quite trivial.
If you're talking about decompiling, that's a different matter; it has to do with the (mostly) lack of optimizations for .NET applications. Most optimizations are done by the JIT compiler rather than the C#/VB.NET/etc. compiler, so the assembly code is almost a 1:1 match of the source code, so figuring out the original is quite possible. But for native code, there's a million different ways to translate a handful of source lines (heck, even no-ops have a gazillion different ways of being written, with different performance characteristics!) so it's quite difficult to figure out what the original was.
In general case there is no much difference between disassembling C++ and .NET code. Of cause C++ is harder to disassemble because it does more optimizations and stuff like that, but that's not the main issue.
The main issue is with names. A disassembled C++ code will have everything named as A,B,C,D,...A1, and etc. Unless you could recognize an algorithm in such format, there is not much information you could extract from the disassembled C++ binary.
The .NET library on the other side contains in it names of methods, method parameters, class names, and class field names. It makes understanding of the disassembled code much easier. All other stuff is secondary.

How does the Java Runtime Environment compare with the .NET framework in terms of compilation process?

I am learning about the conversion of source code to machine code via the .NET and JRE Frameworks. To start off I did some research comparing the two processes and created this diagram. I need some help in criticizing its correctness, and more importantly adding any serious things I missed out to better understand the compilation pathway.
Both .NET and Java compile down to bytecode, that is an intermediate language which contains instructions for a virtual machine. It's not machine code because it cannot run directly on a physical machine. What happens instead (today at least; Java has a darker history in this regard) is that at runtime a just-in-time compiler is run which translates the VM instructions into native code that is then run directly. This has a major performance benefit over only interpreting it.
They differ in this regard a little. Oracle's Java implementation (Hotspot) uses a clever mix of interpretation, measuring and JIT compiling just the parts that are heavily used and interpreting otherwise. This is to reduce initial impact by the JIT compiler (which needs to run upfront otherwise, lengthening process startup time) while still allowing good performance where needed. .NET on the other hand always JIT-compiles all code that is used (unused code is not compiled, though).
Edit (2019): By now .NET also has tiered compilation where depending on what code runs a lot, that code will be optimized further.
As for a question you mentioned in your comments: Yes, the CLR and the JVM are the platforms such programs are run on. A virtual machine is a machine too, just less hardware-y. They both are tightly integrated with a corresponding framework, the Base Class Library for .NET and the Java class library for Java. Those are frameworks.

Porting C++ to C#

C++ and C# are quite simmilar programming languages, in my opinion. If a C++ code needs to be ported to platform where C# is the only supported platform, how much work will need to be done?
Should I get ready, that most of the C++ code will need to be rewritten to C#? Or, because of language simmilarities, should refactoring be quite easy and straightforward?
I am aware, that it will depend on the application itself, but I am asking in general.
I have done a major port of a C++ application to C# recently. Overall I thought it was a pleasant experience. These are the steps that I took, they might or might not apply to your application.
Get the "scaffolding" in place in C#, design your architecture. This is the time to get in major architecture changes from the existing application if you choose to do so.
Get your tests in place. I can't over-emphasize this one. Since you are porting an existing application you should have a set of tests already in place that verify the correct behavior of your application. You can and should reuse these tests for your C# application. This is the one thing that gives you an edge when porting - you know (and have written) already many of the tests you want. Start porting your test project.
Put in method stubs for your C# methods that reflect the existing C++ methods. Given the framework support in C# some methods might not be needed at all anymore, or are very simplified - this is the time to decide.
Copy and paste. Yes I used copy and paste for most of the C++ code - all the flow statements basically can be reused if you are careful. Once pasted go through line by line, many things like use of pointers etc. must be rewritten to use a equivalent C# type.
Once you have re-written a method in such a way, do the obvious re-factoring given the framework support / helper classes you might have been lacking in C++ but are readily available in C#. Also naming conventions for variables etc. can be changed here, should be straightforward given the built in support for this in VS 2010.
Run your tests! Test early and often that the overall framework you have in place so far produces the exact same output as your C++ application which you can use as a reference. This is also the time to add missing tests.
Refactor, Refactor, Refactor. Every application ages, and so did your C++ application most likely. Look closely at the underlying design and simplify and remove as much as possible. Verify at each step by running your tests.
First thing first, this is porting and not refactoring. Also I think it's an extremely bad idea.
It is true that you could (with a lot of work) port C++ to unsafe C#, but saying that the syntax is very similar is a bit of a stretch. In fact, following the same line of reasoning you could port C++ to any other C derived language, and it would be equally painful.
Again, if you do it expect a shedload of rework. It's more than likely gonna take you more than re-coding it from scratch using the existing code as mere model, which is in my opinion a better and less messy option.
Just compile the C++ code with the /clr compiler option. That will translate the code to IL, it can execute on most any .NET enabled platform. There are very few C++ constructs that cannot be translated, it would have to use non-standard compiler extensions like __fastcall.
However, I suspect that you will find out that the platform requires verifiable code. Which is the common reason why a platform would restrict code to a .NET compliant language. I cannot guess at this since you didn't mention the execution environment. Native C++ translated to IL is not verifiable due to pointer manipulations. If that's the case then you are looking at a pretty drastic rewrite.
I'd be interested to know where C# is the "only supported platform".
The problem of rewriting in a new language can be whether you need to rewrite every single part of the code and cannot use any of the old code at all. Sometimes it is best, even when doing a rewrite, to make it more of a refactor: rewrite some parts of the code, move others. The existing code is known to work and can be tricky to reproduce. And it takes time. There needs to be a good reason to do a full rewrite.
.NET supports a version of C++, and Visual Studio also comes with Visual C++ to build standard C++, so consider whether or not you can make this a phased transformation, and whether or not you really have to rewrite the whole thing.
Porting C++ code to C# will not be that hard, assuming that all your dependent libraries have existing C# counterparts. Lack of dependencies is the most likely pitfall. The core concepts of your program, such as inheritance, heap, references, data structures, should be fairly easily translatable.
This is assuming that you don't invoke any specific low level behaviour such as custom memory management, because C# does not really support that kind of thing and you could have a serious problem there.

Cross .NET Languages Performances

Does using Multiple .NET Languages (Delphi, VB.NET, C#) into the same application (but in differents class library of course) can down peformances compared to a full C# application for example ?
I'm not an expert on the CLR, but I would guess that you will have very similar performance. All the languages compile to MSIL which runs on the CLR. There could be differences in performance depending on the MSIL generated from the compilers. i.e. It's possible that similar code in VB.NET would compile to less (or more) optimized MSIL than the C# compiler.
Although I don't have any benchmarks off hand, I would say that for the most part it shouldn't. Those different languages all compile the code into CIL, so you should be fine.
One place where this would be different is with the languages that are run on the DLR (IronPython, IronRuby, etc.). They're compiling in the use of some features that aren't present in the CLR and that are more costly operations.
Without any hard evidence to prove this, I am going to just make an educated guess and say no. Since your assemblies get compiled down to almost identical IL, you really aren't going to see any performance degradation from using different implementations of a CLR language.
As has been mentioned by the other answers, all the code ends up compiling down to CIL, so provided the code is done consistently across languages (and you don't have compiler optimizations enabled) the resulting IL will come out pretty identical. Now if you have the same code and make use of compiler optimizations you could wind up with a differing set of IL that would have an affect on performance.
As was brought up by this answer, the DLR could have an effect on performance. Most of what I've heard/read about it though stated the performance impact is mostly negligible.
I agree with the other answers. The only thing that could affect performance is that if you're loading many assemblies, you will see an overhead. However the overhead is not related to the language used to create the assembly, but if you mix a lot of different components you may end up with more assemblies than otherwise. If that is not the case for your application, you should be fine afaik.

C# without .NET Framework

Writing fast native applications, with API calls and etc, in a modern cross platform programming language like C# would be awesome, wouldn't it? For example if you want to write a simple utility for helping IT people with installing things, which wouldn't need another components, in an easy and modern programming language? or if you want to write a 3D game, it should be fast, and JIT would just make it slower...
Why, why isn't it possible? Why there are no native modern programming languages for these things?
C# and .Net are native code. I think you misunderstand the JITter. It's not a VM. A C# program is compiled to fully native code before any of it is executed.
Now, the "needing other components" part is a concern. Give it time, though. You'll be hard pressed to find a windows installation these days without at least .Net 2.0, and even a couple mainstream linux distros include mono out of the box.
Don't assume the JIT makes things slower. The JIT can optimize for the exact computer running the application rather than a generic computer like a 386 or Pentium. It can even make better speed/memory trade-off decisions when generating code because it knows exactly what's available. And if JIT still makes things slower, you can NGEN them so that JITting is all done beforehand.
As proof of this, consider that Quake has been ported to the CLR a couple of times, and in my personal tests, the frames per second have been faster when Quake runs on the CLR about half the times I demo it.
Compiled .NET programs have been shown to run just as quickly as C. If you want it ultra-lean write it in assembly for your native processor.
You can use the Microsoft NGEN.EXE tool to create a native image of a .NET assembly.
See MSDN NGEN documentation. Microsoft already though about what you're getting at here.
Microsoft also makes ILMERGE.EXE tool to merge multiple assembly files into one. This might border on optimization and speed too.
As a side note, Mono has full ahead of time compiling, eliminating the runtime. (I think that's how they get away running on iPhone, which prohibits any JIT.)
So, does this mean that we could fully compile and link a C# program using (limited) .NET calls into a standalone EXE that would run without .NET being installed at all?
FYI: Checking a server estate of some 5000 servers revealed about 200 without even .NET 2.0.
This causes problems for code that must run on "all Windows instances". With .NET 4.0+ not including 2.0 this gets worse as both new AND old Windows machines might not have the 'right' .NET
there is, C. C can be used to write any application , ever !!!

Categories