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.
Related
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.
Why do Actionscript, Java, C#, etc. compile into intermediate code?
I'm aware of cross-platform benefits of using intermediate code.
The question is: What is the benefit of compiling to intermediate code, compared to scripts (JS, Python, PHP, Perl, etc.) that are interpreted?
Is it just for code obfuscation? Or what?
In addition what is the benefit compared to compiling to native code?
It is much faster to parse and JIT-compile IL code than to parse a high-level language like Java or especially C# (which has more features).
It also allows developers to use new language features without updating anything on the end-users' machines. (eg, LINQBridge)
First of all historically java was targeted to mobiles and embedded devices with very limited CPU/memory, and JVM on such devices can't do any intensive optimization, like modern JITs do for now. So java engeneers decided to move optimization to compile phase.
Next, having "byte code"/IL allows you to have many compilers from different languages into such byte code - and only one JVM/JIT. It is much more efficient then to create separate VM+JIT for each language. Remember, you have Java, JRuby, JPython, Groovy, etc... in JVM world, and C#, VB#, ASP.NET, F#, etc -- in .NET world, and only one runtime/VM for each.
Intermediate code is very similar to assembly in that it contains a limited set of instructions. The runtime is then able to reliably and consistently operate on this (somewhat) small set of instructions without having to worry about parsing the language, etc. It can therefore gain performance improvements and make optimizations.
In .NET compilation to MSIL solves interoperability between different languages like C#, VB.NET etc.
Binary code instructions are very simple and atomic, much more so than programming statements can be.
For example, z = a + b - (c * d) would need to be translated into loading four values into registers, then an add, multiply, and subtract, then write into another memory location. So we have at least 8 instructions or so just for that line!
Intermediate code is the best of both worlds-- cross-platform, but also closer to the way machine code is normally written.
In addition to SLaks's answer, compiling to IL enables a degree of cross-language interoperability that generally doesn't exist in interpreted languages.
This advantage can be huge for new languages. Scala's only been around since 2003, and it's already gained an immense amount of traction. Ruby, on the other hand, hasn't spread very far beyond being used for Rails apps in its 1.5 decades of existence. This is at least in part because Scala is bytecode-compatible with all pre-existing Java code and libraries, which gives it a huge leg up: Its community can focus most of its effort on the language itself, and potential adopters don't have to worry about going through any special contortions (or, worse yet, replacing their entire codebase) in order to start using Scala. F#'s story is almost identical, but for the other major managed environment.
Meanwhile Ruby doesn't speak with code from other languages quite so easily, so its community has to sink a lot more effort into developing Ruby-specific libraries and frameworks, and its potential users have to be a lot more willing to commit to a large-scale platform shift in order to use it.
So we all know that C# doesn't have a C-like macro pre-processor (and there's a good thread on why here). But now that AOP is gaining traction, it seems like we're starting to do stuff with post-processors that we used to do with pre-processors (bear in mind that I am only getting my feet wet with PostSharp so am perhaps off base).
I am a huge fan of attributes in C#, but if a pre-processor was left out for good reasons (which, as a former MFC user I still question but nevertheless accept) why is post-compilation code injection a better idea than pre-compilation code injection?
The reasons why I chose post-compilation when designing PostSharp 5 years ago are:
Language agnosticism.
MSIL has stabler specifications compared to high-level languages (which have non-trivial updates every second year).
Most of the time, MSIL is the level of abstraction you need when dealing with aspects. You don't need to know all the equivalent constructs (think f 'using' and 'try-finally').
Before 2008, nobody has succeeded in producing a decent C# compiler. The difficulties met by Mono were impressive enough, even if they have caught up now.
Dealing with binary seemed much faster than dealing with source code.
Dealing with a binary assembly makes it possible to execute it -- the assembly being processed can transforme itself. It was unheard before PostSharp Laos was first released.
That said, implementations of AOP for C/C++ are indeed a pre-compiler (WeaveC) and implementations in Java are a compiler extension (for the good reason that there are many OSS implementations of the Java compiler).
-gael
Technically, there is a pre-compilation option for C# built into Visual Studio: The Text Template Transformation Toolkit (T4). This allows you to do pretty amazing things in a pre-compilation step, and is the basis of quite a few products, such as some ORMs, etc.
If you were to do pre-compilation you would have to interpret the source files from all the different languages you support then generate code in that language before it gets passed to the compiler. With post-processing you can simply use reflection to examine the assemblies whether the original language was C#, Visual Basic, or whatever.
It is just simpler. IL is a heckofalot easier to parse than C# source code. And it is language agnostic.
Recently I was talking with a friend of mine who had started a C++ class a couple months ago (his first exposure to programming). We got onto the topic of C# and .NET generally, and he made the point to me that he felt it was 'doomed' for all of the commonly-cited issues (low speed, breakable bytecode, etc). I agreed with him on all those issues, but I held back in saying it was doomed, only because I felt that, in time, languages like C# could instead become native code (if Microsoft so chose to change the implementation of .NET from a bytecode, JIT runtime environemnent to one which compiles directly to native code like your C++ program does).
My question is, am I out to lunch here? I mean, it may take a lot of work (and may break too many things), but there isn't some type of magical barrier which prevents C# code from being compiled natively (if one wanted to do it), right? There was a time where C++ was considered a very high-level language (which it still is, but not as much as in the past) yet now it's the bedrock (along with C) for Microsoft's native APIs. The idea that .NET could one day be on the same level as C++ in that respect seems only to be a matter of time and effort to me, not some fundamental flaw in the design of the language.
EDIT: I should add that if native compilation of .NET is possible, why does Microsoft choose not to go that route? Why have they chosen the JIT bytecode path?
Java uses bytecode. C#, while it uses IL as an intermediate step, has always compiled to native code. IL is never directly interpreted for execution as Java bytecode is. You can even pre-compile the IL before distribution, if you really want to (hint: performance is normally better in the long run if you don't).
The idea that C# is slow is laughable. Some of the winforms components are slow, but if you know what you're doing C# itself is a very speedy language. In this day and age it generally comes down to the algorithm anyway; language choice won't help you if you implement a bad bubble sort. If C# helps you use more efficient algorithms from a higher level (and in my experience it generally does) that will trump any of the other speed concerns.
Based on your edit, I also want to explain the (typical) compilation path again.
C# is compiled to IL. This IL is distributed to local machines. A user runs the program, and that program is then JIT-compiled to native code for that machine once. The next time the user runs the program on that machine they're running a fully-native app. There is also a JIT optimizer that can muddy things a bit, but that's the general picture.
The reason you do it this way is to allow individual machines to make compile-time optimizations appropriate to that machine. You end up with faster code on average than if you distributed the same fully-compiled app to everyone.
Regarding decompilation:
The first thing to note is that you can pre-compile to native code before distribution if you really want to. At this point you're close to the same level as if you had distributed a native app. However, that won't stop a determined individual.
It also largely misunderstands the economics at play. Yes, someone might perhaps reverse-engineer your work. But this assumes that all the value of the app is in the technology. It's very common for a programmer to over-value the code, and undervalue the execution of the product: interface design, marketing, connecting with users, and on-going innovation. If you do all of that right, a little extra competition will help you as much as it hurts by building up demand in your market. If you do it wrong, hiding your algorithm won't save you.
If you're more worried about your app showing up on warez sites, you're even more misguided. It'll show up there anyway. A much better strategy is to engage those users.
At the moment, the biggest impediment to adoption (imo) is that the framework redistributable has become mammoth in size. Hopefully they'll address that in a relatively near release.
Are you suggesting that the fact that C# is managed code is a design flaw??
C# can be natively compiled using tool such as NGEN, and the MONO (open source .net framework) team has developed full AOT (ahead of time) compilation which allows c# to run on the IPhone. However, full compilation is culbersome because it destroys cross-platform compatibility, and some machine-specific optimizations cannot be done. However, it is also important to note that .net is not an interpreted language, but a JIT (just in time) compiled language, which means it runs natively on the machine.
dude, fyi, you can always compile your c# assemblies into native image using ngen.exe
and are you suggesting .net is flawed design? it was .net which brought back ms back into the game from their crappy vb 5, vb 6, com days. it was one of their biggest bets
java does the same stuff - so are you suggesting java too is a mistake?
reg. big vendors - please note .net has been hugely hugely successful across companies of all sizes (except for those open source guys - nothing wrong with that). all these companies have made significant amount of investments into the .net framework.
and to compare c# speed with c++ is a crazy idea according to me. does c++ give u managed environment along with a world class powerful framework?
and you can always obfuscate your assemblies if you are so paranoid about decompilation
its not about c++ v/s c#, managed v/s unmanaged. both are equally good and equally powerful in their own domains
C# could be natively compiled but it is unlikely the base class library will ever go there. On the flip side, I really don't see much advantage to moving beyond JIT.
It certainly could, but the real question is why? I mean, sure, it can be slow(er), but most of the time any major differences in performance come down to design problems (wrong algorithms, thread contention, hogging resources, etc.) rather than issues with the language. As for the "breakable" bytecode, it doesn't really seem to be a huge concern of most companies, considering adoption rates.
What it really comes down to is, what's the best tool for the job? For some, it's C++; for others, Java; for others, C#, or Python, or Erlang.
Doomed? Because of supposed performance issues?
How about comparing the price of:
programmer's hour
hardware components
If you have performance issues with applications, it's much cheaper to just buy yourself better hardware, compared to the benefits you loose in switching from a higher-abstraction language to a lower one (and I don't have anything against C++, I've been a C++ developer for a long time).
How about comparing maintenance problems when trying to find memory leaks in C++ code compared to garbage-collected C# code?
"Hardware is Cheap, Programmers are Expensive": http://www.codinghorror.com/blog/archives/001198.html
What's the difference between the inner workings of Java's JVM and .NET's CLR?
Perhaps a starting point would be, are they basically the same thing in their respective environments (Java > JVM > Machine code) (C# > CLR > IL).
Update: Several people have alluded to the points I was trying to cover:
Garbage Collection
Boxing/Unboxing
JIT debugging
Generics/Templates
Please feel free to suggest other good topics that differentiate the two.
#George Mauer - this sounds very interesting:
Already posted this once but here is a series of interviews with c# chief language designer Anders Hejlsberg.
This should be a great thread.
One of the biggest differences is between the CLR and JVM is the CLR"s native integration of generics.
Java instead removes the generic types and the JVM can only work with objects by autoboxing the objects it appears to be pseudo generics.
From here. I couldn't have said it better (Well, with the exception of a flame war, this is a flameless place :-) ).
Hello,
Responding to your question seems
fraught with peril by starting a flame
war, so I'll proceed cautiously.
There are a number of fundamental
technical similarities between the
Java Runtime and the Common Language
Runtime, including garbage collected
memory, an intermediate language
(Microsoft IL versus Java ByteCode),
core system libraries, and support for
fairly high level languages, code
security, and deployment.
However, each of these 'similar' areas
also have a number of sizable and
small differences, and it's beyond the
scope of a simple Forum post to
describe most of them.
I would suggest asking a more
targetted question about any of the
various runtime features and component
areas (e.g. memory management,
compilation, system libraries,
security, etc.) and then we can
provide a more targetted response
(e.g. a blog, a technical article, or
some books).
One essential difference is that the JVM is portable across platforms and runs on Linux, Macintosh, and many cell phones and embedded devices.
CLR runs on Microsoft supported platforms with the Mono project providing partial support of older versions of CLR on a few more.
Internally this means the JVM's performance will vary on those different platforms based on capabilities provided by the platforms themselves.
The CLR and JVM have goals and philosophies that differ more than you might think. In general, the JVM aims to optimize more dynamic, higher-level code while the CLR gives you more low-level tools to do these kinds of optimizations yourself.
A good example is stack allocation. On the CLR you have explicit stack allocation of custom value types. On the JVM the only custom types are reference types but the JVM can convert heap allocations to stack allocations in certain circumstances through Escape Analysis.
Another example. In Java, methods are virtual by default. On C# at least, they are not. It is much more difficult to optimize virtual method calls because the code that gets executed at a given call site cannot be determined statically.
Under the hood, their execution systems are quite different. Most JVMs (in particular, Hotspot) start out with a bytecode interpreter and only JIT-compile parts of the code that are executed heavily e.g. tight loops. They can also re-compile these over and over each time using execution statistics collected from previous runs to drive optimizations. This allows more optimization effort to be applied to the parts of the program that need it most. This is called adaptive optimization.
The CLR compiles everything up-front only once. It does fewer optimization both because it has more code to compile and so has to be fast and because it doesn't have any statistics of the actual execution paths taken to feed into its optimizations. This approach does have the very significant advantage of allowing you to cache compilation results across processes, which CLR does but JVM does not.
A large percentage of the Hotspot JVM code is dedicated to these adaptive optimizations and they are what put Java in the same performance ballpark as native code for most general purpose computation in the early 2000s. They are also what makes the JVM a decent target for dynamic languages. I'm excluding here the more recent developments of the Dynamic Languages Runtime and invokedynamic as I don't know enough about the DLR.
Miguel de Icaza mentions here:
Seasoned industry programmers will notice that the above is
very much like Java and the Java VM. They are right, the above
is just like Java.
The CIL has one feature not found in Java though: it is
byte code representation that is powerful enough to be used as a
target for many languages: from C++, C, Fortran and Eiffel to Lisp
and Haskell including things like Java, C#, JavaScript and Visual
Basic in the mix.
I wish I had the time to go in more detail, but for the sake
of this argument, the above will suffice.
The comments go into some details, though, like tail call optimizations. Lot have changed since 2002 though - both CLR and JVM now have multiple languages targeting it. But nonetheless worth a read.
As Vinko said, the full details are way beyond the scope of a forum post. The differences/similarities boil down to this:
They are both a runtime environment "sandbox" that include a "just-in-time" compiler to translate program instructions in an intermediate language (MSIL or ByteCode) to native machine code and provide automatic memory management (garbage collection). Sitting on top of the respective runtime environments are a set of class libraries that provide higher level abstractions to developers to simplify development tasks.
The internals of how those runtime environments are actually implemented are, for the most part, proprietary to Microsoft and Sun. The algorithms used by the garbage collection systems, for example, while probably similar in technical functionality are different in implementation.
As far as I know, .Net CLR still has much more flexible and powerful Code Access Security built into the runtime, allowing much finer grained permissions and execution policy.
There differences in garbage collection as well.
JVM uses Copying collector and Mark and sweep. .NET user Copying collector and Mark and compact (Much harder to implement).
Also type erasure mentioned by Flyswat is important. JVM doesn't have a clue about generics and everything is object and associated perf. penalty of boxing and unboxing. Also reflection won't give you generic information. CLR supports generics natively.