How to become an MSIL pro? - c#

I have spent hours on a debugging problem only to have a more experienced guy look at the IL (something like 00400089 mov dword ptr [ebp-8],edx ) and point out the problem. Honestly, this looks like Hebrew to me - I have no idea what the heck it's saying.
Where can I learn more about this stuff and impress everyone around me? My goal is to read stuff like the following and make a comment like: Yeh, you are having a race condition.
.maxstack 2
.entrypoint
.locals init (valuetype [MathLib]HangamaHouse.MathClass mclass)
ldloca mclass
ldc.i4 5

That is not MSIL, it is assembly langauge 80x86.

To get great at IL, start with this fantastic article: Introduction to IL Assembly Language. Although it says "introduction", it's everything you need to start getting comfortable.
The other part of what you need is practice and lots of it. Use .NET Reflector and start looking at code disassembled into IL. (Tip: when you go to download it, you don't have to provide a real email.) Also, play with the Reflexil plugin in Reflector. Here's a good starting point for that: Assembly Manipulation and C# / VB.NET Code Injection.
Not necessary but a bonus: Reflexil is open source. You can get the source here.

I can give you an answer that runs both ways.
On the one hand, there's nothing like good assembly language skills to teach you how a computer really operates. MSIL is, to some extent, an assembly-like language. On the down side, there are very few opportunities to do this kind of development any more.
On the other hand, resorting to looking at the MSIL to fix a problem is not necessarily the most direct or educational way to understand a problem. In five years of .NET programming, I've never felt the need to go there. Only once has a co-worker (who had worked at Microsoft on compiler testing) gone there with a problem that I was trying to solve, and in the end, his answer was misleading, because the real issue was based in CLR design and constraints. Better knowledge of the CLR and C# would have led to a better understanding and a real solution.
(In case you're wondering, the problem was that I wanted to use "as" for safe casting with a generic. "as" didn't work, but "is" did. My co-worker noted that "is" and "as" use the same MSIL. The real problem is that "as" only works for casting classes, and without the proper constraint on the generic declaration, C# doesn't know whether your generic type will be a class. In fact, the types I was using with generics were value types; "as" couldn't work for those at all.)
Rather than going for MSIL skills, I highly recommend Jeffrey Richter's book CLR via C#. Even after years of digging hard at into C#, this book is still full of revelations - I learn something from every page.

Can’t say I’m an IL “pro”, but I managed to teach myself pretty much all of IL by doing the following:
Write a very short (two or three line) C# program that you are curious about how to write in IL.
Compile the program.
Open the compiled EXE in .NET Reflector.
Look at the IL code for the method in Reflector.
Hover your mouse over an IL opcode (e.g. “ldloc”). There is a tooltip describing each IL instruction.

Related

VB.NET for a C# Developer

I may be starting a new job which requires VB.NET but I am a C# developer and even though I may be able to understand the code, writing it from scratch seems to be a hassle for me for a while.
There are C#>VB.NET converter out there (online) and where you paste your C# code and it converts it into VB.NET code. My question is whether there is any person who experienced this and whether it is a good temp solution or I am gonna experience so much difficulties with that? Do they convert good?
And probably I am gonna run the codes on Asp.net.
An example converter: http://www.developerfusion.com/tools/convert/csharp-to-vb/
Thanks in advance.
Don't use converters - learn VB.NET and the differences between its syntax and C#.
There is a very good comparison cheat sheet here to get you started.
In practice, you will find that most of the time you are interacting with familiar .NET objects in the same way and you only have some syntax differences (though generics and delegate syntax are such a pain that one tends to shy away from them).
Microsoft has stated that they are trying to bring both language to feature parity, so anything you can do in C#, you should be able to do with VB.NET (with minor differences normally).
Update - don't forget that compiled code (in assemblies) should work identically in both languages (assuming CLS compliance), so you could write a library in C# for use with VB.NET and vice versa.
You can try the Telerik Code Converter
That being said, it would be a valuable exercise to convert the code manually. You'll gain a good amount of experience by doing a manual conversion and you'll learn some of the key differences between the 2 languages that may help you going forward.
I'd say your code will work, but you'll miss some special features for which there is no C# equivalent and which would make your code fit better with the language. Some examples:
In C#, you assign event handlers with +=, which will be translated to AddHandler. In VB, however, it's much more common to use WithEvents instance variables. This is especially relevant for ASP.NET, where C# often uses the AutoEventWireup feature, which done in VB through WithEvents instead.
In C#, you access XML through LINQ to XML method calls, which will be translated to the matching method calls in VB. However, in VB, it's more natural to use the integrated language support for XML.
This is good for converting the bulk of your code, but it's not a total solution. One thing you will have issues with is the converter knowing what to do with C#'s indexer brackets ([]) vs. method parentheses (()). VB uses parenthesis for indexers and methods and there's no way for it to know which to use.
I've gone through conversion hell with these things and finally decided that they were just too much trouble and that it was much easier to just convert it by hand. I come from a VB background, so this wasn't a huge deal for me.
For what you want to do, though, you need to learn VB.NET syntax. Writing everything in C# and converting it to VB.NET is not a good, long-term solution. You will eventually have to learn VB.NET. Your manager(s) will not be keen to the fact that you're not learning the core fundamentals of the language you were hire to program in.
Don't do it... There are converters, but you will find that once you learn the key differences that you will be fine. You will interact with the .NET libraries in the same way so much of the programming will be the same.
I just changed jobs recently and went the opposite direction. I'm glad I took the time to learn C#. Major dividends in the end and you'll be more versatile.

How is it possible to see C# code after compilation/optimization?

I was reading about the yield keyword when I came across a sample chapter from C# in Depth: http://csharpindepth.com/Articles/Chapter6/IteratorBlockImplementation.aspx.
The first block of code utilizes the yield keyword to make a simple iterator. But, the second block of code shows this code after the compiler has had its way with it. Among other things, it has exploded the yield statement into a state machine.
Several other examples of code being modified by the compiler is evident on the page.
My question is: Was the author actually able to access the code after compilation, or did he infer what it was going to look like?
You can have a look using Reflector, that's probably your best bet:
http://reflector.red-gate.com
The author himself mentioned:
Obviously the compiler doesn't actually produce C#, but I've used Reflector to decompile the code as C#.
in the same paragraph, titled High level overview: what's the pattern?
Probably both. It's quite easy to reverse-engineer compiled assemblies using Reflector. And the C# language spec, which defines how various syntactic-sugary things are compiled, is a public document. The author could have used either approach, or a mixture of the two.
Check out ildasm to take a look at the compiled IL.
(Really, it's good fun once you get your eye in)
.NET CLR actually has a form of assembly called MSIL, along with an assembler and dissembler. So yes, you can actually compile the code, then see the exact compiled CLR instructions.
https://web.archive.org/web/20211020103545/https://www.4guysfromrolla.com/articles/080404-1.aspx
dotPeek by JetBrains
https://www.jetbrains.com/decompiler/
It's free and easy to use :)

translate C++/CLI into C#

How I can translate small C++/CLI project to c#
One roundabout, manual way would be to compile your C++/CLI project and open the output assembly in Reflector. Disassemble each class, have it convert the disassembled IL to C#, and save that code off.
As for an automatic way to do it, I can't think of any off the top of my head.
Those things being said, are you sure you really want to convert your project to C#? If your C++/CLI project uses any unmanaged code, you'll have a difficult time coming up with a purely managed equivalent. If the project is more or less composed of pure CLR code, and it was written in C++/CLI for the sake of being written in C++/CLI, I can understand wanting to convert it to C#. But if there was a reason for writing it in C++/CLI, you may want to keep it that way.
IMHO, line by line is the best way. I've ported several C++ style projects to a managed language and I've tried various approaches; translators, line by line, scripting, etc ... Over time I've found the most effective way is to do it line by line even though it seems like the slowest way at first.
Too much is lost in a translator. No translator is perfect and you end up spending a lot of time fixing up the translated code. Also, translated code as a rule is ugly and tends to be less readable than hand crafted code. So the result is a fixed up, not very pretty code base.
A couple of tips I have on line by line
Start by defining all of the leaf types
For every type that has a non-trivial (freeing memory) destructor, implement IDisposable
Turn on the FxCop rule that checks for lack of Dispose calls to catch all of the places use used stack based RAII and missed it
Pay very close attention to the uses of byref in C++.
I haven't tried it, but I just googled it and found this: http://code2code.net/
According t it, you shouldn't fully rely on the code it produces:
You accept that this page does only half the work.
Futher work on your part is required. In most cases, the translated code will not even compile.
Also, read this: Translate C++/CLI to C#

Is C# code faster than Visual Basic.NET code? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
Is C# code faster than Visual Basic.NET code, or that is a myth?
That is a myth. They compile down to the same CLR. However the compiler for the same routine may come out slightly differently in the CLR. So for certain routines some may be slightly better like (0.0000001%) faster in C# and vice versa for VB.NET, but they are both running off the same common runtime so they both are the same in performance where it counts.
The only reason that the same code in vb.Net might be slower than c# is that VB defaults to have checked arithmetic on and c# doesn't.
By default, arithmetic operations and overflows in Visual Basic are checked; in c#, they are not.
If you disable that then the resulting IL is likely to be identical. To test this take your code and run it through Reflector and you will see that it looks very similar if you switch from c# to vb.Net views.
It is possible that an optimization (or just difference in behaviour) in the c# compiler verses the vb.net compiler might lead to one slightly favouring the other. This is:
Unlikely to be significant
if it was it would be low hanging fruit to fix
Unlikely to happen.
c# and vb.net's abstract syntax trees are very close in structure. You could automatically transliterate a great deal of vb.Net into c# and vice versa. What is more the result would stand a good chance of looking idiomatic.
There are a few constructs in c# not in vb.net such as unsafe pointers. Where used they might provide some benefits but only if they were actually used, and used properly. If you are down to that sort of optimization you should be benchmarking appropriately.
Frankly if it makes a really big difference then the question should not be "Which of c#/vb.net should I use" you should instead be asking yourself why you don't move some code over to C++/CLI.
The only way I could think of that the different compilers could introduce serious, pervasive differences is if one chose to:
Implement tail calls in different places
These can make things faster or slower and certainly would affect things on deeply recursive functions. The 4.0 JIT compiler on all platforms will now respect all tail call instructions even if it has to do a lot of work to achieve it.
Implemented iterator blocks or anonymous lambdas significantly more efficiently.
I believe both compilers are about as efficient at a high level as they are going to get though in this regard. Both languages would require explicit support for the 'yield foreach' style available to f#'s sequence generators.
Boxed when it was not necessary, perhaps by not using the constrained opcode
I have never seen this happen but would love an example where it does.
Both the c# and vb.net compilers currently leave such optimization complexities as en-registering of variables, calling conventions, inlining and unrolling entirely up to the common JIT compiler in the CLR. This is likely to have far more of an impact on anything else (especially when the 32 bit and 64bit JIT's can now behave quite differently).
The framework is written in C# but that still does not tell about performance differences between C# or VB as everything is compiled to IL language which then actually executed (including JITted and so on).
The responsibility is on each specific language compiler that what kind of IL they produce based on source code. If other compiler produces better suited IL than other, then it could have performance difference. I don't know exactly that is there this kind of areas where they would cause drastically different IL, but I doubt the differences would still be huge.
Other aspect is completely then the C#'s ability to run unsafe code like using raw pointers etc that can give performance on special scenarios.
There might be a slight difference in the compiler optimization, but I'd say there is no noticeable difference. Both C# and VB.NET compile to Common Intermediate Language. In some cases, you may be able to get a significant performance gain in C# by using unsafe code, but under most circumstances I wouldn't recommend doing so. If you need something that performance critical, you shouldn't use C# either.
The myth probably started because of the huge difference in Visual Basic 6 performance compared to the average C++ application.
I was at a Microsoft conference and the MS employees stated that C# is up to 8% faster than VB.NET. So if this is a myth, it was started by the people that work at MS. If I can find the slides that state this I would post them, but this was when C# just came out. I think that even if it was true at one point in time, that the only reason for one to be faster than the other is how things are configured by default like ShuggyCoUk said.
It depends on what you're doing. I think there's no real difference between VB and C#. The both of them are .Net languages and they're compiled in IL.
More info? Read this:
http://devlicio.us/blogs/robert_dunaway/archive/2006/10/19/To-use-or-not-use-Microsoft.VisualBasic.dll-_2800_all-.NET-Languages-could-benefit_3F002900_.aspx
As usual the answer is that it depends... By itself, no, VB.Net is not slower than C#, at least nothing that you will notice. Yes, there will be slight differences in compiler optimization, but IL generated will be essentially the same.
However, VB.Net comes with a compatibility library for programmers used to VB6. I am remembering about those string methods like left, right, mid, old VB programmers would expect. Those string manipulation functions are slower. I'm not sure you would notice an impact, but depending on the intensity of their use, I'd bet the answer would be yes. Why are those methods slower than "native" .net string methods? Because they are less type-safe. Basically, you can throw almost anything at them and they will try to do what you want them to, just like in old VB6.
I am thinking about string manipulation, but if I think harder, I'm sure I'll remember about more methods thrown into that compatibility layer (I don't remember the assembly's name, but remember it is referenced by default in VB.Net) that would have a performance impact if used instead of their .net "native" equivalent.
So, if you keep on programming like you were in VB6, then you might notice an impact. If not, it's ok.
It is not really a myth. While C# and VB.Net both compile to IL, the actual instructions produced are likely to be different because 1. the compilers may have different optimisations and 2. the extra checks that VB.Net does by default e.g. arithmetic overflow. So in many cases the performance will be the same but in some cases C# will be faster. It's also possible VB.Net might be quicker in rare circumstances.
There are some small differences in the generated code that may make C# slightly faster in some situations. For example VB.NET has some extra code to clear the local variables in a method while C# doesn't.
However, those differences are barely measurable, and most code is so far from optimal that you are just starting in the wrong end by switching language to make the code run faster. You can take just about any CPU intensive code and rather easily make it twice as fast. Some code can be made 10 times faster, other code perhaps 10000 times faster. In that context the few percent that you may gain by using C# instead of VB.NET is not worth the effort.
On the other hand, learning C# may very well be an effective way of speeding up your code. Not because C# can produce faster code, but because you will get a better understanding of both C# and VB.NET, enabling you to write code that performs better in either language.
Edit:
The C# and VB.NET compilers are obviously developed more or less in sync. The speed difference between C# 1 and C# 2 is something like 30%, the difference between the parallel versions of C# and VB.NET is a lot less.
C# and VB.Net are both compiled by IL. Also C++ and F# are compiled by it. In fact, the four languages I mentioned are executed at the same speed. There isn't in these "a faster language": the unique difference is between auto garbage-collected languages (C#, VB.Net, F# etc.) and those aren't auto-collected (such as C++). This second group generally is slower, because rarely the developer know how and when collect the garbage in the heap memory, however, if you are informed about the heap memory, the program could result faster if in C++. Hard graphics programs are usually made in C++ (such as the most of Adobe programs). You can also manually collect the garbage in C# (System.GC.Collect();) and in VB.Net (System.GC.Collect).
I know this answer is not fully inherent to the question, but I want to offer you many ways and choices. You choose the right way for your programs.

Is there any reason C# does not support manual inline methods? And what about optional parameters?

Is there any design reason for that (like the reason they gave up multi inheritance)?
or it just wasn't important enough?
And same question applies for optional parameters in methods... this was already in the first version of vb.net... so it surely no laziness that cause MS not to allow optional parameters, probably architecture decision.. and it seems they had change of heart about that, because C# 4 is going to include that..
What was the decision and why did they give it up?
Edit:
Maybe readers didn't fully understand me. I'm working lately on a calculation program (support numbers of any size, to the last digit), in which some methods are used millions of times per second.
Say I have a method called Add(int num), and this method is used quiet a lot with 1 as parameter (Add(1);), I've found out it is faster to implement a special method especially for one. And I don't mean overloading - Writing a new method called AddOne, and literally copy the Add method into it, except that instead of using num I'm writing 1. This might seems horribly weird to you, but it's actually faster.
(as much as ugly it is)
That made me wonder why C# doesn't support manual inline which can be amazingly helpful here.
Edit 2:
I asked myself whether or not to add this. I'm very well familiar with the weirdness (and disadvantages) of choosing a platform such as dot net for such project, but I think dot net optimizations are more important than you think... especially features such as Any CPU etc.
To answer part of your question, see Eric Gunnerson's blog post: Why doesn't C# have an 'inline' keyword?
A quote from his post:
For C#, inlining happens at the JIT
level, and the JIT generally makes a
decent decision.
EDIT: I'm not sure of the reason for delayed optional parameters support, however saying they "gave up" on it sounds as though they were expected to implement it based on our expectations of what other languages offered. I imagine it wasn't high on their priority list and they had deadlines to get certain features out the door for each version. It probably didn't rise in importance till now, especially since method overloading was an available alternative. Meanwhile we got generics (2.0), and the features that make LINQ possible etc. (3.0). I'm happy with the progression of the language; the aforementioned features are more important to me than getting support for optional parameters early on.
Manual inlining would be almost useless. The JIT compiler inlines methods during native code compilation where appropriate, and I think in almost all cases the JIT compiler is better at guessing when it is appropriate than the programmer.
As for optional parameters, I don't know why they weren't there in previous versions. That said, I don't like them to be there in C# 4, because I consider them somewhat harmful because the parameter get baked into the consuming assembly and you have to recompile it if you change the standard values in a DLL and want the consuming assembly to use the new ones.
EDIT:
Some additional information about inlining. Although you cannot force the JIT compiler to inline a method call, you can force it to NOT inline a method call. For this, you use the System.Runtime.CompilerServices.MethodImplAttribute, like so:
internal static class MyClass
{
[System.Runtime.CompilerServices.MethodImplAttribute(MethodImplOptions.NoInlining)]
private static void MyMethod()
{
//Powerful, magical code
}
//Other code
}
My educated guess: the reason earlier versions of C# didn't have optional parameters is because of bad experiences with them in C++. On the surface, they look straight-forward enough, but there are a few bothersome corner cases. I think one of Herb Sutter's books describes this in more detail; in general, it has to do with overriding virtual methods. Maximilian has mentioned one of the .NET corner cases in his answer.
You can also pretty much get by with out them by manually writing multiple overloads; that may not be very nice for the author of the class, but clients will hardly notice the difference between overloads and optional parameters.
So after all these years w/o them, why did C# 4.0 add them? 1) improved parity with VB.NET, and 2) easier interop with COM.
I'm working lately on a calculation program (support numbers of any size, to the last digit), in which some methods are used literally millions of times per second.
Then you chose a wrong language. I assume you actually profiled your code (right?) and know that there is nothing apart from micro-optimisations that can help you. Also, you're using a high-performance native bigint library and not writing your own, right?
If that's true, don't use .NET. If you think you can gain speed on partial specialisation, go to Haskell, C, Fortran or any other language that either does it automatically, or can expose inlining to you to do it by hand.
If Add(1) really matters to you, heap allocations will matter too.
However, you should really look at what the profiler can tell you...
C# has added them in 4.0: http://msdn.microsoft.com/en-us/library/dd264739(VS.100).aspx
As to why they weren't done from the beginning, its most likely because they felt method overloads gave more flexibility. With overloading you can specify multiple 'defaults' based on the other parameters that you're taking. Its also not that much more syntax.
Even in languages like C++, inlining something doesn't guarantee that it'll happen; it's a hint to the compiler. The compiler can either take the hint, or do its own thing.
C# is another step removed from the generated assembly code (via IL + the JIT), so it becomes even harder to guarantee that something will inline. Furthermore, you have issues like the x86 + x64 implementations of the JIT differing in behaviour.
Java doesn't include an inline keyword either. The better Java JITs can inline even virtual methods, nor does the use of keywords like private or final make any difference (it used to, but that is now ancient history).

Categories

Resources