C# - Default library has better performance? - c#

Earlier today i made myself a lightweight memory stream, which basically writes to a byte array. I thought i'd benchmark the two of them to see if there's any difference - And there was:
(writing 1 byte to the array)
MemoryStream: 1.0001ms
mine: 3.0004ms
Everyone tells me that MemoryStream basically provides a byte array and a bunch of methods to work with it.
My question: Does the default C# library have a slightly better performance than the code we write? (maybe it runs in release rather than debug?)

The .NET implementation was probably a bit better than your own, but also, how did you benchmark? A couple of million iterations, or just a few? Remember that you need to use a large test base so that you can eliminate some data (CPU being called away for a moment, etc) that will give false results.

The folks at Microsoft are much smarter than you and I and most likely have written a better optimized wrapper over Byte[], much better than something that you or I would implement.
If you are curious, I would suggest that you disassemble the types that you have recreated to see how exactly Microsoft has implemented them. In some of the more important areas of the framework (such as this I would imagine) you will find that the BCL calls out to unmanaged code to accomplish its goals.
Unmanaged code has a much better chance of outperforming managed code in cases like this since you can freely work with arrays without the overhead of a managed runtime (for things like bounds checking and such).

Many of the framework assemblies are NGENed, which may give them a small boost by bypassing the initial JIT time. This is unlikely to be the cause of a 2ms difference, especially if you'd already warmed up your methods before starting the stopwatch, but I mention it for completeness.
Also, yes, the framework assemblies are built in "release" mode (optimisations on and checks off), not "debug."

You probably used Array.Copy() instead of the faster Buffer.BlockCopy(). The fastest way is to use unsafe code with pointers. Check out how they do this in the Mono project (search for memcpy).

Id wager that Microsoft's implementation is a wee bit better than yours. ;)
Did you check the source?

Related

Is there any C# decompiler that can show the coding almost identically to how it was written?

I've been using reflector to decompile a couple simple c# apps but I notice that though code is being decompiled, I still can't see things as they were written on VS. I think this is the way it is as the compiler replaces human instructions by machine code. However I thought I would give it a try and ask it on here. Maybe there is a decompiler that can decompile and show the coding almost identically to the original code.
That is impossible, since there are lots of ways to get the same IL from different code. For example, there is no way to know if an extension method was called fluent-style vs explicit on the declaring type. There is no way to know if LINQ vs regular code was used. All manner of implicit operations may or may not be there. Removed code may or may not have been there. Many primitives (including enums) up-to-and-including 4 bytes are indistinguishable once they are IL.
If you want the actual code, legally obtain the original code.
Existing .Net decompilers generally decompile to the best of their ability.
You appear to be asking for variable names and line formatting, which for obvious reasons are not compiled to IL.
There are several. I currently use JustDecompile found here http://www.telerik.com/products/decompiler.aspx?utm_source=twitter&utm_medium=sm&utm_campaign=ad
[Edit]
An alternative is .NET Reflector found here: http://www.reflector.net/
I believe there is a free version of it, but didn't take time to look.
Basically, no. There are often many ways to arrive at the same IL code, and there's no way at all for a decompiler to know which was used.
No, nor should there ever be. Things like comments and unreachable code would just add bloat with absolutely zero benefit. The very best you can ever do is approximate the compiled code.

Get Calling Object's HashCode?

