Today I tell you about one of my favorite benchmarks (this method doesn't return a useful value, we need it only as an example):

```
[Benchmark]
public string Sum()
{
double a = 1, b = 1;
var sw = new Stopwatch();
for (int i = 0; i < 10001; i++)
a = a + b;
return string.Format("{0}{1}", a, sw.ElapsedMilliseconds);
}
```

An interesting fact: if you call `Stopwatch.GetTimestamp()`

before the first call of the `Sum`

method, you improve `Sum`

performance several times (works only with LegacyJIT-x86).

It's a story about how I tried to open a project in Visual Studio for a few hours. The other day, I was going to do some work. I pulled last commits from a repo, opened Visual Studio, and prepared to start coding. However, one of a project in my solution failed to open with a strange message:

```
error : The operation could not be completed.
```

In the Solution Explorer, I had *"load failed"* as a project status and the following message instead of the file tree: *"The project requires user input. Reload the project for more information."* Hmm, ok, I reloaded the project and got a few more errors:

```
error : The operation could not be completed.
error : The operation could not be completed.
```

Read more CommentsChallenge of the day: what will the following code display?

```
[StructLayout(LayoutKind.Explicit)]
public struct UInt128
{
[FieldOffset(0)]
public ulong Value1;
[FieldOffset(8)]
public ulong Value2;
}
[StructLayout(LayoutKind.Sequential)]
public struct MyStruct
{
public UInt128 UInt128;
public char Char;
}
class Program
{
public static unsafe void Main()
{
var myStruct = new MyStruct();
var baseAddress = (int)&myStruct;
var uInt128Adress = (int)&myStruct.UInt128;
Console.WriteLine(uInt128Adress - baseAddress);
Console.WriteLine(Marshal.OffsetOf(typeof(MyStruct), "UInt128"));
}
}
```

A hint: two zeros or two another same values are wrong answers in the general case. The following table shows the console output on different runtimes:

MS.NET-x86 | MS.NET-x64 | Mono | |
---|---|---|---|

uInt128Adress - baseAddress | 4 | 8 | 0 |

Marshal.OffsetOf(typeof(MyStruct), "UInt128") | 0 | 0 | 0 |

If you want to know why it happens, you probably should learn some useful information about blittable types.

Read more Comments**Update:** The below results are valid for the release version of RyuJIT.

The challenge of the day: which method is faster?

```
public double Sqrt13()
{
return Math.Sqrt(1) + Math.Sqrt(2) + Math.Sqrt(3) + Math.Sqrt(4) + Math.Sqrt(5) +
Math.Sqrt(6) + Math.Sqrt(7) + Math.Sqrt(8) + Math.Sqrt(9) + Math.Sqrt(10) +
Math.Sqrt(11) + Math.Sqrt(12) + Math.Sqrt(13);
}
public double Sqrt14()
{
return Math.Sqrt(1) + Math.Sqrt(2) + Math.Sqrt(3) + Math.Sqrt(4) + Math.Sqrt(5) +
Math.Sqrt(6) + Math.Sqrt(7) + Math.Sqrt(8) + Math.Sqrt(9) + Math.Sqrt(10) +
Math.Sqrt(11) + Math.Sqrt(12) + Math.Sqrt(13) + Math.Sqrt(14);
}
```

I have measured the methods performance with help of BenchmarkDotNet for RyuJIT RC (a part of .NET Framework 4.6 RC) and received the following results:

`// BenchmarkDotNet=v0.7.4.0 // OS=Microsoft Windows NT 6.2.9200.0 // Processor=Intel(R) Core(TM) i7-4702MQ CPU ＠ 2.20GHz, ProcessorCount=8 // CLR=MS.NET 4.0.30319.0, Arch=64-bit [RyuJIT] Common: Type=Math_DoubleSqrtAvx Mode=Throughput Platform=X64 Jit=RyuJit .NET=Current`

`Method | AvrTime | StdDev | op/s | ------- |--------- |---------- |------------- | Sqrt13 | 55.40 ns | 0.571 ns | 18050993.06 | Sqrt14 | 1.43 ns | 0.0224 ns | 697125029.18 |`

How so? If I add one more `Math.Sqrt`

to the expression, the method starts work 40 times faster! Let's examine the situation..

Challenge of the day: what will the following code display?

```
struct Point
{
public int X;
public int Y;
}
static void Print(Point p)
{
Console.WriteLine(p.X + " " + p.Y);
}
static void Main()
{
var p = new Point();
for (p.X = 0; p.X < 2; p.X++)
Print(p);
}
```

The right answer: it depends. There is a bug in CLR2 JIT-x86 which spoil this wonderful program. This story is about optimization that called unrolling of small loops. This is a very interesting theme, let's discuss it in detail.

Read more CommentsRyuJIT will be available soon. It is a next generation JIT-compiler for .NET-applications. Microsoft likes to tell us about the benefits of SIMD using and JIT-compilation time reducing. But what about basic code optimization which is usually applying by a compiler? Today we talk about the loop unrolling (unwinding) optimization. In general, in this type of code optimization, the code

```
for (int i = 0; i < 1024; i++)
Foo(i);
```

transforms to

```
for (int i = 0; i < 1024; i += 4)
{
Foo(i);
Foo(i + 1);
Foo(i + 2);
Foo(i + 3);
}
```

Such approach can significantly increase performance of your code. So, what's about loop unrolling in .NET?

Read more CommentsSometimes I want to know used JIT compiler version in my little C# experiments. It is clear that it is possible to determine the version in advance based on the environment. However, sometimes I want to know it in runtime to perform specific code for the current JIT compiler. More formally, I want to get the value from the following enum:

```
public enum JitVersion
{
Mono, MsX86, MsX64, RyuJit
}
```

It is easy to detect Mono by existing of the `Mono.Runtime`

class. Otherwise, we can assume that we work with Microsoft JIT implementation. It is easy to detect JIT-x86 with help of `IntPtr.Size == 4`

. The challenge is to distinguish JIT-x64 and RyuJIT. Next, I will show how you can do it with help of the bug from my previous post.

Can you say, what will the following code display for `step=1`

?

```
public void Foo(int step)
{
for (int i = 0; i < step; i++)
{
bar = i + 10;
for (int j = 0; j < 2 * step; j += step)
Console.WriteLine(j + 10);
}
}
```

If you think about specific numbers, you are wrong. The right answer: it depends. The post title suggests to us, the program can has a strange behavior for x64.

Read more CommentsSometimes you can learn a lot during reading source .NET. Let's open the source code of a `Decimal`

constructor from .NET Reference Source (mscorlib/system/decimal.cs,158):

```
// Constructs a Decimal from an integer value.
//
public Decimal(int value) {
// JIT today can't inline methods that contains "starg" opcode.
// For more details, see DevDiv Bugs 81184: x86 JIT CQ: Removing the inline striction of "starg".
int value_copy = value;
if (value_copy >= 0) {
flags = 0;
}
else {
flags = SignMask;
value_copy = -value_copy;
}
lo = value_copy;
mid = 0;
hi = 0;
}
```

The comment states that JIT-x86 can't apply the inlining optimization for a method that contains the starg IL-opcode. Curious, is not it?

Read more CommentsThis post is a logical continuation of the Jon Skeet's blog post “When is a string not a string?”. Jon showed very interesting things about behavior of ill-formed Unicode strings in .NET. I wondered about how similar examples will work on Mono. And I have got very interesting results.

Let's take the Jon's code with a small modification. We will just add `text`

null check in `DumpString`

:

```
using System;
using System.ComponentModel;
using System.Text;
using System.Linq;
[Description(Value)]
class Test
{
const string Value = "X\ud800Y";
static void Main()
{
var description = (DescriptionAttribute)typeof(Test).
GetCustomAttributes(typeof(DescriptionAttribute), true)[0];
DumpString("Attribute", description.Description);
DumpString("Constant", Value);
}
static void DumpString(string name, string text)
{
Console.Write("{0}: ", name);
if (text != null)
{
var utf16 = text.Select(c => ((uint) c).ToString("x4"));
Console.WriteLine(string.Join(" ", utf16));
}
else
Console.WriteLine("null");
}
}
```

Read more Comments