Posts

Showing posts with the label c#

Performance impact of sorted arrays.

Image
Computer performance is filled with unexpected results. This morning on   stack overflow  I found  such a result, and decided to replicate it in C#. Take an array of random integers and sum only the big integers.  Next, sort the array and re-sum the big integers. Does sorting the array affect the time taken to compute the aggregation? Let's code it up: The results: Wow, it's 5 times faster to perform this sum over a sorted array then an unsorted array. What's going on? Branch prediction!  If you've never heard of branch prediction check out the stack overflow answer that inspired  this post. You can quickly replicate this experiment using LinqPad and MeasureIt.Net , by loading this file .

Getting Caller Information in C# without reflection (AKA: __LINE__ and __FILE__)

When writing tracing code it's very useful to know your caller. If you've used C or C++ you likely combined macro's,  __LINE__  and __FILE__ to implement this capability. In C# 4.5 there is a better way to solve this problem. By adding attributed function parameters you can instruct the compiler to have your callers supply their calling information.  The code (full source @  bitbucket ): public static void TraceMessage(string message, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0) { Console.WriteLine("message: " + message); Console.WriteLine("member name: " + memberName); Console.WriteLine("source file path: " + sourceFilePath); Console.WriteLine("source line number: " + sourceLineNumber); } st...

Dumping the method descriptor for a System.Action (delegate)

In my previous post I needed to figure out what method descriptor a System.Action points to. This is painful so I wrote a small debugger script to automate it.  To use the script, copy  this code  to dumpMDForAction.dbg. Many thanks to Alois Kraos  for posting how to do this. Without further ado, fire up cdb and  find a System.Action: 0:000> !do 0000003de7023078 Name: System.Action MethodTable: 000007f9d26b9a68 EEClass: 000007f9d2071c10 Size: 64(0x40) bytes File: C:\Windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll Fields: MT Field Offset Type VT Attr Value Name 000007f9d26c1ac8 400002d 8 System.Object 0 instance 0000003de7023078 _target 000007f9d26c1ac8 400002e 10 System.Object 0 instance 0000003de7028800 _methodBase 000007f9d26c60d8 400002f 18 System.IntPtr 1 instance 3de52e0...

Run time costs of small operations in C#.

Image
Thank you smart people that helped me understand this:  Vance Morrison ; Kevin Frei; Dave Detlefs; Jan Kotas; Sean Selitrennikoff; Nathan Iarovich; Dave Driver. One of my colleagues read this post and pointed out for really small operations e.g  {i++ } the cost of the measurement system is exceeding the cost of the operations. I agree completely,  and recommend using  measure it  and reading the help if you need to measure small things. My colleague also noticed something interesting; in this code    (full  code  here , proof of concept in linqpad using measureit .) : class Program { static int interlocked = 0; static int staticInt = 0; static void DoNop() { } static void IncrementStaticInt() { staticInt++; } // This is an array to make it easier to debug in cdb. static NamedAction[] namedActions; static void Main(string[] args) { int loc...

Run time costs of common operations in C#

Disclaimers: 1) The benchmarking methodology below should not be used for very small things like i++. For measuring small things see  this . 2) Since writing the below I've modified  measure it  for integration with linqpad - use that instead. 3) If you still want to read this, be my guest :) Today we debated if Enum.ToString() is too slow to be used. To my surprise it takes 1-5 micro seconds on my core-i7 laptop. If 5 micro seconds is too slow for you, the i nternet has you covered . Naturally, I was curious about  cost of other operations so I measured those as well. You can reproduce and extend  my experiment by putting the below code into linqpad . The output from the current code on my laptop is: Milliseconds to perform 100000 iterations Enum.ToString() took 411 ms NewGuid() took 31 ms InterlockedIncrement() took 3 ms Lock() took 3 ms i++ took 2 ms static TimeSpan TimeIt(int iterations, string title, Action action) { var watch = Stopwa...

Using WinDBG/CDB and SOS to find a thread given a ManagedThreadId

CDB and SOS have more power than most people realize, I’ll use this post to show some some handy cdb/sos tricks while at the same answering the simple question of which thread a ManagedThreadId maps to. At the end of this post you’ll be able to: Map a ManagedThreadId to the correct thread ordinal Use CDB to convert from decimal to hex Pipe CDB commands through pipeline commands like findstr Full source for the simple app below can be found here . In the below app we want to figure which thread we’re running on so we can inspect the stack. internal class Program { private static void SleepForever() { Thread.Sleep(Int32.MaxValue); } static void Main(string[] args) { const int countThreadsToStart = 20; foreach (var unused in Enumerable.Range(0, countThreadsToStart)) { // Instantiate thread that prints and stores its ManagedThreadId. new Thread(() => {...