This might be a duplicate, but I haven't seen this exact question or a similar one asked/answered with a date newer than the release of .Net 4.
I'm looking for a temporary hack that allows me to look through the call stack and get all calling objects (not methods, but the instances that hold the methods) in the stack. Ultimately I need their hashcodes.
Is this possible?
EDIT:
Whether it came across in my question or not, was really asking if there was a simple/built-in way to do this. Really, just a stop-gap fix until I can make breaking changes to other parts of the system. Thanks for the great answers. After seeing them, I think I'll wait . . . :)
What are you trying to achieve here?
Have a look at a similar question I answered about a month ago: How to get current value of EIP in managed code?. You might get some inspiration from that. Or you might decide it is too ugly (+1 for the latter).
If all you want to do is assemble 'unique' call paths within a program session, go right ahead: I'd be very sure to use an AOP weaver and thread local storage. It wouldn't be too hard that way.
Caveat 1: Hashes are not very useful for generic .NET objects
A random object's hashcode may vary with it's location on the heap to begin with. For reference: on MONO, with the moving heap allocator disabled, Object::GetHash is this pretty blob of code (mono/metadata/monitor.c)
#else
/*
* Wang's address-based hash function:
* http://www.concentric.net/~Ttwang/tech/addrhash.htm
*/
return (GPOINTER_TO_UINT (obj) >> MONO_OBJECT_ALIGNMENT_SHIFT) * 2654435761u;
#endif
Of course, with the moving allocator things are slightly more complex to guarantee a constant hash over the lifetime of the object, but you get the point: each runtime will generate different hashes, and the amount of allocations done will alter the future default hash codes of the identical objects.
Caveat 2: Your stack will contain alien frames
Even if you got that part fixed by supplying proper deterministic hash functions, you will require each stackframe to be of 'recgonizable' type. This is probably not going to be the case. Certainly not if you use anything akin to LINQ, anonymous types, static constructors, delegates; all kinds of things could be interleaving stack frames with those of (anonymous) helper types, or even performance trampolines invented by the JIT compiler to optimize tail recursion, a large switch jump table or sharing code between multiple overloads.
Takeaway: stack analysis is hard: you should definitely use the proper API if you are going to undertake it.
Conclusion:
By all means have a ball. But heed the advice
your requirements are non-standard (underlined by the runtime library not supporting it); This is usually a sign that: you are solving a unique problem (but reconsider the tool chosen?) or you are solving it the wrong way
You could perhaps get a lot more info by generating a flow graph with some handwritten simulation code instead of trying to hook into the CLR VM
if you're gonna do it, use the proper API (probably the profiler API since a sampling profiler will save exactly this: stack 'fingerprints' every so-many instructions)
If you really must do it by instrumenting your code, consider using AOP
You can get the call stack by creating an instance of the StackTrace class and inspecting the StackFrame objects within it. Looking at the member list, this doesn't seem to reveal the instances, though, just the classes and methods.
This is possible only with unmanaged APIs, specifically with the CLR profiling API. I know nithing about it, other than it is used to implement profiling and debugging tools. You have to google it and be comfortable with burning 1 week bringing it to production. If at all possible, give up your plan and find an alternative. Tell us what you want to do and we can help!
Try Environment.StackTrace.

Safe vs Unsafe code

Read this question today about safe and unsafe code I then read about it in MSDN but I still don't understand it. Why would you want to use pointers in C#? Is this purely for speed?
There are three reasons to use unsafe code:
APIs (as noted by John)
Getting actual memory address of data (e.g. access memory-mapped hardware)
Most efficient way to access and modify data (time-critical performance requirements)
Sometimes you'll need pointers to interface your C# to the underlying operating system or other native code. You're strongly discouraged from doing so, as it is "unsafe" (natch).
There will be some very rare occasions where your performance is so CPU-bound that you need that minuscule extra bit of performance. My recommendation would be to write those CPU-intesive pieces in a separate module in assembler or C/C++, export an API, and have your .NET code call that API. An possible additional benefit is that you can put platform-specific code in the unmanaged module, and leave the .NET platform agnostic.
I tend to avoid it, but there are some times when it is very helpful:
for performance working with raw buffers (graphics, etc)
needed for some unmanaged APIs (also pretty rare for me)
for cheating with data
For example of the last, I maintain some serialization code. Writing a float to a stream without having to use BitConverter.GetBytes (which creates an array each time) is painful - but I can cheat:
float f = ...;
int i = *(int*)&f;
Now I can use shift (>>) etc to write i much more easily than writing f would be (the bytes will be identical to if I had called BitConverter.GetBytes, plus I now control the endianness by how I choose to use shift).
There is at least one managed .Net API that often makes using pointers unavoidable. See SecureString and Marshal.SecureStringToGlobalAllocUnicode.
The only way to get the plain text value of a SecureString is to use one of the Marshal methods to copy it to unmanaged memory.

C# running faster than C++?

A friend and I have written an encryption module and we want to port it to multiple languages so that it's not platform specific encryption. Originally written in C#, I've ported it into C++ and Java. C# and Java will both encrypt at about 40 MB/s, but C++ will only encrypt at about 20 MB/s. Why is C++ running this much slower? Is it because I'm using Visual C++?
What can I do to speed up my code? Is there a different compiler that will optimize C++ better?
I've already tried optimizing the code itself, such as using x >> 3 instead of x / 8 (integer division), or y & 63 instead of y % 64 and other techniques. How can I build the project differently so that it is more performant in C++ ?
EDIT:
I must admit that I have not looked into how the compiler optimizes code. I have classes that I will be taking here in College that are dedicated to learning about compilers and interpreters.
As for my code in C++, it's not very complicated. There are NO includes, there is "basic" math along with something we call "state jumping" to produce pseudo random results. The most complicated things we do are bitwise operations that actually do the encryption and unchecked multiplication during an initial hashing phase. There are dynamically allocated 2D arrays which stay alive through the lifetime of the Encryption object (and properly released in a destructor). There's only 180 lines in this. Ok, so my micro-optimizations aren't necessary, but I should believe that they aren't the problem, it's about time. To really drill the point in, here is the most complicated line of code in the program:
input[L + offset] ^= state[state[SIndex ^ 255] & 63];
I'm not moving arrays, or working with objects.
Syntactically the entire set of code runs perfect and it'll work seamlessly if I were to encrypt something with C# and decrypt it with C++, or Java, all 3 languages interact as you'd expect they would.
I don't necessarily expect C++ to run faster then C# or Java (which are within 1 MB/s of each other), but I'm sure there's a way to make C++ run just as fast, or at least faster then it is now. I admit I'm not a C++ expert, I'm certainly not as seasoned in it as many of you seem to be, but if I can cut and paste 99% of the code from C# to C++ and get it to work in 5 mins, then I'm a little put out that it takes twice as long to execute.
RE-EDIT:
I found an optimization in Visual Studio I forgot to set before. Now C++ is running 50% faster then C#. Thanks for all the tips, I've learned a lot about compilers in my research.
Without source code it's difficult to say anything about the performance of your encryption algorithm/program.
I reckon though that you made a "mistake" while porting it to C++, meaning that you used it in a inefficient way (e.g. lots of copying of objects happens). Maybe you also used VC 6, whereas VC 9 would/could produce much better code.
As for the "x >> 3" optimization... modern compilers do convert integer division to bitshifts by themselves. Needless to say that this optimization may not be the bottleneck of your program at all. You should profile it first to find out where you're spending most of your time :)
The question is extreamly broad. Something that's efficient in C# may not be efficient in C++ and vice-versa.
You're making micro-optimisations, but you need to examine the overall design of your solution to make sure that it makes sense in C++. It may be a good idea to re-design large parts of your solution so that it works better in C++.
As with all things performance related, profile the code first, then modify, then profile again. Repeat until you've got to an acceptable level of performance.
Things that are 'relatively' fast in C# may be extremely slow in C++.
You can write 'faster' code in C++, but you can also write much slower code. Especially debug builds may be extremely slow in C++. So look at the type of optimizations by your compiler.
Mostly when porting applications, C# programmers tend to use the 'create a million newed objects' approach, which really makes C++ programs slow. You would rewrite these algorithm to use pre-allocated arrays and run with tight loops over these.
With pre-allocated memory you leverage the strengths of C++ in using pointers to memory by casting these to the right pod structured data.
But it really depends on what you have written in your code.
So measure your code an see where the implementations burn the most cpu, and then structure your code to use the right algorithms.
Your timing results are definitely not what I'd expect with well-written C++ and well-written C#. You're almost certainly writing inefficient C++. (Either that, or you're not compiling with the same sort of options. Make sure you're testing the release build, and check the optimization options.
However, micro-optimizations, like you mention, are going to do effectively nothing to improve the performance. You're wasting your time doing things that the compiler will do for you.
Usually you start by looking at the algorithm, but in this case we know the algorithm isn't causing the performance issue. I'd advise using a profiler to see if you can find a big time sink, but it may not find anything different from in C# or Java.
I'd suggest looking at how C++ differs from Java and C#. One big thing is objects. In Java and C#, objects are represented in the same way as C++ pointers to objects, although it isn't obvious from the syntax.
If you're moving objects about in Java and C++, you're moving pointers in Java, which is quick, and objects in C++, which can be slow. Look for where you use medium or large objects. Are you putting them in container classes? Those classes move objects around. Change those to pointers (preferably smart pointers, like std::tr1::shared_ptr<>).
If you're not experienced in C++ (and an experienced and competent C++ programmer would be highly unlikely to be microoptimizing), try to find somebody who is. C++ is not a really simple language, having a lot more legacy baggage than Java or C#, and you could be missing quite a few things.
Free C++ profilers:
What's the best free C++ profiler for Windows?
"Porting" performance-critical code from one language to another is usually a bad idea. You tend not to use the target language (C++ in this case) to its full potential.
Some of the worst C++ code I've seen was ported from Java. There was "new" for almost everything - normal for Java, but a sure performance killer for C++.
You're usually better off not porting, but reimplementing the critical parts.
The main reason C#/Java programs do not translate well (assuming everything else is correct). Is that C#/Java developers have not grokked the concept of objects and references correctly. Note in C#/Java all objects are passed by (the equivalent of) a pointer.
Class Message
{
char buffer[10000];
}
Message Encrypt(Message message) // Here you are making a copy of message
{
for(int loop =0;loop < 10000;++loop)
{
plop(message.buffer[loop]);
}
return message; // Here you are making another copy of message
}
To re-write this in a (more) C++ style you should probably be using references:
Message& Encrypt(Message& message) // pass a reference to the message
{
...
return message; // return the same reference.
}
The second thing that C#/Java programers have a hard time with is the lack of Garbage collection. If you are not releasing any memory correctly, you could start running low on memory and the C++ version is thrashing. In C++ we generally allocate objects on the stack (ie no new). If the lifetime of the object is beyond the current scope of the method/function then we use new but we always wrap the returned variable in a smart pointer (so that it will be correctly deleted).
void myFunc()
{
Message m;
// read message into m
Encrypt(m);
}
void alternative()
{
boost::shared_pointer<Message> m(new Message);
EncryptUsingPointer(m);
}
Show your code. We can't tell you how to optimize your code if we don't know what it looks like.
You're absolutely wasting your time converting divisions by constants into shift operations. Those kinds of braindead transformations can be made even by the dumbest compiler.
Where you can gain performance is in optimizations that require information the compiler doesn't have. The compiler knows that division by a power of two is equivalent to a right-shift.
Apart from this, there is little reason to expect C++ to be faster. C++ is much more dependent on you writing good code. C# and Java will produce pretty efficient code almost no matter what you do. But in C++, just one or two missteps will cripple performance.
And honestly, if you expected C++ to be faster because it's "native" or "closer to the metal", you're about a decade too late. JIT'ed languages can be very efficient, and with one or two exceptions, there's no reason why they must be slower than a native language.
You might find these posts enlightening.
They show, in short, that yes, ultimately, C++ has the potential to be faster, but for the most part, unless you go to extremes to optimize your code, C# will be just as fast, or faster.
If you want your C++ code to compete with the C# version, then a few suggestions:
Enable optimizations (you've hopefully already done this)
Think carefully about how you do disk I/O (IOStremas isn't exactly an ideal library to use)
Profile your code to see what needs optimizing.
Understand your code. Study the assembler output, and see what can be done more efficiently.
Many common operations in C++ are surprisingly slow. Dynamic memory allocation is a prime example. It is almost free in C# or Java, but very costly in C++. Stack-allocation is your friend.
Understand your code's cache behavior. Is your data scattered all over the place? It shouldn't be a surprise then that your code is inefficient.
Totally of topic but...
I found some info on the encryption module on the homepage you link to from your profile http://www.coreyogburn.com/bigproject.html
(quote)
Put together by my buddy Karl Wessels and I, we believe we have quite a powerful new algorithm.
What separates our encryption from the many existing encryptions is that ours is both fast AND secure. Currently, it takes 5 seconds to encrypt 100 MB. It is estimated that it would take 4.25 * 10^143 years to decrypt it!
[...]
We're also looking into getting a copyright and eventual commercial release.
I don't want to discourage you, but getting encryption right is hard. Very hard.
I'm not saying it's impossible for a twenty year old webdeveloper to develop an encryption algorithm that outshines all existing algorithms, but it's extremely unlikely, and I'm very sceptic, I think most people would be.
Nobody who cares about encryption would use an algorithm that's unpublished. I'm not saying you have to open up your sourcecode, but the workings of the algorithm must be public, and scrutinized, if you want to be taken seriously...
There are areas where a language running on a VM outperforms C/C++, for example heap allocation of new objects. You can find more details here.
There is a somwhat old article in Doctor Dobbs Journal named Microbenchmarking C++, C#, and Java where you can see some actual benchmarks, and you will find that C# sometimes is faster than C++. One of the more extreme examples is the single hash map benchmark. .NET 1.1 is a clear winner at 126 and VC++ is far behind at 537.
Some people will not believe you if you claim that a language like C# can be faster than C++, but it actually can. However, using a profiler and the very high level of fine-grained control that C++ offers should enable you to rewrite your application to be very performant.
When serious about performance you might want to be serious about profiling.
Separately, the "string" object implementation used in C# Java and C++, is noticeably slower in C++.
There are some cases where VM based languages as C# or Java can be faster than a C++ version. At least if you don't put much work into optimization and have a good knowledge of what is going on in the background. One reason is that the VMs can optimize byte-code at runtime and figure out which parts of the program are used often and changes its optimization strategy. On the other hand an old fashioned compiler has to decide how to optimize the program on compile-time and may not find the best solution.
The C# JIT probably noticed at run-time that the CPU is capable of running some advanced instructions, and is compiling to something better than what the C++ was compiled.
You can probably (surely with enough efforts) outperform this by compiling using the most sophisticated instructions available to the designated C.P.U and using knowledge of the algorithm to tell the compiler to use SIMD instructions at specific stages.
But before any fancy changes to your code, make sure are you C++ compiling to your C.P.U, not something much more primitive (Pentium ?).
Edit:
If your C++ program does a lot of unwise allocations and deallocations this will also explain it.
In another thread, I pointed out that doing a direct translation from one language to another will almost always end up in the version in the new language running more poorly.
Different languages take different techniques.
Try the intel compiler. Its much better the VC or gcc. As for the original question, I would be skeptical. Try to avoid using any containers and minimize the memory allocations in the offending function.
[Joke]There is an error in line 13[/Joke]
Now, seriously, no one can answer the question without the source code.
But as a rule of the thumb, the fact that C++ is that much slower than managed one most likely points to the difference of memory management and object ownership issues.
For instance, if your algorithm is doing any dynamic memory allocations inside the processing loop, this will affect the performance. If you pass heavy structures by the value, this will affect the performance. If you do unnecessary copies of objects, this will affect the performance. Exception abuse will cause performance to go south. And still counting.
I know the cases when forgotten "&" after the parameter name resulted in weeks of profiling/debugging:
void DoSomething(const HeavyStructure param); // Heavy structure will be copied
void DoSomething(const HeavyStructure& param); // No copy here
So, check your code to find possible bottlenecks.
C++ is not a language where you must use classes. In my opinion its not logical to use OOP methodologies where it doesnt really help. For a encrypter / decrypter its best not use classes; use arrays, pointers, use as few functions / classes / files possible. Best encryption system consists of a single file containing few functions. After your function works nice you can wrap it into classes if you wish. Also check the release build. There is huge speed difference
Nothing is faster than good machine/assembly code, so my goal when writing C/C++ is to write my code in such a way that the compiler understands my intentions to generate good machine code. Inlining is my favorite way to do this.
First, here's an aside. Good machine code:
uses registers more often than memory
rarely branches (if/else, for, and while)
uses memory more often than functions calls
rarely dynamically allocates any more memory (from the heap) than it already has
If you have a small class with very little code, then implement its methods in the body of the class definition and declare it locally (on the stack) when you use it. If the class is simple enough, then the compiler will often only generate a few instructions to effect its behavior, without any function calls or memory allocation to slow things down, just as if you had written the code all verbose and non-object oriented. I usually have assembly output turned on (/FAs /Fa with Visual C++) so I can check the output.
It's nice to have a language that allows you to write high-level, encapsulated object-oriented code and still translate into simple, pure, lightning fast machine code.
Here's my 2 cents.
I wrote a BlowFish cipher in C (and C#). The C# was almost 'identical' to the C.
How I compiled (i cant remember the numbers now, so just recalled ratios):
C native: 50
C managed: 15
C#: 10
As you can see, the native compilation out performs any managed version. Why?
I am not 100% sure, but my C version compiled to very optimised assembly code, the assembler output almost looked the same as a hand written assembler one I found.

Pointers in C# and how frequently it is used in the application?

For me , the Pointer was one of the hardest concept in programming languages in C++. When I was learning C++, I spent tremendous amount of time learning it. However, Now I primarily work in projects that are entirely written in languages like C#, and VB.NET etc. As a matter fact, I have NOT touched C++ for almost 4 years. Even though, C# has pointer, but I have not encouter the situation where I must use pointer in C#. So my question is , what kinds of productivity can we obtain in C# by using pointer ? what are the situation where the uses of the pointer is must?
You're already using lots of pointers in C#, except that they don't look like pointers. Every time you do something with an instance of a class, that's a pointer. You're getting almost all the potential benefit already, without the hassle.
It is possible to use pointers more explicitly in C#, which is what most people mean by C# pointers, but I would think the occasions would be very rare. They may be useful to link to C libraries and the like, but other than that I don't see much use for them.
Personally, I've never had a need for using pointers in .NET, but if you're dealing with absolute performance critical code, you'd use pointers. If you look at the System.String class, you'll see that a lot of the methods that handle the string manipulation, use pointers. Also, when dealing with image processing, very often it's useful to use pointers. Now, one can definitely argue whether those sort of applications should be written in .NET in the first place (I think they should), but at least if you need to squeeze out that extra bit of speed, you can.
I use pointers in C# only in rare circumstances that mostly have to do with sending/receiving data, where you have to convert a byte array to a struct and vice-versa. Though even then, you don't have to deal with pointers directly typically.
In some cases, you can use pointers to improve performance, because with the Marshaller, sometimes you have to copy memory to access data, while with pointers, you can access it directly (think Bitmap.Lock()).
Personally, I've never needed to use a pointer in C#. If I need that kind of functionality, I write that code in C++/CLI, and call it from C#. If I need to pass pointers from C# to C++/CLI or vice-versa, I pass them around as an IntPtr and cast it to the type I need in C++/CLI.
In my opinion - if you're using pointers in C#, in 99% of cases, you're using the language wrong.
Edit:
The nice thing about C++/CLI is that you can mark individual classes for native-only compilation. I do a lot of image processing work which needs to happen very quickly; it uses a lot of pointer-based code. I generally have a managed C++/CLI object forward calls to a native C++ object where my processing takes place. I turn on optimizations for that native code and viola, I get a nice performance gain.
Granted, this only matters if the performance gain you get by executing native, optimized code can offset the overhead of managed to unmanaged transitions. In my case, it always does.

Categories