<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://nimaara.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://nimaara.com/" rel="alternate" type="text/html" /><updated>2026-03-06T23:08:08+00:00</updated><id>https://nimaara.com/feed.xml</id><title type="html">Hi, I am Nima</title><subtitle>Nima is a full-stack .NET technologist focusing on building high-performance, low-latency server and distributed message-based components; He is also a library author and OSS contributor.</subtitle><author><name>Nima Ara</name></author><entry><title type="html">Tranquillity in C# with EasyDictionary</title><link href="https://nimaara.com/2019/04/10/tranquillity-in-csharp.html" rel="alternate" type="text/html" title="Tranquillity in C# with EasyDictionary" /><published>2019-04-10T00:00:00+00:00</published><updated>2019-04-10T00:00:00+00:00</updated><id>https://nimaara.com/2019/04/10/tranquillity-in-csharp</id><content type="html" xml:base="https://nimaara.com/2019/04/10/tranquillity-in-csharp.html"><![CDATA[<p><a href="https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2"><code>Dictionary&lt;TKey, TValue&gt;</code></a> is probably among the most used collections in C#. If you are reading this blog then I am assuming you know the fundamentals of this data structure and if you are not, you can have a look at <a href="https://www.red-gate.com/simple-talk/blogs/the-net-dictionary/">The .NET Dictionary</a> which covers it in detail. As a summary however:</p>

<ul>
  <li><code>Dictionary&lt;TKey, TValue&gt;</code> is a <a href="https://en.wikipedia.org/wiki/Hash_table">Hash table</a> mapping a set of keys to a set of values.</li>
  <li>Each key in the dictionary must be unique according to the <a href="https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.iequalitycomparer-1"><code>IEqualityComparer&lt;TKey&gt;</code></a> (used to determine the equality of the keys in the dictionary).</li>
  <li>Retrieving a value by using its key has a complexity of <em>O(1)</em> (very fast).</li>
</ul>

<h3 id="typical-use-case">Typical use-case</h3>

<p>Most of the time, I use a dictionary to map a model to one of its properties; Let’s say an <em>Id</em> or <em>Name</em>. For example, given the model:</p>

<pre><code class="language-csharp">public sealed record class Person(Guid Id, string Name, uint Age);
</code></pre>

<p>And given a collection of people from somewhere:</p>

<pre><code class="language-csharp">IEnumerable&lt;Person&gt; people = Enumerable.Range(1, 10)
    .Select(n =&gt; new Person(Guid.NewGuid(), "P-" + n.ToString(), (uint)n));
</code></pre>

<p>We may now want to make <code>people</code> available for fast lookups based on the <em>Id</em> of a given person.</p>

<p>Well that’s easy, let’s new-up a <code>Dictionary</code> and add our people to it:</p>

<pre><code class="language-csharp">Dictionary&lt;Guid, Person&gt; dic = new();
foreach(Person p in people)
{
    dic[p.Id] = p;
    // or if you don't like the index syntax then you can instead do:
    // dic.Add(p.Id, p);
}
</code></pre>

<p>We can also create a dictionary directly from the <code>IEnumerable&lt;Person&gt;</code> by doing:</p>

<pre><code class="language-csharp">Dictionary&lt;Guid, Person&gt; dic = Enumerable.Range(1, 10)
    .Select(n =&gt; new Person(Guid.NewGuid(), "P-" + n.ToString(), (uint)n))
    .ToDictionary(p =&gt; p.Id, p =&gt; p);
</code></pre>

<p>Okay not the most verbose code to complain about but if you take into account that every time you want to <code>Add</code>, <code>TryGet</code> or check for existence (<code>Contains</code>) of a given value you need to specify the <code>TKey</code> explicitly then you will be able to also hear my <em>OCD</em> screaming to make things simpler.</p>

<p style="text-align: center;">
    <img alt="picture of a meme showing a creature with a twitching eye" src="/assets/imgs/2019-04-10-tranquillity-in-csharp.ocd.gif" width="400" />    
</p>

<h3 id="what-if">What if…</h3>

<p>Would it not be more <em>elegant</em> if we could just add a person and let the dictionary get the <em>Id</em> from it? Something similar to:</p>

<pre><code class="language-csharp">EasyDictionary&lt;Guid, Person&gt; dic = new (...);
foreach(Person p in people)
{
    dic.Add(p)
}
</code></pre>

<p>In order to do this, we would need some sort of a key selector which for a given <code>TValue</code> would return a <code>TKey</code>. In other words, we need a <code>Func&lt;TValue, TKey&gt;</code> which in our example would be a <code>Func&lt;Person, Guid&gt;</code>.</p>

<p>Now that we know what a key selector would look like, we can start thinking about the structure of our new abstraction:</p>

<pre><code class="language-csharp">public sealed class EasyDictionary&lt;TKey, TValue&gt;
{
    public EasyDictionary(Func&lt;TValue, TKey&gt; keySelector)
    {
        KeySelector = keySelector;
    }

    public Func&lt;TValue, TKey&gt; KeySelector { get; }
    ...
}
</code></pre>

<p>All we have to do now is put a <code>Dictionary&lt;TKey, TValue&gt;</code> inside our wrapper, implement <code>IReadOnlyDictionary&lt;TKey, TValue&gt;</code> as well as <code>ICollection&lt;TValue&gt;</code> and then redirect all the required methods and properties to our internal dictionary.</p>

<h3 id="job-done">Job done!</h3>

<p>I am going to spare you the unexciting code here and instead, point you to the completed version in <a href="https://github.com/NimaAra/Easy.Common/blob/master/Easy.Common/EasyDictionary.cs"><code>EasyDictionary</code></a> available as part of the <a href="https://github.com/NimaAra/Easy.Common">Easy.Common</a> <a href="https://www.nuget.org/packages/Easy.Common">NuGet package</a>.</p>

<p>Armed with our much smarter dictionary, let us see what we can do with it (look at the <a href="https://github.com/NimaAra/Easy.Common/blob/master/Easy.Common.Tests.Unit/EasyDictionary/EasyDictionaryTests.cs">unit tests</a> for more examples):</p>

<pre><code class="language-csharp">Person[] people = Enumerable.Range(1, 10)
    .Select(n =&gt; new Person(Guid.NewGuid(), "P-" + n.ToString(), (uint)n))
    .ToArray();

EasyDictionary&lt;Guid, Person&gt; easyDic = new(p =&gt; p.Id);
foreach(Person p in people)
{
    easyDic.Add(p);
}

// Let's lookup an existing value.
Person firstPerson = people[0];

easyDic.Contains(firstPerson);                          // true
easyDic.ContainsKey(firstPerson.Id);                    // true

easyDic[firstPerson.Id];                                // firstPerson

easyDic.TryGetValue(firstPerson.Id, out Person yep);    // true (yep is firstPerson)

easyDic.Remove(firstPerson.Id);                         // true (removed)
easyDic.Remove(firstPerson);                            // false (no longer there)

easyDic.TryGetValue(firstPerson.Id, out Person _);      // false (no longer there)
</code></pre>

<p>We can also enumerate over the items:</p>

<pre><code class="language-csharp">foreach (Person p in easyDic) { /* do what you want with p */ }
</code></pre>

<p>But what about over-writing an existing item? Well, we can use <code>AddOrReplace</code> for that:</p>

<pre><code class="language-csharp">Person olderPerson = new(
    firstPerson.Id,
    firstPerson.Name,
    firstPerson.Age + 41);

easyDic.AddOrReplace(olderPerson); // true;
</code></pre>

<h3 id="bonus-point">Bonus point</h3>

<p>We can even throw a bunch of <a href="https://github.com/NimaAra/Easy.Common/blob/master/Easy.Common/Extensions/EnumerableExtensions.cs#L148,#L159">extension methods</a> to be able to do:</p>

<pre><code class="language-csharp">EasyDictionary&lt;Guid, Person&gt; dic = Enumerable.Range(1, 10)
    .Select(n =&gt; new Person(Guid.NewGuid(), "P-" + n.ToString(), (uint)n))
    .ToEasyDictionary(p =&gt; p.Id);
</code></pre>

<p>Now this is tranquillity!</p>

<p style="text-align: center;">
    <img alt="picture of a meme showing a calm horse" src="/assets/imgs/2019-04-10-tranquillity-in-csharp.horse.gif" width="400" />    
</p>]]></content><author><name>Nima Ara</name></author><category term="C#" /><category term=".NET" /><summary type="html"><![CDATA[Dictionary&lt;TKey, TValue&gt; is probably among the most used collections in C#. If you are reading this blog then I am assuming you know the fundamentals of this data structure and if you are not, you can have a look at The .NET Dictionary which covers it in detail. As a summary however:]]></summary></entry><entry><title type="html">Generating IDs in C#, ‘safely’ and efficiently</title><link href="https://nimaara.com/2018/10/10/generating-ids-in-csharp.html" rel="alternate" type="text/html" title="Generating IDs in C#, ‘safely’ and efficiently" /><published>2018-10-10T00:00:00+00:00</published><updated>2018-10-10T00:00:00+00:00</updated><id>https://nimaara.com/2018/10/10/generating-ids-in-csharp</id><content type="html" xml:base="https://nimaara.com/2018/10/10/generating-ids-in-csharp.html"><![CDATA[<p>Recently I needed to find an efficient algorithm for generating unique IDs in a highly concurrent and low latency component. After looking at several options I settled for the algorithm used by the <a href="https://github.com/aspnet/KestrelHttpServer">Kestrel HTTP</a> server. <em>Kestrel</em> generates request IDs that are stored in the <code>TraceIdentifier</code> property hanging off the <a href="https://github.com/aspnet/HttpAbstractions/blob/07d115400e4f8c7a66ba239f230805f03a14ee3d/src/Microsoft.AspNetCore.Http.Abstractions/HttpContext.cs">HTTPContext</a>.</p>

<p>The IDs are base-32 encoded increments of a <code>long</code> (which is seeded based on the <code>DateTime.UtcNow.Ticks</code>) using the characters <em>1</em> to <em>9</em> and <em>A</em> to <em>V</em>.</p>

<p>Let’s look at the <a href="https://github.com/aspnet/KestrelHttpServer/blob/6fde01a825cffc09998d3f8a49464f7fbe40f9c4/src/Kestrel.Core/Internal/Infrastructure/CorrelationIdGenerator.cs#L9">code</a>:</p>

<pre><code class="language-csharp">internal static class CorrelationIdGenerator
{
    private static readonly string _encode32Chars = "0123456789ABCDEFGHIJKLMNOPQRSTUV";

    private static long _lastId = DateTime.UtcNow.Ticks;

    public static string GetNextId() =&gt; GenerateId(Interlocked.Increment(ref _lastId));

    private static unsafe string GenerateId(long id)
    {
        char* charBuffer = stackalloc char[13];

        charBuffer[0] = _encode32Chars[(int)(id &gt;&gt; 60) &amp; 31];
        charBuffer[1] = _encode32Chars[(int)(id &gt;&gt; 55) &amp; 31];
        charBuffer[2] = _encode32Chars[(int)(id &gt;&gt; 50) &amp; 31];
        charBuffer[3] = _encode32Chars[(int)(id &gt;&gt; 45) &amp; 31];
        charBuffer[4] = _encode32Chars[(int)(id &gt;&gt; 40) &amp; 31];
        charBuffer[5] = _encode32Chars[(int)(id &gt;&gt; 35) &amp; 31];
        charBuffer[6] = _encode32Chars[(int)(id &gt;&gt; 30) &amp; 31];
        charBuffer[7] = _encode32Chars[(int)(id &gt;&gt; 25) &amp; 31];
        charBuffer[8] = _encode32Chars[(int)(id &gt;&gt; 20) &amp; 31];
        charBuffer[9] = _encode32Chars[(int)(id &gt;&gt; 15) &amp; 31];
        charBuffer[10] = _encode32Chars[(int)(id &gt;&gt; 10) &amp; 31];
        charBuffer[11] = _encode32Chars[(int)(id &gt;&gt; 5) &amp; 31];
        charBuffer[12] = _encode32Chars[(int)id &amp; 31];

        return new string(charBuffer, 0, 13);
    }
}
</code></pre>

<p>If we invoke it like so:</p>

<pre><code class="language-csharp">CorrelationIdGenerator.GetNextId();
Thread.Sleep(50);
CorrelationIdGenerator.GetNextId();
Thread.Sleep(150);
CorrelationIdGenerator.GetNextId();
</code></pre>

<p>We get:</p>

<pre><code class="language-shell">0HLH7QN5JTC87
0HLH7QN5JTC88
0HLH7QN5JTC89
</code></pre>

<p>Overall, this code is very efficient in how it constructs a <code>string</code> representation of an ID based on a <code>long</code> by avoiding the <code>.ToString()</code> call which (according to the <a href="https://github.com/aspnet/KestrelHttpServer/blob/6fde01a825cffc09998d3f8a49464f7fbe40f9c4/src/Kestrel.Core/Internal/Infrastructure/CorrelationIdGenerator.cs#L23">comments on the code</a>) would be <strong><em>~310%</em></strong> and <strong><em>~600%</em></strong> slower on <em>x64</em> and <em>x86</em> respectively.</p>

<p>It also avoids allocating memory on the <em>heap</em> avoiding frequent <em>GC</em> collections (when invoked on a hot path) by allocating a <code>char[]</code> on the <em>stack</em>, populating it with the encoded values then passing the <code>char</code> pointer to the <code>string</code> constructor.</p>

<h3 id="impressive-stuff-but">Impressive stuff, but…</h3>

<p>Allocating memory on the <em>stack</em> (using <code>stackalloc</code>) has long been used as a performance trick; Not only it can be faster than <em>heap</em> allocation but it also avoids <em>GC</em>. However, there are some caveats:</p>

<ul>
  <li>
    <p><code>stackalloc</code> is explicitly unsafe (hence why I used <code>'safe'</code> in the title of this article) which means you would have to compile your assembly as such (by using the <code>unsafe</code> flag). Doing so means that your assembly may be black-listed by some environments where loading of <code>unsafe</code> assemblies are not permitted. e.g. <em>SQLServer</em> (<a href="https://docs.microsoft.com/en-us/sql/relational-databases/clr-integration/assemblies/creating-an-assembly?view=sql-server-2017">although there are workarounds</a>). (Also note that as of <em>C#7.2</em> <code>unsafe</code> is no longer required as long as you use <code>Span</code> when using <code>stackalloc</code>)</p>
  </li>
  <li>
    <p>The amount of data you are allowed to allocate is very limited. Managed stacks are limited to <strong><em>1MB</em></strong> in size and can be even less when running under <em>IIS</em>. Each stack frame takes a chunk of that space so the deeper the <em>stack</em> the less memory will be available.</p>
  </li>
  <li>
    <p>If an <em>exception</em> is thrown during allocation, you will get an <code>StackOverflowException</code> which is best known as an exception that cannot be caught. To be fair, <em>Kestrel</em> allocates a small block of memory when generating an ID, therefore, the chances of overflowing is rare; However, I still prefer to be on the <em>safe</em> side if and when I can.</p>
  </li>
</ul>

<p>With the above points in mind, I got curious to see if I can avoid using <code>unsafe</code> and:</p>

<ol>
  <li>Measure the performance impact of going without it.</li>
  <li>Try close the gap in the performance as much as possible and bring it to a reasonable level.</li>
</ol>

<h3 id="a-bit-about-how-we-are-going-to-measure-the-performance">A bit about how we are going to measure the performance</h3>

<p>If you have not yet read my previous articles I suggest having a look so that you can get familiar with some of the terms, tools and <em>my</em> overall approach to profiling.</p>

<ul>
  <li><a href="/2017/06/01/practical-parallelization-in-csharp.html">Practical Parallelization in C#</a></li>
  <li><a href="/2016/01/01/high-performance-logging-using-log4net.html">High Performance Logging using log4net</a></li>
  <li><a href="/2018/03/20/counting-lines-of-a-text-file-in-csharp.html">Counting Lines of a Text File in C#, the Smart Way</a></li>
  <li><a href="/2017/11/07/stuff-every-dotnet-app-should-log.html">Stuff Every .NET App Should be Logging at Startup</a></li>
</ul>

<p>We are going to start by doing some <em>coarse-grained/high-level</em> measurements just so that we get a general idea of the behaviour of <em>GC</em> and the running time for our baseline algorithm before we start playing with things.</p>

<p>We will be running a <em>.NET Core 2.1.5</em> application hosted on <em>Windows Server 2016</em>. Our machine is a <em>dual CPU Xeon processor</em> with <em>12</em> cores (<em>24</em> logical) clocking at <em>2.67GHz</em>.</p>

<p>Also note the <em>GC</em> mode of our application will be set to <code>Workstation</code> to emphasise the impact of the <em>GC</em> collections on the process (refer to the links above for finding out the difference between <code>Workstation</code> and <code>Server</code>). The overall result of our benchmark should still be valid with <code>Server</code> mode enabled.</p>

<p>Let’s start by generating <strong><em>100 million</em></strong> IDs while measuring the execution time and the <em>GC</em> behaviour. We will repeat this <strong><em>10 times</em></strong> and look at the average values across all executions.</p>

<p>Here is the code for generating the IDs:</p>

<pre><code class="language-csharp">Stopwatch sw = Stopwatch.StartNew();
for(int i = 0; i &lt; 100_000_000; i++)
{
    string id = CorrelationIdGenerator.GetNextId();
}
sw.Stop();

using Process process = Process.GetCurrentProcess();

Console.WriteLine("Execution time: {0}\r\n  - Gen-0: {1}, Gen-1: {2}, Gen-2: {3}",
        sw.Elapsed.ToString(),
        GC.CollectionCount(0),
        GC.CollectionCount(1),
        GC.CollectionCount(2));
</code></pre>

<p>This <em>not-so-fancy</em> code starts a timer, generates a lot of IDs then measures how many times <em>GC</em> collections occurred across the <em>3</em> generations.</p>

<h3 id="1-stackalloc">1. Stackalloc</h3>

<p>With all the above out of the way, here’s the average values for our baseline:</p>

<pre><code class="language-shell">- Execution time: 00:00:06.0511525
- Gen-0: 890, Gen-1: 0, Gen-2: 0
</code></pre>

<p>Okay, so it took around <strong><em>6 seconds</em></strong> and <strong><em>890</em></strong> <em>Gen0</em> <em>GC</em> to generate the IDs. If you are wondering why we have those <em>Gen0</em> collections despite allocating on the <em>stack</em>, well, the answer is; We are only allocating the <code>char[]</code> on the <em>stack</em> but we still need to allocate <strong><em>100 million</em></strong> <code>string</code> objects on the <em>heap</em>.</p>

<p>Now that we know how our baseline behaves, let us measure how we would have done if we had allocated the <code>char[]</code> on the <em>heap</em> instead of the <em>stack</em>.</p>

<h3 id="2-heap-allocation">2. Heap allocation</h3>

<p>All we have to do for this version is remove the <code>unsafe</code> keyword and new up a <code>char[]</code>, with everything else unchanged.</p>

<pre><code class="language-csharp">private static string GenerateId(long id)
{
    var buffer = new char[13];

    buffer[0] = _encode32Chars[(int)(id &gt;&gt; 60) &amp; 31];
    buffer[1] = _encode32Chars[(int)(id &gt;&gt; 55) &amp; 31];
    buffer[2] = _encode32Chars[(int)(id &gt;&gt; 50) &amp; 31];
    buffer[3] = _encode32Chars[(int)(id &gt;&gt; 45) &amp; 31];
    buffer[4] = _encode32Chars[(int)(id &gt;&gt; 40) &amp; 31];
    buffer[5] = _encode32Chars[(int)(id &gt;&gt; 35) &amp; 31];
    buffer[6] = _encode32Chars[(int)(id &gt;&gt; 30) &amp; 31];
    buffer[7] = _encode32Chars[(int)(id &gt;&gt; 25) &amp; 31];
    buffer[8] = _encode32Chars[(int)(id &gt;&gt; 20) &amp; 31];
    buffer[9] = _encode32Chars[(int)(id &gt;&gt; 15) &amp; 31];
    buffer[10] = _encode32Chars[(int)(id &gt;&gt; 10) &amp; 31];
    buffer[11] = _encode32Chars[(int)(id &gt;&gt; 5) &amp; 31];
    buffer[12] = _encode32Chars[(int)id &amp; 31];

    return new string(buffer, 0, 13);
}
</code></pre>

<p>Right, let us measure this version:</p>

<pre><code class="language-shell">- Execution time: 00:00:06.1883507
- Gen-0: 1780, Gen-1: 0, Gen-2: 0
</code></pre>

<p>Allocating on the <em>heap</em> seems to be about <strong><em>140 milliseconds</em></strong> slower than allocating on the <em>stack</em>; However, we have doubled the number of _GC_s. You may now be saying:</p>

<blockquote>
  <p>Dude, it doesn’t matter. Gen0 GCs are super fast…</p>
</blockquote>

<p>And you would be right; Both <em>Gen0</em> and <em>Gen1</em> collections are fast but unlike the <em>Gen2</em> collections, they are <em>blocking</em>; So, the more IDs you generate, the more frequent blocking collections wasting CPU cycles reducing your overall throughput. This may not be a problem for your application and if it is not then fair enough but there are scenarios where you need to reduce allocations as much as possible.</p>

<p>Okay, what is the most simple method of reducing those allocations? Reusing the <code>char[]</code> you say? Sure, let’s try that…</p>

<h3 id="3-re-using-the-buffer">3. Re-using the buffer</h3>

<p>What we need to do here is declare a field for our re-usable <code>char[]</code> buffer and overwrite it for every ID we generate.</p>

<pre><code class="language-csharp">private static readonly char[] _buffer = new char[13];

private static string GenerateId(long id)
{
    char[] buffer = _buffer;
    ...
}
</code></pre>

<p>And this is how it does:</p>

<pre><code class="language-shell">- Execution time: 00:00:05.5621535
- Gen-0: 890, Gen-1: 0, Gen-2: 0
</code></pre>

<p style="text-align: center;">
    <img alt="picture of a meme showing 2 colleagues saying how easy their task was" src="/assets/imgs/2018-10-10-generating-ids-in-csharp.that.was.easy.gif" width="400" />    
</p>

<p>Excellent! Awesome gains! Super fast! No allocation! Let’s wrap up!</p>

<h3 id="but-wait-a-second">But wait a second</h3>

<p>The <code>unsafe</code> version was <em>thread-safe</em> and our version is not. What if we want to generate the IDs from different threads and in parallel?</p>

<p>No worries, all we have to do is ensure access to the <code>char[]</code> is <em>synchronised</em> across all threads and for that we are going to use a simple <code>lock</code>, let’s go!</p>

<h3 id="4-locking-the-buffer">4. Locking the buffer</h3>

<p>With the rest of the code unchanged, Let us <code>lock</code> the body of our method like so:</p>

<pre><code class="language-csharp">private static string GenerateId(long id)
{
    lock(_buffer)
    {
        char[] buffer = _buffer;
        ...
    }
}
</code></pre>

<p>And run the benchmark:</p>

<pre><code class="language-shell">- Execution time: 00:00:07.7254997
- Gen-0: 890, Gen-1: 0, Gen-2: 0
</code></pre>

<p>Okay, no more allocation other than the actual <code>string</code> representation of our IDs. As you can see the cost of using the <code>lock</code> is an <strong><em>extra second</em></strong> or so of overhead.</p>

<h3 id="but-this-is-not-a-valid-test">But this is not a valid test</h3>

<p>Even though we now have a <em>thread-safe</em> method, we have so far only generated the IDs from a single thread and that is not representative of how our code can and will be used out in the wild.</p>

<h3 id="a-more-realistic-scenario">A more realistic scenario</h3>

<p>We are going to sprinkle a bit of parallelism to our benchmarking code by generating <strong><em>1 billion</em></strong> IDs across <strong><em>12</em></strong> threads in parallel.</p>

<p>Here is the updated code for our benchmarker:</p>

<pre><code class="language-csharp">const int ITERATION_COUNT = 1_000_000_000;
const int THREAD_COUNT = 12;

Stopwatch sw = Stopwatch.StartNew();

ParallelEnumerable
    .Range(1, ITERATION_COUNT)
    .WithDegreeOfParallelism(THREAD_COUNT)
    .WithExecutionMode(ParallelExecutionMode.ForceParallelism)
    .ForAll(_ =&gt; {
        string id = CorrelationIdGenerator.GetNextId();
    });

sw.Stop();

using Process process = Process.GetCurrentProcess();
Console.WriteLine("Execution time: {0}\r\n  - Gen-0: {1}, Gen-1: {2}, Gen-2: {3}",
        sw.Elapsed.ToString(),
        GC.CollectionCount(0),
        GC.CollectionCount(1),
        GC.CollectionCount(2));
</code></pre>

<h3 id="5-stackalloc-parallel">5. Stackalloc (Parallel)</h3>

<p>Now that we have updated our benchmarker, we need to run it again for our baseline to see how it does in parallel.</p>

<pre><code class="language-shell">- Execution time: 00:00:58.9092805
- Gen-0: 8980, Gen-1: 5, Gen-2: 0
</code></pre>

<p>Okay, so <strong><em>8,980</em></strong> <em>Gen0</em>, <strong><em>5</em></strong> <em>Gen1</em> and <strong><em>00:00:58.9092805</em></strong> is what we are up against.</p>

<h3 id="6-new-buffer-parallel">6. New buffer (Parallel)</h3>

<p>As a reminder, this is the version where we are creating a new <code>char[]</code> each time we are generating an ID. So let us see the performance of this <em>allocaty</em> method in parallel:</p>

<pre><code class="language-shell">- Execution time: 00:01:04.6934614
- Gen-0: 17959, Gen-1: 19, Gen-2: 0
</code></pre>

<p>Again, we can see the high number of allocations except this time the <em>Gen1</em> allocations are also increasing.</p>

<h3 id="7-locking-the-buffer-parallel">7. Locking the buffer (Parallel)</h3>

<p>Not to worry, we have it all under control. We will be avoiding all those nasty allocations thanks to our friend Mr <code>lock</code>! Let’s go:</p>

<pre><code class="language-shell">- Execution time: 00:04:14.3642255
- Gen-0: 9008, Gen-1: 25, Gen-2: 2
</code></pre>

<p style="text-align: center;">
    <img alt="picture of a meme showing an old woman adjusting her glasses while looking at a laptop screen" src="/assets/imgs/2018-10-10-generating-ids-in-csharp.what.did.I.just.read.jpg" width="400" />    
</p>

<p>Yep, looks like Mr <code>lock</code> was not much of a friend after all! not only it took us <strong><em>4 times</em></strong> longer but also <strong><em>25</em></strong> <em>Gen1</em> and <strong><em>2</em></strong> <em>Gen2</em> collections. But why? Isn’t acquiring a lock fast? Well, that depends; Acquiring a <em>non-contended</em> lock is extremely fast (<em>~20 ns</em>) but if contended, the context switch depending on the number of competing threads can quickly increase this to microseconds which in our case resulted in a noticeable performance hit.</p>

<p>Indeed, if we profile this app using <a href="https://www.jetbrains.com/profiler/">dotTrace</a> (refer to my previous blog posts for more details) we can see that we spent a whopping <strong><em>75%</em></strong> of our total execution time <em>waiting</em> in <em>Lock contention</em> (click to enlarge):</p>

<p style="text-align: center;">
    <a href="/assets/imgs/2018-10-10-generating-ids-in-csharp.profile.result.1.png" target="_blank">
    <img alt="picture of profiling result using dotTrace" src="/assets/imgs/2018-10-10-generating-ids-in-csharp.profile.result.1.png" width="700" />
    </a>
</p>

<p>Those <em>12</em> threads are barely utilising the CPU. Let’s compare that with our <code>stackalloc</code> version:</p>

<p style="text-align: center;">
    <a href="/assets/imgs/2018-10-10-generating-ids-in-csharp.profile.result.2.png" target="_blank">
    <img alt="picture of profiling result using dotTrace" src="/assets/imgs/2018-10-10-generating-ids-in-csharp.profile.result.2.png" width="700" />
    </a>
</p>

<p>See how nice and healthy those threads are? Those context switches are wasting the CPU cycles. If only we could somehow reduce it…</p>

<h3 id="8-spin-locking">8. Spin Locking</h3>

<p>Guess what? We can avoid those context switches by using a <a href="https://docs.microsoft.com/en-us/dotnet/api/system.threading.spinlock?view=netframework-4.7.2">SpinLock</a>.</p>

<blockquote>
  <p>SpinLock lets you lock without incurring the cost of a context switch, at the expense of keeping a thread spinning (uselessly busy) - <a href="http://www.albahari.com/threading/part5.aspx#_SpinLock_and_SpinWait">Albahari</a></p>
</blockquote>

<p>And this is how we are going to use it in our code:</p>

<pre><code class="language-csharp">private static readonly char[] _buffer = new char[13];
private static SpinLock _spinner = new SpinLock(false);

private static string GenerateId(long id)
{
    bool lockTaken = false;
    try
    {
        _spinner.Enter(ref lockTaken);

        char[] buffer = _buffer;
        ...
        return new string(buffer, 0, 13);
    } finally
    {
        if (lockTaken)
        {
            _spinner.Exit();
        }
    }
}
</code></pre>

<h3 id="warningimportantwarning"><code>&lt;warning&gt;</code>IMPORTANT<code>&lt;/warning&gt;</code></h3>

<p>You should almost never use a <code>SpinLock</code> as it comes with many gotchas one of which is that unlike a <code>lock</code> (aka <a href="https://docs.microsoft.com/en-us/dotnet/api/system.threading.monitor">Monitor</a>) a <code>SpinLock</code> is not <em>re-entrant</em>; So, if you cannot figure out why I have set its constructor parameter to <code>false</code> or why the <code>_spinner</code> field has not been declared as <code>readonly</code>, then it means you should not be using <code>SpinLock</code> until you fully understand how it works (I still do not!) and once you do, you should totally erase any memory of <code>SpinLock</code> from your head. Seriously, DO NOT USE IT! Nevertheless, you can have a look at <a href="https://stackoverflow.com/questions/11224130/spinlock-throwing-synchronizationlockexception">THIS</a> and <a href="https://stackoverflow.com/questions/5869825/when-should-one-use-a-spinlock-instead-of-mutex">THIS</a> to satisfy your curiosity.</p>

<p>Let’s see what difference <code>SpinLock</code> makes:</p>

<pre><code class="language-shell">- Execution time: 00:01:34.5641002
- Gen-0: 8962, Gen-1: 9, Gen-2: 0
</code></pre>

<p>It looks like this time we did much better by not having to do as many context switches as we did when we were locking; But let us have a closer look at what our process was actually doing:</p>

<p style="text-align: center;">
    <a href="/assets/imgs/2018-10-10-generating-ids-in-csharp.profile.result.3.png" target="_blank">
    <img alt="picture of profiling result using dotTrace" src="/assets/imgs/2018-10-10-generating-ids-in-csharp.profile.result.3.png" width="700" />
    </a>
</p>

<p>Even though we had no contentions, we spent only <strong><em>13.5%</em></strong> of our total execution time running and the rest spinning and wasting precious CPU time. <strong>NOT GOOD</strong>!</p>

<h3 id="the-evil-shared-state">The Evil Shared State</h3>

<p>Sharing the <code>char[]</code> across our worker threads does not seem to be a good choice after all. How can we eliminate this shared resource and at the same time avoid allocating? If only there was a way for each thread to have its own buffer to work with…</p>

<p>Well, .NET has a facility which allows us to do just that.</p>

<h3 id="9-threadstatic">9. ThreadStatic</h3>

<p>Any <em>static field</em> marked with a <a href="https://docs.microsoft.com/en-us/dotnet/api/system.threadstaticattribute">ThreadStatic</a> attribute is attached to a thread and each thread will then have its own copy of it. You can think of it as a container which holds a separate instance of our field for every thread.</p>

<blockquote>
  <p>A <em>static field</em> marked with <code>ThreadStaticAttribute</code> is not shared between threads. Each executing thread has a separate instance of the field, and independently sets and gets values for that field. If the field is accessed on a different thread, it will contain a different value. <a href="https://docs.microsoft.com/en-us/dotnet/api/system.threadstaticattribute">MSDN</a></p>
</blockquote>

<p>When using <code>ThreadStatic</code>, we are not required to specify an initial value for our field; if we do, then the initialisation occurs once the static constructor of the class is executed, therefore, the value is only set for the thread executing that constructor; When accessed in all subsequent threads, it will be initialised to its default value. So, in our case, before each thread tries to use the buffer for the first time, we need to make sure the field for that thread is initialised to a new <code>char[]</code> otherwise its value will be <code>null</code>.</p>

<p>This is what our code looks like with <code>ThreadStatic</code>:</p>

<pre><code class="language-csharp">[ThreadStatic]
private static char[] _buffer;

private static string GenerateId(long id)
{
    if (_buffer is null)
    {
        _buffer = new char[13];
    }

    char[] buffer = _buffer;
    ...
}
</code></pre>

<p>Let’s see how this one does:</p>

<pre><code class="language-shell">- Execution time: 00:01:11.0138624
- Gen-0: 8981, Gen-1: 7, Gen-2: 0
</code></pre>

<p>Okay, we are getting there! We reduced the execution time by around <strong><em>20 seconds</em></strong>. Let us see how our threads performed:</p>

<p style="text-align: center;">
    <a href="/assets/imgs/2018-10-10-generating-ids-in-csharp.profile.result.4.png" target="_blank">
    <img alt="picture of profiling result using dotTrace" src="/assets/imgs/2018-10-10-generating-ids-in-csharp.profile.result.4.png" width="700" />
    </a>
</p>

<p>Now we are talking! As you can see from the image, all our threads are showing a healthy utilisation and overall spent <strong><em>94.6%</em></strong> of their time <em>running</em>. This is what we wanted as eliminating that shared buffer also removes any contention between our worker threads enabling them to each do their work independently with no bottleneck.</p>

<p>Okay good, but can we do better? Just a little bit faster?</p>

<h3 id="10-threadlocal">10. ThreadLocal</h3>

<p>Starting from <em>.NET4.0</em>, <a href="https://docs.microsoft.com/en-us/dotnet/api/system.threading.threadlocal-1">ThreadLocal</a> provides <em>Thread Local Storage</em> (<em>TLS</em>) of data. It also improves on <code>ThreadStatic</code> by providing a strongly typed, locally scoped container to store values specific to each thread. Unlike <code>ThreadStatic</code>, you can mark both <em>instance</em> and <em>static fields</em> with it. It also allows you to use a factory method to create or initialise its value <em>lazily</em> and on the first access from each thread.</p>

<h4 id="side-note">Side note</h4>

<p>I have used this <code>ThreadLocal</code> trick many times in the past including in <a href="https://github.com/NimaAra/Easy.MessageHub">Easy.MessageHub</a> (a high-performance <em>Event Aggregator</em> which you can read about <a href="/2017/11/07/stuff-every-dotnet-app-should-log.html">HERE</a>) to avoid locking and remove contention between threads.</p>

<p>Armed with our new friend, I present to you the final version of our code:</p>

<pre><code class="language-csharp">private static readonly ThreadLocal&lt;char[]&gt; _buffer =
    new ThreadLocal&lt;char[]&gt;(() =&gt; new char[13]);

private static string GenerateId(long id)
{
    char[] buffer = _buffer.Value;

    buffer[0] = Encode_32_Chars[(int)(id &gt;&gt; 60) &amp; 31];
    buffer[1] = Encode_32_Chars[(int)(id &gt;&gt; 55) &amp; 31];
    buffer[2] = Encode_32_Chars[(int)(id &gt;&gt; 50) &amp; 31];
    buffer[3] = Encode_32_Chars[(int)(id &gt;&gt; 45) &amp; 31];
    buffer[4] = Encode_32_Chars[(int)(id &gt;&gt; 40) &amp; 31];
    buffer[5] = Encode_32_Chars[(int)(id &gt;&gt; 35) &amp; 31];
    buffer[6] = Encode_32_Chars[(int)(id &gt;&gt; 30) &amp; 31];
    buffer[7] = Encode_32_Chars[(int)(id &gt;&gt; 25) &amp; 31];
    buffer[8] = Encode_32_Chars[(int)(id &gt;&gt; 20) &amp; 31];
    buffer[9] = Encode_32_Chars[(int)(id &gt;&gt; 15) &amp; 31];
    buffer[10] = Encode_32_Chars[(int)(id &gt;&gt; 10) &amp; 31];
    buffer[11] = Encode_32_Chars[(int)(id &gt;&gt; 5) &amp; 31];
    buffer[12] = Encode_32_Chars[(int)id &amp; 31];

    return new string(buffer, 0, buffer.Length);
}
</code></pre>

<p>Let’s take it for a spin:</p>

<pre><code class="language-shell">- Execution time: 00:00:58.7741476
- Gen-0: 8980, Gen-1: 5, Gen-2: 0
</code></pre>

<p>And just like that, we managed to beat the <code>stackalloc</code> version by <strong><em>135ms</em></strong>!</p>

<p style="text-align: center;">
    <img alt="picture of a meme showing a group of people clapping" src="/assets/imgs/2018-10-10-generating-ids-in-csharp.clapping.gif" width="400" />    
</p>

<p>Here’s the profiling snapshot where once again we can see a clean and healthy utilisation across all our threads.</p>

<p style="text-align: center;">
    <a href="/assets/imgs/2018-10-10-generating-ids-in-csharp.profile.result.5.png" target="_blank">
    <img alt="picture of profiling result using dotTrace" src="/assets/imgs/2018-10-10-generating-ids-in-csharp.profile.result.5.png" width="700" />
    </a>
</p>

<h3 id="bonus-point">Bonus point</h3>

<p>Shortly after publishing this article, <a href="https://twitter.com/ben_a_adams">Ben Adams</a> the author of the original <a href="https://github.com/aspnet/Hosting/pull/385">pull request</a> for <em>Kestrel</em>’s ID generation reminded me of the new <a href="https://msdn.microsoft.com/en-us/magazine/mt814808.aspx?f=255&amp;MSPPError=-2147217396"><code>String.Create</code></a> method which allows us to avoid both stack and heap allocation for our buffer and write directly to the <code>string</code> memory.</p>

<p>You will need to be on <em>.NET Core 2.1</em> or higher and know the length of your <code>string</code> in advance. The method then allocates a <code>string</code> and gives you a <code>Span&lt;char&gt;</code> allowing you to essentially write directly into the <code>string</code>’s memory on the <em>heap</em>.</p>

<p>This is how that version would look like:</p>

<pre><code class="language-csharp">public static string GenerateId(long id) =&gt;
    string.Create(13, id, _writeToStringMemory);

private static readonly SpanAction&lt;char, long&gt; _writeToStringMemory =
    // DO NOT convert to method group otherwise will allocate
    (span, id) =&gt; WriteToStringMemory(span, id);

private static void WriteToStringMemory(Span&lt;char&gt; span, long id)
{
    span[0] = Encode_32_Chars[(int) (id &gt;&gt; 60) &amp; 31];
    span[1] = Encode_32_Chars[(int) (id &gt;&gt; 55) &amp; 31];
    span[2] = Encode_32_Chars[(int) (id &gt;&gt; 50) &amp; 31];
    span[3] = Encode_32_Chars[(int) (id &gt;&gt; 45) &amp; 31];
    span[4] = Encode_32_Chars[(int) (id &gt;&gt; 40) &amp; 31];
    span[5] = Encode_32_Chars[(int) (id &gt;&gt; 35) &amp; 31];
    span[6] = Encode_32_Chars[(int) (id &gt;&gt; 30) &amp; 31];
    span[7] = Encode_32_Chars[(int) (id &gt;&gt; 25) &amp; 31];
    span[8] = Encode_32_Chars[(int) (id &gt;&gt; 20) &amp; 31];
    span[9] = Encode_32_Chars[(int) (id &gt;&gt; 15) &amp; 31];
    span[10] = Encode_32_Chars[(int) (id &gt;&gt; 10) &amp; 31];
    span[11] = Encode_32_Chars[(int) (id &gt;&gt; 5) &amp; 31];
    span[12] = Encode_32_Chars[(int) id &amp; 31];
}
</code></pre>

<p>Ready to see the result?</p>

<pre><code class="language-shell">- Execution time: 00:01:00.1041126
- Gen-0: 8980, Gen-1: 6, Gen-2: 0
</code></pre>

<p>And here’s how the process was doing:</p>

<p style="text-align: center;">
    <a href="/assets/imgs/2018-10-10-generating-ids-in-csharp.profile.result.6.png" target="_blank">
    <img alt="picture of profiling result using dotTrace" src="/assets/imgs/2018-10-10-generating-ids-in-csharp.profile.result.6.png" width="700" />
    </a>
</p>

<p>Hmm… this is not what I expected. Could it be that we are spending a little too much time <a href="https://en.wikipedia.org/wiki/Bounds_checking">Bounds Checking</a>? Let’s give the <em>JIT</em> a little help by reversing the buffer population:</p>

<pre><code class="language-csharp">private static void WriteToStringMemory(Span&lt;char&gt; span, long id)
{
    span[12] = Encode_32_Chars[(int) id &amp; 31];
    ...
    span[0] = Encode_32_Chars[(int) (id &gt;&gt; 60) &amp; 31];
}
</code></pre>

<p>And how about now?</p>

<pre><code class="language-shell">- Execution time: 00:00:56.6800000
- Gen-0: 8980, Gen-1: 5, Gen-2: 0
</code></pre>

<p>Excellent!</p>

<h3 id="conclusion">Conclusion</h3>

<p>As we discussed before, our focus was to avoid using <code>unsafe</code> whilst trying to minimise any potential drop in the performance. The goal was not to be faster than the baseline but as it turned out we managed to shave a little bit off which is also nice.</p>

<p>I have included the final version of this method (<a href="https://github.com/NimaAra/Easy.Common/blob/master/Easy.Common/IDGenerator.cs"><code>IDGenerator</code></a>) in <a href="https://github.com/NimaAra/Easy.Common">Easy.Common</a>. You can also find the benchmark code <a href="https://github.com/NimaAra/Blog.Samples/tree/master/IDGenerator">HERE</a>.</p>

<p>I hope you enjoyed this article. Happy <code>ThreadLocal</code>ing all the things!</p>]]></content><author><name>Nima Ara</name></author><category term="C#" /><category term=".NET" /><category term="Performance" /><summary type="html"><![CDATA[Recently I needed to find an efficient algorithm for generating unique IDs in a highly concurrent and low latency component. After looking at several options I settled for the algorithm used by the Kestrel HTTP server. Kestrel generates request IDs that are stored in the TraceIdentifier property hanging off the HTTPContext.]]></summary></entry><entry><title type="html">Counting Lines of a Text File in C#, the Smart Way</title><link href="https://nimaara.com/2018/03/20/counting-lines-of-a-text-file-in-csharp.html" rel="alternate" type="text/html" title="Counting Lines of a Text File in C#, the Smart Way" /><published>2018-03-20T00:00:00+00:00</published><updated>2018-03-20T00:00:00+00:00</updated><id>https://nimaara.com/2018/03/20/counting-lines-of-a-text-file-in-csharp</id><content type="html" xml:base="https://nimaara.com/2018/03/20/counting-lines-of-a-text-file-in-csharp.html"><![CDATA[<p>Counting the lines of a text file may not seem very exciting but recently I had to deal with a number of large files (for an upcoming article which you will soon read about on this blog) and one of the operations that I had to do was to count the number of lines but at the same time ensuring that I am nice to the .NET <em>Garbage Collector</em> and don’t cause any blocking collection.</p>

<p>So in this article we are going to have a look at how you can (micro)-optimise this seemingly easy task.</p>

<h3 id="sample-data">Sample Data</h3>

<p>Before we start we need to have some sort of sample data we can use to benchmark and measure the performance of our algorithms.</p>

<p>We will be running our algorithms against 5 text files I have produced with each increasing in size starting from <strong><em>6MB</em></strong> going all the way to <strong><em>37GB</em></strong>. Every file consists of a word in each line also every smaller file is a subset of its larger brother (or sister or gender-neutral sibling).</p>

<p>Here’s the summary of our files:</p>

<pre><code class="language-shell">Name     Size(KB)     Lines
1.txt    6,516        714,584
2.txt    12,995       1,410,082
3.txt    370,180      32,245,593
4.txt    3,721,999    332,799,453
5.txt    37,089,272   3,261,066,928
</code></pre>

<h3 id="no-cheating">No Cheating</h3>

<p>When benchmarking disk <em>I/O</em> operations it is important to remember to clear the <em>Windows File Cache</em> before each run otherwise instead of reading the data directly from the file we will read it from the RAM which can skew the results dramatically; Therefore, we will use <a href="https://docs.microsoft.com/en-us/sysinternals/downloads/rammap">RAMMap</a> from the <em>Sysinternals</em> suite to clear the cache before each run.</p>

<p>Okay now that we have all of the formality out of the way let’s start counting some lines!</p>

<h3 id="the-simple-way">The Simple Way</h3>

<p>The simplest way to get the number of lines in a text file is to combine the <code>File.ReadLines</code> method with <code>System.Linq.Enumerable.Count</code>. The <code>ReadLines</code> method returns an <code>IEnumerable&lt;string&gt;</code> on which we can then call the Count method to get the result. Here’s how:</p>

<pre><code class="language-csharp">public long CountLinesLINQ(FileInfo file) =&gt;
    File.ReadLines(file.FullName).Count();
</code></pre>

<p>Let us benchmark this nice and short method and see how it does against our files.</p>

<pre><code class="language-csharp">private void Benchmark(FileInfo file)
{
    Console.WriteLine(nameof(CountLinesLINQ));

    Stopwatch sw = Stopwatch.StartNew();
    int count = CountLinesLINQ(file);
    sw.Stop();

    Console.WriteLine("{0} | {1} | Gen0 - {2} | Gen1 - {3} | Gen2 - {4}",
        file.Name,
        sw.Elapsed.ToString(),
        GC.CollectionCount(0).ToString("N0"),
        GC.CollectionCount(1).ToString("N0"),
        GC.CollectionCount(2).ToString("N0"));
}
</code></pre>

<p>All we are doing here is run the method once for each of our input files (remembering to clear the cache before each run) and output the time taken as well as the number of times <em>GC</em> kicked in across all generations.</p>

<p>On my machine with a 1TB 7200 RPM 64MB cache <em>HDD</em>, Here’s what I get:</p>

<pre><code class="language-shell">CountLinesLINQ
    1.txt | 00:00:00.5933717 | Gen0 - 4     | Gen1 - 0 | Gen2 - 0
    2.txt | 00:00:00.6265670 | Gen0 - 8     | Gen1 - 0 | Gen2 - 0
    3.txt | 00:00:03.4404236 | Gen0 - 210   | Gen1 - 0 | Gen2 - 0
    4.txt | 00:00:30.1371443 | Gen0 - 2,274 | Gen1 - 3 | Gen2 - 0
    5.txt System.OverflowException: Arithmetic operation resulted in an overflow.
</code></pre>

<p>Oops! Everything was going well until we got an <code>OverflowException</code>, why?</p>

<p>Well, the <code>System.Linq.Enumerable.Count</code> extension method on <code>File.ReadLines</code> returns an <code>Int32</code> which has a max value of <strong><em>2,147,483,647</em></strong> and as we saw earlier, there are over <strong>3 billion</strong> lines in the <em>5.txt</em> file so no surprise there.</p>

<p>Also notice the number of <em>GC_s that took place, we didn’t have any _Gen2</em> collection and that’s mainly due to the fact that we don’t need to hold on to each line read from the file so nothing survives the <em>Gen1</em> collection but even without the expensive <em>Gen2</em> collection we are still causing Gen0 and Gen1 which are both blocking operations requiring all user threads to be suspended.</p>

<p>Let’s first fix that <code>OverflowException</code>. You may have realised that we should have used the <code>System.Linq.Enumerable.LongCount</code> as opposed to <code>System.Linq.Enumerable.Count</code> which as the name suggests returns an <code>Int64</code> but why not avoid <em>LINQ</em> altogether.</p>

<h3 id="slightly-less-simple-way">Slightly Less Simple Way</h3>

<p>In the <em>LINQ</em> version, all the <code>File.ReadLine</code> does is new-up a <code>StreamReader</code> and <code>yield</code> return every line read from the file as an <code>IEnumerable&lt;string&gt;</code> which we then call <code>System.Linq.Enumerable.Count</code> on, so why don’t we do that ourselves this time avoiding the <code>OverflowException</code>:</p>

<pre><code class="language-csharp">public long CountLinesReader(FileInfo file)
{
    var lineCounter = 0L;
    using(StreamReader reader = new(file.FullName))
    {
        while(reader.ReadLine() != null)
        {
            lineCounter++;
        }
        return lineCounter;
    }
}
</code></pre>

<p>Again nothing really complicated here, we have the <code>lineCounter</code> declared as <code>Int64</code> which we then increment every time a line is read from the reader. Okay, let’s benchmark it:</p>

<pre><code class="language-shell">CountLinesReader
    1.txt | 00:00:00.5690903 | Gen0 - 4      | Gen1 - 0  | Gen2 - 0
    2.txt | 00:00:00.6243011 | Gen0 - 8      | Gen1 - 0  | Gen2 - 0
    3.txt | 00:00:03.2662413 | Gen0 - 210    | Gen1 - 0  | Gen2 - 0
    4.txt | 00:00:29.3749685 | Gen0 - 2,274  | Gen1 - 2  | Gen2 - 0
    5.txt | 00:04:28.1865611 | Gen0 - 22,663 | Gen1 - 25 | Gen2 - 2
</code></pre>

<p>The results are almost identical albeit slightly faster compared to the <em>LINQ</em> version but this time we managed to handle the <em>5.txt</em> file. So can we do better? Is there a way to count the lines without allocating anything on the <em>heap</em> so that <em>GC</em> doesn’t have to run? After all we don’t really care about the content of the lines. Hmm…</p>

<h3 id="what-if">What If…</h3>

<p>what if we go through the file one character at the time and every time we encounter an <a href="https://www.altap.cz/salamander/help/salamand/appendix_txtfiles/">end-of-line</a> character we increment our counter. Sounds pretty easy but before jumping to the implementation let’s remember that there are <strong><em>3</em></strong> different flavors of <em>end-of-line</em> characters:</p>

<ul>
  <li><strong>Carriage Return</strong> (<code>\r</code>) used in <em>Macintosh</em></li>
  <li><strong>Line Feed</strong> (<code>\n</code>) used in <em>UNIX</em></li>
  <li><strong>Carriage Return</strong> Line Feed (<code>\r\n</code>) used in <em>MS-DOS</em>, <em>Windows</em>, <em>OS/2</em></li>
</ul>

<p>Even though <code>\r\n</code> is the most used <em>end-of-line</em> character these days but we still need to make sure our algorithm can handle other flavors.</p>

<p>So what if we do this:</p>

<pre><code class="language-csharp">private const char CR = '\r';
private const char LF = '\n';
private const char NULL = (char)0;

public static long CountLinesSmarter(Stream stream)
{
    Ensure.NotNull(stream, nameof(stream));

    long lineCount = 0L;

    byte[] byteBuffer = new byte[1024 * 1024];
    char prevChar = NULL;
    bool pendingTermination = false;

    int bytesRead;
    while ((bytesRead = stream.Read(byteBuffer, 0, byteBuffer.Length)) &gt; 0)
    {
        for (int i = 0; i &lt; bytesRead; i++)
        {
            char currentChar = (char)byteBuffer[i];

            if (currentChar == NULL) { continue; }
            if (currentChar == CR || currentChar == LF)
            {
                if (prevChar == CR &amp;&amp; currentChar == LF) { continue; }

                lineCount++;
                pendingTermination = false;
            }
            else
            {
                if (!pendingTermination)
                {
                    pendingTermination = true;
                }
            }
            prevChar = currentChar;
        }
    }

    if (pendingTermination) { lineCount++; }
    return lineCount;
}
</code></pre>

<p>Take your time to study what it actually does but all it is doing is incrementing a counter whenever it sees an <em>end-of-line</em> character.</p>

<p>Now that we have a working algorithm why don’t we also sprinkle some <em>C#7</em> goodness over it! We can rewrite the body of the <code>for</code> loop as a <code>switch</code> statement with some pattern matching case blocks. You can read more about this feature <a href="https://visualstudiomagazine.com/articles/2017/02/01/pattern-matching.aspx">HERE</a>.</p>

<p>That then gives us:</p>

<pre><code class="language-csharp">public static long CountLinesSmarter(Stream stream)
{
    Ensure.NotNull(stream, nameof(stream));

    long lineCount = 0L;

    byte[] byteBuffer = new byte[1024 * 1024];
    char prevChar = NULL;
    bool pendingTermination = false;

    int bytesRead;
    while ((bytesRead = stream.Read(byteBuffer, 0, byteBuffer.Length)) &gt; 0)
    {
        for (int i = 0; i &lt; bytesRead; i++)
        {
            char currentChar = (char)byteBuffer[i];
            switch (currentChar)
            {
                case NULL:
                case LF when prevChar == CR:
                    continue;
                case CR:
                case LF when prevChar != CR:
                    lineCount++;
                    pendingTermination = false;
                    break;
                default:
                    if (!pendingTermination)
                    {
                        pendingTermination = true;
                    }
                    break;
            }
            prevChar = currentChar;
        }
    }

    if (pendingTermination) { lineCount++; }
    return lineCount;
}
</code></pre>

<h3 id="decisions-decisions">Decisions Decisions</h3>

<p>In terms of readability, both versions look pretty similar but which one should we pick? Is there any performance difference between the two versions? hmm…</p>

<h3 id="profiling-time">Profiling Time</h3>

<p>Let’s take our <a href="https://www.jetbrains.com/profiler/">dotTrace</a> profiler for a spin. We are going to use the <a href="https://blog.jetbrains.com/dotnet/2013/01/30/line-by-line-profiling-with-dottrace-performance/">line-by-line</a> profiling which will give us the most accurate timing information on each statement we execute.</p>

<p>First the version with the <code>if</code> statement:</p>

<p style="text-align: center;">
    <a href="/assets/imgs/2018-03-20-counting-lines-of-a-text-file-in-csharp.profile.result.1.png" target="_blank">
    <img alt="picture of profiling result" src="/assets/imgs/2018-03-20-counting-lines-of-a-text-file-in-csharp.profile.result.1.png" width="700" />
    </a>
</p>

<p>And now the one with the <code>switch</code> statement:</p>

<p style="text-align: center;">
    <a href="/assets/imgs/2018-03-20-counting-lines-of-a-text-file-in-csharp.profile.result.2.png" target="_blank">
    <img alt="picture of profiling result" src="/assets/imgs/2018-03-20-counting-lines-of-a-text-file-in-csharp.profile.result.2.png" width="700" />
    </a>
</p>

<p>I let you go through the result at your leisure but a simple summing up of the numbers shows us that the <code>switch</code> version executes <strong><em>15%</em></strong> fewer statements than the <code>if</code> version. So there we go, we know which version to pick.</p>

<pre><code class="language-shell">If                  Switch
---------------------------
1                   1
1                   1
1                   1
1                   1
1                   1
3,636               3,636
3,635               3,635
3,811,330,537       3,811,330,537
3,811,326,902       3,811,326,902
3,811,326,902       3,811,326,902
3,811,326,902       3,811,326,902
3,811,326,902       332,799,453
665,598,906         332,799,453
332,799,453         332,799,453
332,799,453         332,799,453
332,799,453         3,145,727,996
3,145,727,996       332,799,453
332,799,453         3,478,527,449
3,478,527,449       1
1                   1
1
--------------------------------------
27,677,697,586      23,533,571,231
</code></pre>

<h3 id="refactor">Refactor</h3>

<p>Our <code>Switch</code> algorithm doesn’t look too bad but the fact that we have created a <em>state-machine</em> looks less satisfying to me so why don’t we refactor it slightly and see if we can reduce the number of comparisons we make.</p>

<pre><code class="language-csharp">public static long CountLinesSmarter(Stream stream)
{
    Ensure.NotNull(stream, nameof(stream));

    long lineCount = 0L;

    byte[] byteBuffer = new byte[1024 * 1024];
    char detectedEOL = NULL;
    char currentChar = NULL;

    int bytesRead;
    while ((bytesRead = stream.Read(byteBuffer, 0, byteBuffer.Length)) &gt; 0)
    {
        for (int i = 0; i &lt; bytesRead; i++)
        {
            currentChar = (char)byteBuffer[i];

            if (detectedEOL != NULL)
            {
                if (currentChar == detectedEOL)
                {
                    lineCount++;
                }
            }
            else if (currentChar == LF || currentChar == CR)
            {
                detectedEOL = currentChar;
                lineCount++;
            }
        }
    }

    // We had a NON-EOL character at the end without a new line
    if (currentChar != LF &amp;&amp; currentChar != CR &amp;&amp; currentChar != NULL)
    {
        lineCount++;
    }
    return lineCount;
}
</code></pre>

<p>This time we first try detecting the <em>end-of-line</em> character and then once we have it we can just check for that character and increment our counter without having to keep track of the previous character.</p>

<p>Let us see what the profiler says this time:</p>

<p style="text-align: center;">
    <a href="/assets/imgs/2018-03-20-counting-lines-of-a-text-file-in-csharp.profile.result.3.png" target="_blank">
    <img alt="picture of profiling result" src="/assets/imgs/2018-03-20-counting-lines-of-a-text-file-in-csharp.profile.result.3.png" width="700" />
    </a>
</p>

<p>I like the smell of less statements to execute in a <code>for</code> loop!</p>

<h3 id="micro-micro-optimisation">Micro-Micro-Optimisation</h3>

<p>By looking at the profiling sessions above you may jump to the conclusion that since we are spending too much time in the <code>for</code> loop why not <em>unroll</em> it.</p>

<p>For those unfamiliar with the concept of <a href="https://en.wikipedia.org/wiki/Loop_unrolling">Loop Unrolling</a>, it is an optimisation technique with the goal of reducing the overhead of a loop by executing fewer iterations but doing more work per iteration. So if we were to unroll the above implementation we can come up with something like:</p>

<pre><code class="language-csharp">public static long CountLinesMaybe(Stream stream)
{
    Ensure.NotNull(stream, nameof(stream));

    long lineCount = 0L;

    byte[] byteBuffer = new byte[1024 * 1024];
    const int BytesAtTheTime = 4;
    char detectedEOL = NULL;
    char currentChar = NULL;

    int bytesRead;
    while ((bytesRead = stream.Read(byteBuffer, 0, byteBuffer.Length)) &gt; 0)
    {
        int i = 0;
        for (; i &lt;= bytesRead - BytesAtTheTime; i += BytesAtTheTime)
        {
            currentChar = (char)byteBuffer[i];

            if (detectedEOL != NULL)
            {
                if (currentChar == detectedEOL) { lineCount++; }

                currentChar = (char)byteBuffer[i + 1];
                if (currentChar == detectedEOL) { lineCount++; }

                currentChar = (char)byteBuffer[i + 2];
                if (currentChar == detectedEOL) { lineCount++; }

                currentChar = (char)byteBuffer[i + 3];
                if (currentChar == detectedEOL) { lineCount++; }
            }
            else
            {
                if (currentChar == LF || currentChar == CR)
                {
                    detectedEOL = currentChar;
                    lineCount++;
                }
                i -= BytesAtTheTime - 1;
            }
        }

        for (; i &lt; bytesRead; i++)
        {
            currentChar = (char)byteBuffer[i];

            if (detectedEOL != NULL)
            {
                if (currentChar == detectedEOL) { lineCount++; }
            }
            else
            {
                if (currentChar == LF || currentChar == CR)
                {
                    detectedEOL = currentChar;
                    lineCount++;
                }
            }
        }
    }

    if (currentChar != LF &amp;&amp; currentChar != CR &amp;&amp; currentChar != NULL)
    {
        lineCount++;
    }
    return lineCount;
}
</code></pre>

<p>This abomination would certainly result in a better performance if we were not <em>I/O</em> bound but in our case any performance gained by unrolling the loop is dwarfed by the time taken to read the bytes from the disk. Therefore, we are going to stick to the non-unrolled version.</p>

<p>What we have come up with so far is by no means anywhere close to the most optimal solution specially if you are prepared to use <a href="https://jeffreystedfast.blogspot.co.uk/2013/09/optimization-tips-tricks-used-by.html">unsafe combined with byte-masking</a> but it is pretty much as far as I am prepared to go with optimising the algorithm for now as my main goal was to eliminate allocation.</p>

<h3 id="moment-of-truth">Moment of Truth</h3>

<p>Now that we have our candidate algorithm let’s run the benchmarks:</p>

<pre><code class="language-shell">CountLinesSmart
    1.txt | 00:00:00.5498381 | Gen0 - 0 | Gen1 - 0 | Gen2 - 0
    2.txt | 00:00:00.5834317 | Gen0 - 0 | Gen1 - 0 | Gen2 - 0
    3.txt | 00:00:03.0332798 | Gen0 - 0 | Gen1 - 0 | Gen2 - 0
    4.txt | 00:00:25.3517502 | Gen0 - 0 | Gen1 - 0 | Gen2 - 0
    5.txt | 00:04:13.1127603 | Gen0 - 0 | Gen1 - 0 | Gen2 - 0
</code></pre>

<p>Voila! Not only we improved the overall execution time but also we managed to be nice to the <em>GC</em> by not causing any collections.</p>

<p style="text-align: center;">
    <img alt="picture of a meme showing minions celebrating" src="/assets/imgs/2018-03-20-counting-lines-of-a-text-file-in-csharp.celebrating.gif" width="400" />    
</p>

<h3 id="how-does-it-compare-to-wc--l">How does it compare to <code>wc -l</code>?</h3>

<p>In case you are wondering how fast you can count these lines in <em>Linux</em> (using time <code>wc -l &lt;file-name&gt;</code>), here are some numbers:</p>

<pre><code class="language-shell">time wc -l &lt;file-name&gt;
    1.txt | real 0m00.680s | user 0m0.000s | sys 0m0.031s
    2.txt | real 0m00.719s | user 0m0.015s | sys 0m0.061s
    3.txt | real 0m03.218s | user 0m0.015s | sys 0m0.046s
    4.txt | real 0m25.966s | user 0m0.015s | sys 0m0.046s
    5.txt | real 4m13.669s | user 0m0.015s | sys 0m0.000s
</code></pre>

<p>And finally, I have added this implementation to <a href="https://www.nuget.org/packages/Easy.Common/">Easy.Common</a>. You can use it by calling the <code>CountLines</code> extension method on any <code>Stream</code>. The source is <a href="https://github.com/NimaAra/Easy.Common/blob/768133ecf2257e0750a3d8998cb729d01c957927/Easy.Common/Extensions/StreamExtensions.cs#L23">HERE</a> and unit tests are <a href="https://github.com/NimaAra/Easy.Common/blob/master/Easy.Common.Tests.Unit/StreamExtensions/CountingLinesTests.cs">HERE</a>.</p>]]></content><author><name>Nima Ara</name></author><category term="C#" /><category term=".NET" /><summary type="html"><![CDATA[Counting the lines of a text file may not seem very exciting but recently I had to deal with a number of large files (for an upcoming article which you will soon read about on this blog) and one of the operations that I had to do was to count the number of lines but at the same time ensuring that I am nice to the .NET Garbage Collector and don’t cause any blocking collection.]]></summary></entry><entry><title type="html">Stuff Every .NET App Should be Logging at Startup</title><link href="https://nimaara.com/2017/11/07/stuff-every-dotnet-app-should-log.html" rel="alternate" type="text/html" title="Stuff Every .NET App Should be Logging at Startup" /><published>2017-11-07T00:00:00+00:00</published><updated>2017-11-07T00:00:00+00:00</updated><id>https://nimaara.com/2017/11/07/stuff-every-dotnet-app-should-log</id><content type="html" xml:base="https://nimaara.com/2017/11/07/stuff-every-dotnet-app-should-log.html"><![CDATA[<p>In my opinion, a large part of being a good developer is ensuring the applications you build are maintainable and easy to debug both during development and after deployment. This becomes even more important if you work in the enterprise with plethora of complicated interdependent systems deployed regularly and the army of people constantly making changes to it; In such environments tasks such as maintaining, troubleshooting and monitoring the system is of tremendous value.</p>

<p>Unless all you build are <em>HelloWorld</em> applications which never get deployed anywhere you almost certainly have come across cases where either you or your support team have had to figure out:</p>

<ul>
  <li>What is causing that <em>OutOfMemory</em> exception?</li>
  <li>Why is there such a performance degradation after the last release?</li>
  <li>Why is the <em>DLL</em> I have referenced not doing what it is supposed to?</li>
  <li>What system is my app running in?</li>
  <li>What arguments the app has started with?</li>
  <li>What version of <em>JSON.NET</em> is the app using?</li>
  <li>…</li>
</ul>

<p>Over the years I have found myself and my colleagues spending precious time trying to deal with finding the answers to such questions over and over again particularly at times where there are production issues and downtime could cost the business a lot of money. So today I have decided to share with you a helper class I built a while back which can help answer such questions more proactively. The idea is to log the report generated by this class at the start of your application and if required on demand or at certain intervals.</p>

<p>The class is very simple to use and currently supports <em>Windows</em>, <em>Linux</em> and <em>OSX</em>:</p>

<pre><code class="language-csharp">DiagnosticReport report = DiagnosticReport.Generate();
Console.WriteLine(report.ToString());
</code></pre>

<p>Which then generates a report that looks like:</p>

<pre><code class="language-shell">/
|Diagnostic Report generated at: 13-11-2017 18:14:41.174 (+00:00) in: 849.7042 milliseconds.
|
|System|..................................................................
|
|    . OS - Name         : Microsoft Windows 10.0.14393
|    . OS - Type         : Windows (Server)
|    . OS - 64Bit        : True
|    . CLR Runtime       : .NET Framework 4.7.2110.0
|    . Machine Name      : MyServer.
|    . FQDN              : MyServer
|    . User              : MyServer\admin
|    . CPU               : Intel(R) Xeon(R) CPU E5-2673 v3 @ 2.40GHz
|    . CPU Core Count    : 2
|    . Installed RAM     : 16GB
|    . System Directory  : C:\Windows\system32
|    . Current Directory : C:\Users\admin\SampleApp
|    . Runtime Directory : C:\Windows\Microsoft.NET\Framework64\v4.0.30319\
|    . Uptime            : 20Day 12Hour 00Min 08Sec
|
|Process|......................................................................................................
|
|    . Id                  : 348
|    . Name                : LINQPad.UserQuery
|    . Started             : 13-11-2017 18:13:18.161 (+00:00)
|    . Loaded In           : 00:01:23.1225614
|    . Interactive         : True
|    . Optimized           : True
|    . 64Bit Process       : True
|    . Server GC           : True
|    . Large Address Aware : True
|    . WorkingSet          : 42MB
|    . Threads             : 88
|    . IO Threads          : 24 &lt;-&gt; 1,000
|    . Worker Threads      : 24 &lt;-&gt; 32,767
|    . File Version        : 1.0.0.0
|    . Product Version     : 1.0.0.0
|    . Language            : Language Neutral
|    . Copyright           : Copyright © Nima Ara 2017
|    . Original File Name  : LINQPad.UserQuery.exe
|    . File Name           : C:\Users\admin\AppData\Local\LINQPad\ProcessServer5AnyCPUB\LINQPad.UserQuery.exe
|    . Module Name         : LINQPad.UserQuery.exe
|    . Module File Name    : C:\Users\admin\AppData\Local\LINQPad\ProcessServer5AnyCPUB\LINQPad.UserQuery.exe
|    . Product Name        : A Sample Query
|    . CommandLine         : C:\Users\admin\AppData\Local\LINQPad\ProcessServer5AnyCPUB\LINQPad.UserQuery.exe
|                            C:/Program Files/LINQPad5/LINQPad.EXE
|                            C:/Program Files/LINQPad5/
|                            C:/Program Files/LINQPad5/LINQPad.config
|                            LINQPad.ivddgmnj.Server.2
|                            ivddgmnj
|                            4328
|                            True
|
|Drives|.......................................................................................
|
|     -----------------------------------------------------------------------------------------
|    | Name | Type      | Format | Label             | Capacity(GB) | Free(GB) | Available(GB) |
|    |------|-----------|--------|-------------------|--------------|----------|---------------|
|    | A:\  | Removable |        |                   | 0            | 0        | 0             |
|    | C:\  | Fixed     | NTFS   |                   | 127          | 108      | 108           |
|    | D:\  | Fixed     | NTFS   | Temporary Storage | 14           | 13       | 13            |
|    | E:\  | CDRom     |        |                   | 0            | 0        | 0             |
|     -----------------------------------------------------------------------------------------
|
|Assemblies|........................................................................................................................................
|
|    001| Name      : mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
|       . GAC       : True
|       . 64Bit     : True
|       . Optimized : True
|       . Framework : .NET 2, 3 or 3.5
|       . Location  : C:\Windows\Microsoft.NET\Framework64\v4.0.30319\mscorlib.dll
|       . CodeBase  : file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/mscorlib.dll
|
|    002| Name      : System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
|       . GAC       : True
|       . 64Bit     : True
|       . Optimized : True
|       . Framework : .NET 2, 3 or 3.5
|       . Location  : C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll
|       . CodeBase  : file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System/v4.0_4.0.0.0__b77a5c561934e089/System.dll
|
|    003| Name      : System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
|       . GAC       : True
|       . 64Bit     : True
|       . Optimized : True
|       . Framework : .NET 2, 3 or 3.5
|       . Location  : C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Drawing\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Drawing.dll
|       . CodeBase  : file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Drawing/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
|
|    004| Name      : System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
|       . GAC       : True
|       . 64Bit     : True
|       . Optimized : True
|       . Framework : .NET 2, 3 or 3.5
|       . Location  : C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Core\v4.0_4.0.0.0__b77a5c561934e089\System.Core.dll
|       . CodeBase  : file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Core/v4.0_4.0.0.0__b77a5c561934e089/System.Core.dll
|
|    005| Name      : System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
|       . GAC       : True
|       . 64Bit     : True
|       . Optimized : True
|       . Framework : .NET 2, 3 or 3.5
|       . Location  : C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Windows.Forms\v4.0_4.0.0.0__b77a5c561934e089\System.Windows.Forms.dll
|       . CodeBase  : file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms/v4.0_4.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
|
|    006| Name      : System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
|       . GAC       : True
|       . 64Bit     : True
|       . Optimized : True
|       . Framework : .NET 2, 3 or 3.5
|       . Location  : C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Configuration\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Configuration.dll
|       . CodeBase  : file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Configuration/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll
|
|    007| Name      : System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
|       . GAC       : True
|       . 64Bit     : True
|       . Optimized : True
|       . Framework : .NET 2, 3 or 3.5
|       . Location  : C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Xml\v4.0_4.0.0.0__b77a5c561934e089\System.Xml.dll
|       . CodeBase  : file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Xml/v4.0_4.0.0.0__b77a5c561934e089/System.Xml.dll
|
|    008| Name      : System.Xml.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
|       . GAC       : True
|       . 64Bit     : True
|       . Optimized : True
|       . Framework : .NET 2, 3 or 3.5
|       . Location  : C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Xml.Linq\v4.0_4.0.0.0__b77a5c561934e089\System.Xml.Linq.dll
|       . CodeBase  : file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Xml.Linq/v4.0_4.0.0.0__b77a5c561934e089/System.Xml.Linq.dll
|
|    009| Name      : System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
|       . GAC       : True
|       . 64Bit     : True
|       . Optimized : True
|       . Framework : .NET 2, 3 or 3.5
|       . Location  : C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Data.Linq\v4.0_4.0.0.0__b77a5c561934e089\System.Data.Linq.dll
|       . CodeBase  : file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Data.Linq/v4.0_4.0.0.0__b77a5c561934e089/System.Data.Linq.dll
|
|    010| Name      : System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
|       . GAC       : True
|       . 64Bit     : True
|       . Optimized : True
|       . Framework : .NET 2, 3 or 3.5
|       . Location  : C:\Windows\Microsoft.Net\assembly\GAC_64\System.Data\v4.0_4.0.0.0__b77a5c561934e089\System.Data.dll
|       . CodeBase  : file:///C:/Windows/Microsoft.Net/assembly/GAC_64/System.Data/v4.0_4.0.0.0__b77a5c561934e089/System.Data.dll
|
|    011| Name      : Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
|       . GAC       : True
|       . 64Bit     : True
|       . Optimized : True
|       . Framework : .NET 2, 3 or 3.5
|       . Location  : C:\Windows\Microsoft.Net\assembly\GAC_MSIL\Microsoft.CSharp\v4.0_4.0.0.0__b03f5f7f11d50a3a\Microsoft.CSharp.dll
|       . CodeBase  : file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/Microsoft.CSharp/v4.0_4.0.0.0__b03f5f7f11d50a3a/Microsoft.CSharp.dll
|
|    012| Name      : LINQPad, Version=1.0.0.0, Culture=neutral, PublicKeyToken=21353812cd2a2db5
|       . GAC       : False
|       . 64Bit     : True
|       . Optimized : False
|       . Framework : .NETFramework,Version=v4.5.2
|       . Location  : C:\Program Files\LINQPad5\LINQPad.exe
|       . CodeBase  : file:///C:/Program Files/LINQPad5/LINQPad.EXE
|
|    013| Name      : LINQPad.Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=21353812cd2a2db5
|       . GAC       : False
|       . 64Bit     : True
|       . Optimized : False
|       . Framework : .NETFramework,Version=v4.5.2
|       . Location  :
|       . CodeBase  : file:///C:/Program Files/LINQPad5/LINQPad.exe
|
|    014| Name      : query_viulpd, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|       . GAC       : False
|       . 64Bit     : True
|       . Optimized : False
|       . Framework : .NET 2, 3 or 3.5
|       . Location  : C:\Users\admin\AppData\Local\Temp\2\LINQPad5\_tqnmweww\query_viulpd.dll
|       . CodeBase  : file:///C:/Users/admin/AppData/Local/Temp/2/LINQPad5/_tqnmweww/query_viulpd.dll
|
|    015| Name      : Easy.Common, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|       . GAC       : False
|       . 64Bit     : True
|       . Optimized : True
|       . Framework : .NETFramework,Version=v4.5
|       . Location  : C:\Users\admin\AppData\Local\Temp\2\LINQPad5\_tqnmweww\shadow_ebuhxn\easy.common.dll
|       . CodeBase  : file:///C:/Users/admin/AppData/Local/Temp/2/LINQPad5/_tqnmweww/shadow_ebuhxn/easy.common.dll
|
|    016| Name      : System.Runtime.InteropServices.RuntimeInformation, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
|       . GAC       : False
|       . 64Bit     : True
|       . Optimized : True
|       . Framework : .NET 2, 3 or 3.5
|       . Location  : C:\Users\admin\AppData\Local\Temp\2\LINQPad5\netstandard2\System.Runtime.InteropServices.RuntimeInformation.dll
|       . CodeBase  : file:///C:/Users/admin/AppData/Local/Temp/2/LINQPad5/netstandard2/System.Runtime.InteropServices.RuntimeInformation.dll
|
|Environment-Variables|..................................................................................................................................................................................................
|
|    001. ALLUSERSPROFILE           : C:\ProgramData
|    002. APPDATA                   : C:\Users\admin\AppData\Roaming
|    003. CLIENTNAME                : SomeClient
|    004. CommonProgramFiles        : C:\Program Files\Common Files
|    005. CommonProgramFiles(x86)   : C:\Program Files (x86)\Common Files
|    006. CommonProgramW6432        : C:\Program Files\Common Files
|    007. COMPUTERNAME              : MyServer
|    008. ComSpec                   : C:\Windows\system32\cmd.exe
|    009. HOMEDRIVE                 : C:
|    010. HOMEPATH                  : \Users\admin
|    011. LOCALAPPDATA              : C:\Users\admin\AppData\Local
|    012. LOGONSERVER               : \\MyServer
|    013. NUMBER_OF_PROCESSORS      : 2
|    014. OS                        : Windows_NT
|    015. Path                      : C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\LINQPad5;C:\Users\admin\AppData\Local\Microsoft\WindowsApps;
|    016. PATHEXT                   : .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
|    017. PROCESSOR_ARCHITECTURE    : AMD64
|    018. PROCESSOR_IDENTIFIER      : Intel64 Family 6 Model 63 Stepping 2, GenuineIntel
|    019. PROCESSOR_LEVEL           : 6
|    020. PROCESSOR_REVISION        : 3f02
|    021. ProgramData               : C:\ProgramData
|    022. ProgramFiles              : C:\Program Files
|    023. ProgramFiles(x86)         : C:\Program Files (x86)
|    024. ProgramW6432              : C:\Program Files
|    025. PSModulePath              : C:\Program Files\WindowsPowerShell\Modules;C:\Windows\system32\WindowsPowerShell\v1.0\Modules;C:\Program Files\Microsoft Monitoring Agent\Agent\PowerShell\
|    026. PUBLIC                    : C:\Users\Public
|    027. SESSIONNAME               : RDP-Tcp#58
|    028. SystemDrive               : C:
|    029. SystemRoot                : C:\Windows
|    030. TEMP                      : C:\Users\admin\AppData\Local\Temp\2
|    031. TMP                       : C:\Users\admin\AppData\Local\Temp\2
|    032. USERDOMAIN                : MyServer
|    033. USERDOMAIN_ROAMINGPROFILE : MyServer
|    034. USERNAME                  : admin
|    035. USERPROFILE               : C:\Users\admin
|    036. windir                    : C:\Windows
|
|Networks|.....................................................................
|
|    . Windows IP Configuration
|      -------------------------
|      | Host               : MyServer
|      | Domain             :
|      | DHCP Scope         :
|      | Node Type          : Hybrid
|      | Is WINS Proxy      : False
|
|    . Microsoft Hyper-V Network Adapter #2
|      -------------------------------------
|      | Name               : Ethernet 2
|      | MAC                : 00:0D:3B:A3:D6:AC
|      | Type               : Ethernet
|      | Status             : Up
|      | Supports Multicast : True
|      | Is Receive Only    : False
|      | Speed              : 10,000 Mbit/s
|      | IP Addresses       : [1.2.3.4]
|
|    . Software Loopback Interface 1
|      ------------------------------
|      | Name               : Loopback Pseudo-Interface 1
|      | MAC                :
|      | Type               : Loopback
|      | Status             : Up
|      | Supports Multicast : True
|      | Is Receive Only    : False
|      | Speed              : 1,073 Mbit/s
|
|    . Microsoft ISATAP Adapter #2
|      ----------------------------
|      | Name               : isatap.MyServer.a8.internal.cloudapp.net
|      | MAC                : 00:00:00:00:00:00:00:E0
|      | Type               : Tunnel
|      | Status             : Down
|      | Supports Multicast : False
|      | Is Receive Only    : False
|      | Speed              : 0 Mbit/s
|
|    . Teredo Tunneling Pseudo-Interface
|      ----------------------------------
|      | Name               : Teredo Tunneling Pseudo-Interface
|      | MAC                : 00:00:00:00:00:00:00:E0
|      | Type               : Tunnel
|      | Status             : Up
|      | Supports Multicast : False
|      | Is Receive Only    : False
|      | Speed              : 0 Mbit/s
|
\
</code></pre>

<h3 id="what-does-it-produce">What does it produce?</h3>

<p>The above report was generated in about <em>849</em> milliseconds on its first run and contains various information that are relevant to your application. This information has been categorised into six main sections which you can find in more detail at the bottom of this article but here’s an overview:</p>

<ol>
  <li>System</li>
  <li>Process</li>
  <li>Drives</li>
  <li>Assemblies</li>
  <li>Environment Variables</li>
  <li>Networking</li>
</ol>

<p>If you are not interested in generating the full report, you have the option to only generate a specific section:</p>

<pre><code class="language-csharp">DiagnosticReport drivesReport = DiagnosticReport.Generate(DiagnosticReportType.Drives);
</code></pre>

<p>or combine multiple sections:</p>

<pre><code class="language-csharp">DiagnosticReport drivesAndNetworkingReport = DiagnosticReport.Generate(
    DiagnosticReportType.Drives | DiagnosticReportType.Networking);
</code></pre>

<p>or only exclude a specific section:</p>

<pre><code class="language-csharp">DiagnosticReport partialReport = DiagnosticReport.Generate(
       DiagnosticReportType.Full &amp;~ DiagnosticReportType.EnvironmentVariables);
</code></pre>

<p>It is as simple as that!</p>

<h3 id="where-do-i-find-it">Where do I find it?</h3>

<p>You can see the source of the class in <a href="https://github.com/NimaAra/Easy.Common/blob/master/Easy.Common/DiagnosticReport/DiagnosticReport.cs">DiagnosticReport</a> and can start generating your own reports by referencing the <a href="https://www.nuget.org/packages/Easy.Common/">Easy.Common NuGet</a> package from your .NET or .NET Core app.</p>

<h3 id="what-information-is-covered">What information is covered?</h3>

<h4 id="system">System</h4>

<p>Contains information relating to the system under which the application is running:</p>

<ul>
  <li>Name of the operating system</li>
  <li>Type of the operating system e.g <em>Windows</em>, <em>Linux</em> or <em>OSX</em></li>
  <li>Flag indicating whether the operating system is 64-bit capable</li>
  <li>Version of the <em>CLR</em></li>
  <li>machine name</li>
  <li>Fully Qualified Domain Name (<em>FQDN</em>)</li>
  <li>User under which the process is running</li>
  <li>Processor name</li>
  <li>Number of processor cores including <em>HyperThreading</em></li>
  <li>Number of installed <em>RAM</em></li>
  <li>Location of the <em>System</em> directory</li>
  <li>Location of the current directory the application is running</li>
  <li>Location where the <em>CLR</em> is installed</li>
  <li>Duration the system has been up</li>
</ul>

<h4 id="process">Process</h4>

<p>Contains information relating to the current process:</p>

<ul>
  <li>Process ID (<em>PID</em>)</li>
  <li>Process name</li>
  <li>Time at which the process was started</li>
  <li>Time taken for the process to be loaded</li>
  <li>Flag indicating whether the process is running in <em>User Interactive</em> mode (This will be <em>false</em> for a <em>Windows Service</em> or a service such as <em>IIS</em> that runs without a <em>UI</em>)</li>
  <li>Flag indicating whether the application has been compiled in Release mode</li>
  <li>Flag indicating whether the process is 64-bit</li>
  <li>Flag indicating whether the <em>GC</em> mode is <em>Server</em></li>
  <li>Flag indicating whether the process is Large Address Aware</li>
  <li>Current value of <em>Working Set</em> memory (RAM) in use by the process. This value includes both <em>Shared</em> and <em>Private</em> memory</li>
  <li>Number of threads owned by the process</li>
  <li>Minimum and maximum number of <em>IO Completion Port</em> threads</li>
  <li>Minimum and maximum number of <em>Thread Pool Worker</em> threads</li>
  <li>File version of the process</li>
  <li>Version of the product the process is distributed with</li>
  <li>Default language for the process</li>
  <li>Copyright notices that apply to the process</li>
  <li>Name of the file the process was created as</li>
  <li>File name representing the process</li>
  <li>Name of the process module</li>
  <li>File representing the process module</li>
  <li>Name of the product the process is distributed with</li>
  <li><em>CommandLine</em> including any arguments passed into the process</li>
</ul>

<h4 id="drives">Drives</h4>

<p>Contains information relating to the system drives including <em>fixed</em> as well as <em>removable</em> ones:</p>

<ul>
  <li>Name of the drive</li>
  <li>Type of the drive e.g. <em>Fixed</em>, <em>CDRom</em> etc.</li>
  <li>Format of the drive e.g. <em>NTFS</em></li>
  <li>Label of the drive</li>
  <li>Capacity of the drive</li>
  <li>Total amount of free space available on the drive (not just what is available to the current user)</li>
  <li>Amount of free space available on the drive (this value takes into account disk quotas)</li>
</ul>

<h4 id="assemblies">Assemblies</h4>

<p>Contains information relating to the assemblies which have been loaded by the process:</p>

<ul>
  <li>Full name of the assembly</li>
  <li>Flag indicating whether the assembly has been loaded from the <em>GAC</em></li>
  <li>Flag indicating whether the assembly is 64-bit</li>
  <li>Flag indicating whether the assembly has been compiled in <em>Release</em> mode</li>
  <li>framework for which the assembly has been compiled</li>
  <li>Location from which the assembly has been loaded from</li>
  <li>Path to the location where the assembly was found. (If the assembly was downloaded from the web, this value may start with <em>HTTP</em>)</li>
</ul>

<h4 id="environment-variables">Environment Variables</h4>

<p>Contains the name and value of the environment variables available to the process.</p>

<h4 id="networking">Networking</h4>

<p>Contains information relating to the networking infrastructure available to the process:</p>

<ul>
  <li>
    <p>Windows IP Configuration including:</p>

    <ul>
      <li>Host name</li>
      <li><em>DNS</em> details</li>
    </ul>
  </li>
  <li>
    <p>Adapter information:</p>

    <ul>
      <li>Name &amp; description</li>
      <li>Status</li>
      <li>Speed</li>
      <li>Physical address (<em>MAC</em>)</li>
      <li><em>IP</em> addresses</li>
      <li><em>DHCP</em> details</li>
    </ul>
  </li>
</ul>

<p>Enjoy!</p>]]></content><author><name>Nima Ara</name></author><category term="C#" /><category term=".NET" /><summary type="html"><![CDATA[In my opinion, a large part of being a good developer is ensuring the applications you build are maintainable and easy to debug both during development and after deployment. This becomes even more important if you work in the enterprise with plethora of complicated interdependent systems deployed regularly and the army of people constantly making changes to it; In such environments tasks such as maintaining, troubleshooting and monitoring the system is of tremendous value.]]></summary></entry><entry><title type="html">Practical Parallelization in C# with MapReduce, ProducerConsumer and ActorModel</title><link href="https://nimaara.com/2017/06/01/practical-parallelization-in-csharp.html" rel="alternate" type="text/html" title="Practical Parallelization in C# with MapReduce, ProducerConsumer and ActorModel" /><published>2017-06-01T00:00:00+00:00</published><updated>2017-06-01T00:00:00+00:00</updated><id>https://nimaara.com/2017/06/01/practical-parallelization-in-csharp</id><content type="html" xml:base="https://nimaara.com/2017/06/01/practical-parallelization-in-csharp.html"><![CDATA[<p>The barrier of entry into multi-threading in .NET is relatively low as both <em>Parallel Computing</em> (making programs run faster) and <em>Concurrent Programming</em> (making programs more responsive) have been greatly simplified since the introduction of <a href="https://msdn.microsoft.com/en-us/library/dd537609(v=vs.110).aspx">TPL</a> and its friends (<a href="https://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel(v=vs.110).aspx">Parallel</a> and <a href="https://msdn.microsoft.com/en-us/library/dd460688(v=vs.110).aspx">PLINQ</a>) in <em>.NET4.0</em>.</p>

<p>Despite this low barrier of entry, many developers fail to achieve the best performance out of their multi-threaded solutions. This is sometimes due to frequent or unnecessary <em>locking/synchronization</em> or at other times due to incorrectly partitioning their data or using an inappropriate pattern.</p>

<p>In this article we are going to look at how we can squeeze the best performance out of an easily parallelizable problem by rewriting the same basic implementation using some of the most widely used multi-threading tools available in .NET. We will be covering different .NET technologies such as <a href="https://msdn.microsoft.com/en-us/library/dd460688(v=vs.110).aspx">PLINQ</a>, <a href="https://msdn.microsoft.com/en-us/library/dd997371(v=vs.110).aspx">BlockingCollection</a>, <a href="https://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel(v=vs.110).aspx">Parallel</a> class as well as <a href="https://msdn.microsoft.com/en-us/library/hh228603(v=vs.110).aspx">TPL Dataflow</a> in conjunction with patterns such as <a href="https://en.wikipedia.org/wiki/MapReduce">MapReduce</a>, <a href="https://en.wikipedia.org/wiki/Actor_model">ActorModel</a> as well as <a href="https://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem">ProducerConsumer</a> while trying to achieve <em>optimal parallelization</em> and <em>minimize the cost of synchronization</em> between the threads.</p>

<h3 id="the-scenario">The Scenario</h3>

<p>The example scenario we will be solving is to count the number of words in a text file which is the <a href="http://www.imdb.com/">IMDB</a> database for movie plots downloaded from <a href="ftp://ftp.fu-berlin.de/pub/misc/movies/database/frozendata/plot.list.gz">HERE</a>. The file (as of today) is <strong>432MB</strong> with <strong>8,151,603</strong> lines consisting of <strong>69,275,414</strong> words and <strong>432,045,742</strong> characters. So our job is to figure out what the top n words and their respective counts are in this file. The overall work required to calculate the result can be summarized as:</p>

<ol>
  <li>Read every line in the file</li>
  <li>Convert each line into words</li>
  <li>Exclude invalid words e.g. <em>“a”</em>, <em>“and”</em>, <em>“with”</em> etc.</li>
  <li>Count and track the occurrence of each word</li>
  <li>Sort the words from the highest count to the lowest</li>
  <li>Return the top n words e.g. <em>100</em></li>
</ol>

<p>Our final result should display something like this:</p>

<pre><code class="language-shell">life   128,714
new    119,587
man    96,257
time   89,828
world  88,863
young  87,279
film   82,800
love   80,002
family 75,530
home   74,265
story  73,211
old    62,433
day    62,319
finds  61,394
father 60,055
...
</code></pre>

<h3 id="approach">Approach</h3>

<p>We will be measuring the following for each of the patterns we implement:</p>

<ol>
  <li>The total execution time of the program</li>
  <li>The count of times <em>Garbage Collection</em> occurs across different generations i.e. <em>0</em>, <em>1</em> and <em>2</em></li>
  <li>The process’s <em>Peak Working Set</em> memory which is the maximum amount of physical memory (RAM) used by the process.</li>
</ol>

<p>In addition to the above, for each implementation I will also include a <em>Time-Line</em> profiling snapshot of the process using the awesome <a href="https://www.jetbrains.com/profiler/">dotTrace</a> profiler developed by <a href="https://www.jetbrains.com/">JetBrains</a> (available as a 10 day trial). This allows us to analyze the context under which our thread(s) were executing and the level of concurrency and CPU utilization we achieved for that implementation.</p>

<p>You can use other tools and profilers such as the <a href="https://msdn.microsoft.com/en-us/library/ms182372.aspx">Visual Studio Performance Profiling</a>, <a href="http://www.red-gate.com/products/dotnet-development/ants-performance-profiler">ANTS Performance Profiler</a> by <a href="http://www.red-gate.com/">RedGate</a> or the <a href="https://msdn.microsoft.com/en-us/library/dd537632.aspx">Concurrency Visualizer</a> extension for <em>Visual Studio</em>. There is also a free new comer built using C# and WPF called <a href="http://www.getcodetrack.com/">CodeTrack</a>; It looks quite promising and I highly suggest taking a look and having a play.</p>

<p>In order to increase our application’s throughput, we will set the <em>GC</em> mode to <a href="https://msdn.microsoft.com/en-us/library/ms229357(v=vs.110).aspx">Server</a>. A <em>Server GC</em> mode results in less frequent <em>GC</em> across all generations but it also means that each CPU core will now have its own heap as well as a dedicated thread responsible for collecting every dead references in that heap so on my 24-core server we will have 24 threads dedicated to GC but that is not all, thanks to the <a href="https://blogs.msdn.microsoft.com/dotnet/2012/07/20/the-net-framework-4-5-includes-new-garbage-collector-enhancements-for-client-and-server-apps/">Background Server GC</a> which was introduced in <em>.NET4.5</em> the number of threads can increase even more! This feature is used to offload a significant subset of the <em>Gen-2</em> <em>GC</em> by using dedicated background threads resulting in a significant reduction of the total pause times on the user threads but remember, this only applies to <em>Gen-2</em> as both <em>Gen-0</em> and <em>Gen-1</em> collections still require all user threads to be suspended.</p>

<p>Also remember that under <em>Server GC</em>, heap sizes are much larger compared to the <a href="https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/fundamentals#workstation_and_server_garbage_collection">Workstation GC</a> so don’t be alarmed if you see large memory usage in our implementations.</p>

<h4 id="note">Note:</h4>

<p>In order to keep the focus of this article on the concurrency costs of each implementation rather than the behavior of <em>GC</em>, I have excluded all of the GC threads from our profiling results. This includes the <em>Finalizer</em> as well as the <em>background GC</em> threads. But to investigate how the <em>GC</em> performed for each of the algorithms, you can include all those threads in the snapshot file provided for each implementation (by installing &amp; running <em>dotTrace</em>).</p>

<p>I will be running the application on a <strong>24-core</strong> dual CPU workstation with <strong>24GB</strong> of RAM and the input file is being read from a <strong>7200 RPM</strong> HDD with <strong>64MB</strong> of cache. Each pattern will be profiled individually and the <em>Windows File Cache</em> will be cleared between each run.</p>

<p>Finally, You can find the code <a href="https://github.com/NimaAra/Blog.Samples/tree/master/Practical%20Parallelization">HERE</a>. Okay, now that we have all those covered, let’s get started!</p>

<h3 id="1-sequential">1. Sequential</h3>

<pre><code class="language-csharp">private static IDictionary&lt;string, uint&gt; GetTopWords()
{
    Dictionary&lt;string, uint&gt; result = new(StringComparer.InvariantCultureIgnoreCase);

    // process lines as IEnumerable&lt;string&gt; read one after another from the disk.
    foreach (var line in File.ReadLines(InputFile.FullName))
    {
        foreach (var word in line.Split(Separators, StringSplitOptions.RemoveEmptyEntries))
        {
            if (!IsValidWord(word)) { continue; }
            TrackWordsOccurrence(result, word);
        }
    }

    return result
        .OrderByDescending(kv =&gt; kv.Value)
        .Take((int)TopCount)
        .ToDictionary(kv =&gt; kv.Key, kv =&gt; kv.Value);
}

private static void TrackWordsOccurrence(IDictionary&lt;string, uint&gt; wordCounts, string word)
{
    if (wordCounts.TryGetValue(word, out uint count))
    {
        wordCounts[word] = count + 1;
    }
    else
    {
        wordCounts[word] = 1;
    }
}

private static bool IsValidWord(string word) =&gt;
    !InvalidCharacters.Contains(word[0]) &amp;&amp; !StopWords.Contains(word);
</code></pre>

<p>There is nothing complicated about this code, all we are doing here is reading a bunch of lines splitting them into words, doing some filtering and keeping track of each word in a <code>Dictionary&lt;string, uint&gt;</code>. We then order the result by the count of each word in descending order and return n entries from the result.</p>

<p>Running the above produces the following:</p>

<pre><code class="language-shell">Execution time: 87,025 ms
Gen-0: 27, Gen-1: 10, Gen-2: 4
Peak WrkSet: 617,037,824
</code></pre>

<p style="text-align: center;">
    <a href="/assets/imgs/2017-06-01-practical-parallelization-in-csharp-1.sequential.png" target="_blank">
    <img alt="picture of profiling result using dotTrace" src="/assets/imgs/2017-06-01-practical-parallelization-in-csharp-1.sequential.png" width="700" />
    </a>
</p>

<p>As we can see, the program achieved an average CPU utilization of <strong><em>4.0%</em></strong>, took <strong><em>87,025</em></strong> milliseconds out of which <strong><em>0.6%</em></strong> was spent on <em>GC</em>. <strong><em>91.3%</em></strong> of the <em>main</em> thread time was in the <em>Running</em> state and <strong><em>8.7%</em></strong> in <em>Waiting</em>. The process reached a peak memory of <strong><em>~600MB</em></strong>. Since this implementation is a straight-forward single-threaded execution, there was no locking involved therefore no cost associated to locking-contention.</p>

<h3 id="2-sequential-linq">2. Sequential (LINQ)</h3>

<p>Next, the same sequential algorithm implemented using <em>LINQ</em>:</p>

<pre><code class="language-csharp">private static IDictionary&lt;string, uint&gt; GetTopWords()
{
    return File.ReadLines(InputFile.FullName)
        .SelectMany(l =&gt; l.Split(Separators, StringSplitOptions.RemoveEmptyEntries))
        .Where(IsValidWord)
        .ToLookup(x =&gt; x, StringComparer.InvariantCultureIgnoreCase)
        .Select(x =&gt; new { Word = x.Key, Count = (uint)x.Count() })
        .OrderByDescending(kv =&gt; kv.Count)
        .Take((int)TopCount)
        .ToDictionary(kv =&gt; kv.Word, kv =&gt; kv.Count);
}
</code></pre>

<p>Here we are projecting each line into a sequence of words, filter out the invalid words and then group the words using <code>ToLookup</code> (or <code>GroupBy</code>) to get their count; finally we order them and take the top n items.</p>

<p>Here’s the result:</p>

<pre><code class="language-shell">Execution time: 92,174 ms
Gen-0: 6, Gen-1: 4, Gen-2: 3
Peak WrkSet: 4,579,205,120
</code></pre>

<p style="text-align: center;">
    <a href="/assets/imgs/2017-06-01-practical-parallelization-in-csharp-2.sequential.linq.png" target="_blank">
    <img alt="picture of profiling result using dotTrace" src="/assets/imgs/2017-06-01-practical-parallelization-in-csharp-2.sequential.linq.png" width="700" />
    </a>
</p>

<p>This time, the program achieved an average CPU utilization of <strong><em>7.6%</em></strong>, took <strong><em>92,174</em></strong> milliseconds out of which <strong>8.7%</strong> was spent on <em>GC</em>. <strong><em>82.5%</em></strong> of all our threads time were in the <em>Running</em> state and <strong><em>17.5%</em></strong> in <em>Waiting</em>. Exploring the snapshot file reveals that around <strong><em>40%</em></strong> was used doing LINQ operations so there is no surprise to see the inferior performance (due to LINQ’s overhead). Just as above, there is no locking involved. Also note our process resulted in a whopping <strong><em>4.6GB</em></strong> of peak memory.</p>

<h3 id="3-plinq-naive">3. PLINQ (Naive)</h3>

<p>As the title suggests here we will build a hybrid of <em>PLINQ</em> and a single-threaded solution. The code is similar to the sequential <em>LINQ</em> with the addition of <code>.AsParallel()</code> which does all the magic!</p>

<p>The work relating to reading each line, projecting the words and filtering will be distributed across all the available system cores and the work relating to keeping track of each of the word’s occurrence is done on the <em>main</em> thread. In other words the main thread in our <code>foreach</code> loop <em>pulls</em> each line from the disk all the way through the <em>PLINQ</em> parallelized pipeline.</p>

<pre><code class="language-csharp">private static IDictionary&lt;string, uint&gt; GetTopWords()
{
    var words = File.ReadLines(InputFile.FullName)
        .AsParallel()
        .SelectMany(l =&gt; l.Split(Separators, StringSplitOptions.RemoveEmptyEntries))
        .Where(IsValidWord);

    Dictionary&lt;string, uint&gt; result = new(StringComparer.InvariantCultureIgnoreCase);
    foreach (var word in words)
    {
        TrackWordsOccurrence(result, word);
    }

    return result
        .OrderByDescending(kv =&gt; kv.Value)
        .Take((int)TopCount)
        .ToDictionary(kv =&gt; kv.Key, kv =&gt; kv.Value);
}
</code></pre>

<p>Running the above results in the following:</p>

<pre><code class="language-shell">Execution time: 80,620 ms
Gen-0: 10, Gen-1: 7, Gen-2: 4
Peak WrkSet: 1,677,287,424
</code></pre>

<p style="text-align: center;">
    <a href="/assets/imgs/2017-06-01-practical-parallelization-in-csharp-3.plinq.naive.png" target="_blank">
    <img alt="picture of profiling result using dotTrace" src="/assets/imgs/2017-06-01-practical-parallelization-in-csharp-3.plinq.naive.png" width="700" />
    </a>
</p>

<p>This time, the program achieved an average CPU utilization of <strong><em>17.5%</em></strong>, took <strong><em>80,620</em></strong> milliseconds out of which <strong><em>1.0%</em></strong> was spent on <em>GC</em>. <strong><em>17%</em></strong> of all our threads time were in the <em>Running</em> state and <strong><em>83%</em></strong> in <em>Waiting</em>. Exploring the snapshot file reveals that around <strong><em>18%</em></strong> was spent doing <em>LINQ</em> operations there is also very little locking contention (<strong><em>0.07%</em></strong>) since the main part of the app which requires synchronization is actually running on the main thread. Also note our process resulted in a <strong><em>1.7GB</em></strong> of peak memory.</p>

<p>Okay, so not much of an improvement but be ready as things are about to change!</p>

<h4 id="a-bit-about-partitioning">A bit about Partitioning</h4>

<p>Before continuing any further I feel I should mention an important aspect of <em>PLINQ</em> which is responsible for splitting and assigning each input element to a worker thread. This is known as <em>Partitioning</em> and there are currently four different partitioning strategies in <em>TPL</em> all of which are supported by <em>PLINQ</em>; These are:</p>

<ol>
  <li>Chunk partitioning</li>
  <li>Range partitioning</li>
  <li>Hash partitioning</li>
  <li>Striped partitioning</li>
</ol>

<p><strong>Chunk partitioning</strong> uses <em>dynamic</em> element allocation as opposed to <em>static</em> element allocation (which is used by both <em>Range</em> and <em>Hash</em> partitioning). <em>Dynamic</em> allocation allows partitions to be created on the fly as opposed to being allocated in advance which means that a <em>dynamic</em> partitioner needs to request elements more frequently from the input sequence resulting in more synchronization; In contrast, <em>static</em> partitioning allows elements to be assigned all at once which results in less overhead and no additional synchronization after the initial work required for creating the partitions. Note that <code>Parallel.ForEach</code> only supports <em>dynamic</em> partitioning (<a href="https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/how-to-implement-a-partitioner-for-static-partitioning">unless you implement one yourself</a>).</p>

<p><em>PLINQ</em> chooses <strong>Range partitioning</strong> for any sequence which can be indexed into i.e <code>IList&lt;T&gt;</code> (or <code>ParallelEnumerable.Range</code>) which <em>usually</em> results in a better performance unless the amount of processing required for each element is not constant. For example in a scenario where there is a non-uniform processing time (think of ray-tracing), threads can finish work on their assigned partitions early and sit there idle unable to process more items. For such scenarios with non-uniform processing times, <em>Chunk</em> partitioning may be a better strategy. It is possible to instruct <em>PLINQ</em> to choose <em>Chunk</em> partitioning for an <em>indexable</em> sequence by using <code>Partitioner.Create(myArray, true)</code>.</p>

<p><strong>Hash partitioning</strong> is used by query operators that require comparing elements (e.g. <code>GroupBy</code>, <code>Join</code>, <code>GroupJoin</code>, <code>Intersect</code>, <code>Except</code>, <code>Union</code> and <code>Distinct</code>). <em>Hash</em> partitioning can be inefficient in that it must precalculate the <em>hashcode</em> for each element (so that elements with identical codes are assigned and processed on the same thread).</p>

<p><strong>Striped partitioning</strong> is the strategy used by <code>SkipWhile</code> and <code>TakeWhile</code> and is optimized for processing items at the head of a data source. In striped partitioning, each of the n worker threads is allocated a small number of items (sometimes 1) from each block of n items. The set of items belonging to a single thread is called a <em>stripe</em>, hence the name. A useful feature of this scheme is that there is no inter-thread synchronization required as each worker thread can determine its data via simple arithmetic. This is really a special case of range partitioning and only works on arrays and types that implement <code>IList&lt;T&gt;</code>.</p>

<p>Here is a diagram showing an overview of the most widely used <em>Chunk</em> and <em>Range</em> partitioning taken from <em>Albahari’s</em> must read <a href="http://www.albahari.com/threading/part5.aspx#_Optimizing_PLINQ">Threading in C#</a>.</p>

<p style="text-align: center;">
    <a href="/assets/imgs/2017-06-01-practical-parallelization-in-csharp-plinq.partitioning.png" target="_blank">
    <img alt="picture of plinq partitioning" src="/assets/imgs/2017-06-01-practical-parallelization-in-csharp-plinq.partitioning.png" width="700" />
    </a>
</p>

<p>For more details on <em>Partitioning</em>, I highly suggest having a look at <a href="https://blogs.msdn.microsoft.com/pfxteam/2009/05/28/partitioning-in-plinq/">Partitioning in PLINQ</a>, <a href="https://blogs.msdn.microsoft.com/pfxteam/2007/12/02/chunk-partitioning-vs-range-partitioning-in-plinq/">Chunk partitioning vs range partitioning in PLINQ</a>, <a href="http://reedcopsey.com/2010/01/26/parallelism-in-net-part-5-partitioning-of-work/">Partitioning of Work</a> and <a href="https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/custom-partitioners-for-plinq-and-tpl">Custom Partitioners for PLINQ and TPL</a>.</p>

<p>Okay, now that we know a little more about partitioning we can look at more <em>PLINQ</em> implementations.</p>

<h3 id="4-plinq">4. PLINQ</h3>

<p>This time we are going to let <em>PLINQ</em> do all the work by letting it partition the input sequence of lines (using <em>Chunk</em> partitioning) and see if we can do any better than what we have done so far.</p>

<pre><code class="language-csharp">private static IDictionary&lt;string, uint&gt; GetTopWords()
{
    return File.ReadLines(InputFile.FullName)
        .AsParallel()
        .SelectMany(l =&gt; l.Split(Separators, StringSplitOptions.RemoveEmptyEntries))
        .Where(IsValidWord)
        .ToLookup(x =&gt; x, StringComparer.InvariantCultureIgnoreCase)
        .AsParallel()
        .Select(x =&gt; new { Word = x.Key, Count = (uint)x.Count() })
        .OrderByDescending(kv =&gt; kv.Count)
        .Take((int)TopCount)
        .ToDictionary(kv =&gt; kv.Word, kv =&gt; kv.Count);
}
</code></pre>

<p>Running the above results in the following:</p>

<pre><code class="language-shell">Execution time: 22,480 ms
Gen-0: 4, Gen-1: 2, Gen-2: 2
Peak WrkSet: 4,579,401,728
</code></pre>

<p style="text-align: center;">
    <a href="/assets/imgs/2017-06-01-practical-parallelization-in-csharp-4.plinq.png" target="_blank">
    <img alt="picture of profiling result using dotTrace" src="/assets/imgs/2017-06-01-practical-parallelization-in-csharp-4.plinq.png" width="700" />
    </a>
</p>

<p>And just like that the program managed to achieve an average CPU utilization of <strong><em>60.7%</em></strong>, took <strong><em>22,480</em></strong> milliseconds out of which <strong><em>6.1%</em></strong> was spent on <em>GC</em>. <strong><em>62.4%</em></strong> of all our threads time were in the <em>Running</em> state and <strong><em>37.6%</em></strong> in <em>Waiting</em>. Exploring the snapshot file reveals that around <strong><em>47%</em></strong> was spent executing <em>LINQ</em> operations and <strong><em>14.5%</em></strong> on locking contention. Note the size of the <em>WorkingSet</em> is still at around <strong><em>4.5GB</em></strong>.</p>

<p>Despite the great reduction in execution time we can still observe a substantial cost in locking contention. A large part of this cost is incurred during the grouping of the words (the step calling <code>ToLookup(x =&gt; x, StringComparer.InvariantCultureIgnoreCase)</code>).</p>

<h3 id="5-plinq-mapreduce">5. PLINQ (MapReduce)</h3>

<p>As we saw above, despite the simplicity and succinctness of the <em>PLINQ</em> implementation, we still incurred a high cost of locking so now we will use a different flavour of <em>PLINQ</em> which allows us to perform <em>MapReduce</em>. We are going to have a <em>map</em> phase where our problem can be split into smaller independent steps which can then be executed on any thread without the need for synchronization.</p>

<p>Each worker thread will then do the work of splitting the lines and excluding the invalid words and when the time comes to group them all back together, each thread will then merge <em>reduce</em> the result by locking over the shared collection which will happen per partition.</p>

<p>Let us see how this can be implemented using the <code>Aggregate</code> method in <em>PLINQ</em>:</p>

<pre><code class="language-csharp">private static IDictionary&lt;string, uint&gt; GetTopWords()
{
    return File.ReadLines(InputFile.FullName)
        .AsParallel()
        .Aggregate(
/*#1*/      () =&gt; new Dictionary&lt;string, uint&gt;(StringComparer.InvariantCultureIgnoreCase),
/*#2*/      (localDic, line) =&gt;
            {
                foreach (var word in line.Split(Separators, StringSplitOptions.RemoveEmptyEntries))
                {
                    if (!IsValidWord(word)) { continue; }
                    TrackWordsOccurrence(localDic, word);
                }
                return localDic;
            },
/*#3*/      (finalResult, localDic) =&gt;
            {
                foreach (var pair in localDic)
                {
                    var key = pair.Key;
                    if (finalResult.ContainsKey(key))
                    {
                        finalResult[key] += pair.Value;
                    }
                    else
                    {
                        finalResult[key] = pair.Value;
                    }
                }
                return finalResult;
            },
/*#4*/      finalResult =&gt; finalResult
                .OrderByDescending(kv =&gt; kv.Value)
                .Take((int)TopCount)
                .ToDictionary(kv =&gt; kv.Key, kv =&gt; kv.Value)
        );
}
</code></pre>

<p>Still confusing? Here are the main steps again:</p>

<ul>
  <li>
    <p>Step #1: First we supply a <code>Dictionary&lt;string, uint&gt;</code> for each of the threads running our code so this means every thread will have a local collection to work with, eliminating the need for locking.</p>
  </li>
  <li>
    <p>Step #2: Here we have the main logic which will be executed by each thread for every line in our file, the scary looking <code>Func&lt;Dictionary&lt;string, uint&gt;, string, Dictionary&lt;string, uint&gt;&gt;</code> allows the dictionary declared at step <em>#1</em> to be passed as <code>localDic</code> along with the line read from the disk to the body of the delegate. After the thread is done adding the words to the dictionary it will return the <code>localDic</code> so that it can be available to the same thread operating on the next line in the same partition.</p>
  </li>
  <li>
    <p>Step #3: Once every thread has finished processing all the items in its partition then all the items on its local dictionary is then merged (reduced) into a final result-set. Hence, the delegate is of type <code>Func&lt;Dictionary&lt;string, uint&gt;, Dictionary&lt;string, uint&gt;&gt;</code>. By this step our <em>MapReduce</em> implementation is actually complete however the <code>Aggregate</code> method offers us one final step.</p>
  </li>
  <li>
    <p>Step #4: This is where you have the chance to do any modification to the final result before returning it. In our case we are doing a simple ordering followed by a <code>Take</code> and projection back into a dictionary.</p>
  </li>
</ul>

<p>So let us see how we did this time:</p>

<pre><code class="language-shell">Execution time: 21,915 ms
Gen-0: 12, Gen-1: 5, Gen-2: 3
Peak WrkSet: 1,082,503,168
</code></pre>

<p style="text-align: center;">
    <a href="/assets/imgs/2017-06-01-practical-parallelization-in-csharp-5.plinq.map.reduce.png" target="_blank">
    <img alt="picture of profiling result using dotTrace" src="/assets/imgs/2017-06-01-practical-parallelization-in-csharp-5.plinq.map.reduce.png" width="700" />
    </a>
</p>

<p>This time the program achieved an average CPU utilization of <strong><em>45.9%</em></strong>, it took <strong><em>21,915</em></strong> milliseconds out of which only <strong><em>1.4%</em></strong> was spent on <em>GC</em>. <strong><em>55.1%</em></strong> of all our threads time were in the <em>Running</em> state and <strong><em>44.9%</em></strong> in <em>Waiting</em>. So despite the lower CPU utilization in comparison to the previous step the lower time in <em>GC</em> did actually improve the overall execution time. Exploring the snapshot file reveals that around <strong><em>37%</em></strong> was spent executing <em>LINQ</em> operations and <strong><em>6.9%</em></strong> on locking contention. You can also see that our peak memory usage was <strong><em>4x</em></strong> smaller than the previous method. So while we may not have improved the execution time significantly we have managed to achieve more by using less CPU as well as a much lower memory footprint.</p>

<p>Not too shabby ha! :-)</p>

<h3 id="6-plinq-concurrentdictionary">6. PLINQ (ConcurrentDictionary)</h3>

<p><em>PLINQ</em>’s biggest advantage/convenience is thanks to its ability to collate the result of the parallelized work into a single output sequence and that is indeed what we have used until now. For this pattern we are going to do things a bit differently; First, we are not going to use <em>PLINQ</em>’s result collation. Instead, we are going to give it a function and tell it to run multiple threads each applying that function to our data. The method allowing us to achieve this is <code>ForAll</code>. That was the first part, now for the second part we are going to choose a different data type for tracking the count of words.</p>

<p>Sometimes choosing the right datatype (in our case collection), can make all the difference. There is no better example to demonstrate this than what we will see in this section. We are going to pick the <code>ConcurrentDictionary</code> as our collection and let it handle all the synchronization for us.</p>

<pre><code class="language-csharp">private static IDictionary&lt;string, uint&gt; GetTopWords()
{
    ConcurrentDictionary&lt;string, uint&gt; result = new(StringComparer.InvariantCultureIgnoreCase);

    File.ReadLines(InputFile.FullName)
        .AsParallel()
        .ForAll(line =&gt;
        {
            foreach (var word in line.Split(Separators, StringSplitOptions.RemoveEmptyEntries))
            {
                if (!IsValidWord(word)) { continue; }
                result.AddOrUpdate(word, 1, (key, oldVal) =&gt; oldVal + 1);
            }
        });

    return result
        .OrderByDescending(kv =&gt; kv.Value)
        .Take((int)TopCount)
        .ToDictionary(kv =&gt; kv.Key, kv =&gt; kv.Value);
}
</code></pre>

<p>There is not much to the code except the use of <code>AddOrUpdate</code>. Each thread is using this method to <em>Add</em> a given word with a count of <em>1</em>, if the word was already added, it then takes the value (count) of that word and adds <em>1</em> to it. All of this is done in a thread-safe manner and any synchronization is handled by the <code>ConcurrentDictionary</code>. Okay, how did we do this time?</p>

<pre><code class="language-shell">Execution time: 19,229 ms
Gen-0: 16, Gen-1: 8, Gen-2: 4
Peak WrkSet: 863,531,008
</code></pre>

<p style="text-align: center;">
    <a href="/assets/imgs/2017-06-01-practical-parallelization-in-csharp-6.plinq.concurrent.dictionary.png" target="_blank">
    <img alt="picture of profiling result using dotTrace" src="/assets/imgs/2017-06-01-practical-parallelization-in-csharp-6.plinq.concurrent.dictionary.png" width="700" />
    </a>
</p>

<p>This time the program achieved an average CPU utilization of <strong><em>53%</em></strong>, it took <strong><em>19,229</em></strong> milliseconds out of which only <strong><em>7%</em></strong> was spent on <em>GC</em>. <strong><em>65.7%</em></strong> of all our threads time were in the <em>Running</em> state and <strong><em>34.3%</em></strong> in <em>Waiting</em>. Exploring the snapshot file reveals that around <strong><em>33%</em></strong> was spent executing <em>LINQ</em> operations and <strong><em>10.3%</em></strong> in locking.</p>

<h3 id="7-plinq-producerconsumer">7. PLINQ (ProducerConsumer)</h3>

<p>In this final section of using <em>PLINQ</em> to achieve parallelism, we are going to cover my favorite pattern which I frequently use to deal with problems where I have one or more producers producing data and one or more workers consuming them.</p>

<p>For this algorithm, we have a single <em>producer</em> reading and adding (producing) the lines into some sort of a collection. We then have a bunch of <em>consumers</em> taking (consuming) and processing each line. The collection which allows such dance between the producer and its consumers is called the <code>BlockingCollection&lt;T&gt;</code> which by default is very similar to a [ConcurrentQueue<T>](&lt;https://msdn.microsoft.com/en-us/library/dd267265(v=vs.110).aspx&gt;). There is more to `BlockingCollection<T>` than I will cover today but the bits we are interested in are the _Add_ method which the producer will use to add each line to the collection; The `GetConsumingEnumerable()` which blocks each thread invoking it until there is an item in the collection and finally the `CompleteAdding` method which notifies the consumers that no more item will be added by the publisher(s) therefore unblocking every thread that is waiting on `GetConsumingEnumerable()`.</T></T></p>

<p>As far as <em>PLINQ</em> is concerned we are telling it to use at most <em>12</em> threads and also to not buffer the input so that as soon as the <em>publisher</em> adds a line, <em>PLINQ</em> can pass that to one of its <em>12</em> <em>consumers</em> and through the rest of the pipeline.</p>

<pre><code class="language-csharp">private static IDictionary&lt;string, uint&gt; GetTopWords()
{
    const int WorkerCount = 12;
    const int BoundedCapacity = 10_000;
    ConcurrentDictionary&lt;string, uint&gt; result = new(StringComparer.InvariantCultureIgnoreCase);

    // Setup the queue
    BlockingCollection&lt;string&gt; blockingCollection = new(BoundedCapacity);

    // Declare the worker
    Action&lt;string&gt; work = line =&gt;
    {
        foreach (var word in line.Split(Separators, StringSplitOptions.RemoveEmptyEntries))
        {
            if (!IsValidWord(word)) { continue; }
            result.AddOrUpdate(word, 1, (key, oldVal) =&gt; oldVal + 1);
        }
    };

    Task.Run(() =&gt;
    {
        // Begin producing
        foreach (var line in File.ReadLines(InputFile.FullName))
        {
            blockingCollection.Add(line);
        }
        blockingCollection.CompleteAdding();
    });

    // Start consuming
    blockingCollection
        .GetConsumingEnumerable()
        .AsParallel()
        .WithDegreeOfParallelism(WorkerCount)
        .WithMergeOptions(ParallelMergeOptions.NotBuffered)
        .ForAll(work);

    return result
        .OrderByDescending(kv =&gt; kv.Value)
        .Take((int)TopCount)
        .ToDictionary(kv =&gt; kv.Key, kv =&gt; kv.Value);
}
</code></pre>

<p>With the output of:</p>

<pre><code class="language-shell">Execution time: 18,858 ms
Gen-0: 16, Gen-1: 9, Gen-2: 4
Peak WrkSet: 857,141,248
</code></pre>

<p style="text-align: center;">
    <a href="/assets/imgs/2017-06-01-practical-parallelization-in-csharp-7.plinq.producer.consumer.png" target="_blank">
    <img alt="picture of profiling result using dotTrace" src="/assets/imgs/2017-06-01-practical-parallelization-in-csharp-7.plinq.producer.consumer.png" width="700" />
    </a>
</p>

<p>This time the program achieved an average CPU utilization of <strong><em>30.7%</em></strong>, it took <strong><em>18,858</em></strong> milliseconds out of which only <strong><em>7.2%</em></strong> was spent on <em>GC</em>. <strong><em>67.9%</em></strong> of all our threads time were in the <em>Running</em> state and <strong><em>32.1%</em></strong> in <em>Waiting</em>. Exploring the snapshot file reveals that around <strong><em>15%</em></strong> was spent executing <em>LINQ</em> operations and <strong><em>2.2%</em></strong> in locking contention.</p>

<p>As you can see, we managed to achieve very good concurrency by only using half of our cores and reduced the overall <em>Waiting</em> time and locking cost.</p>

<p>I cannot think of any other ways to squeeze any more performance juice out of <em>PLINQ</em>; (I am happy to be challenged by anyone on this, let me know in the comments) therefore, we are now going to start playing with the <code>Parallel</code> class.</p>

<h3 id="8-parallelforeach-mapreduce">8. Parallel.ForEach (MapReduce)</h3>

<p>The <a href="https://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel(v=vs.110).aspx">Parallel</a> class has a bunch of methods for us to use but the one we are interested in is the <code>Parallel.ForEach</code>. In it’s simplest form it accepts an <code>IEnumerable&lt;T&gt;</code> and an <code>Action&lt;T&gt;</code> which it then invokes in parallel for every item in the collection. Using this method however is not suitable for our use-case as we would need to synchronize access to our dictionary responsible for tracking the occurrence of each word therefore diminishing any benefits of parallelization. Instead, we are going to use the overload of the method which enables us to implement <em>MapReduce</em>. Here’s the code:</p>

<pre><code class="language-csharp">private static IDictionary&lt;string, uint&gt; GetTopWords()
{
    Dictionary&lt;string, uint&gt; result = new (StringComparer.InvariantCultureIgnoreCase);
    Parallel.ForEach(
        File.ReadLines(InputFile.FullName),
        new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount },
        () =&gt; new Dictionary&lt;string, uint&gt;(StringComparer.InvariantCultureIgnoreCase),
        (line, state, index, localDic) =&gt;
        {
            foreach (var word in line.Split(Separators, StringSplitOptions.RemoveEmptyEntries))
            {
                if (!IsValidWord(word)) { continue; }
                TrackWordsOccurrence(localDic, word);
            }
            return localDic;
        },
        localDic =&gt;
        {
            lock (result)
            {
                foreach (var pair in localDic)
                {
                    var key = pair.Key;
                    if (result.ContainsKey(key))
                    {
                        result[key] += pair.Value;
                    }
                    else
                    {
                        result[key] = pair.Value;
                    }
                }
            }
        }
    );

    return result
        .OrderByDescending(kv =&gt; kv.Value)
        .Take((int)TopCount)
        .ToDictionary(kv =&gt; kv.Key, kv =&gt; kv.Value);
}
</code></pre>

<p>The implementation is very similar to the <em>MapReduce</em> we implemented using <em>PLINQ</em> and as you saw before, the main idea behind this pattern is to ensure each thread has it’s local data to work with and then when all the threads have processed all their items they will then merge (<em>reduce</em>) their results into a single sequence therefore greatly reducing synchronization.</p>

<p>Here is what this implementation gets us:</p>

<pre><code class="language-shell">Execution time: 19,606 ms
Gen-0: 23, Gen-1: 13, Gen-2: 7
Peak WrkSet: 942,002,176
</code></pre>

<p style="text-align: center;">
    <a href="/assets/imgs/2017-06-01-practical-parallelization-in-csharp-8.parallel.foreach.map.reduce.png" target="_blank">
    <img alt="picture of profiling result using dotTrace" src="/assets/imgs/2017-06-01-practical-parallelization-in-csharp-8.parallel.foreach.map.reduce.png" width="700" />
    </a>
</p>

<p>Okay, not bad. We have an average CPU utilization of <strong><em>35.9%</em></strong>, an execution time of <strong><em>19,606</em></strong> milliseconds out of which <strong><em>3.4%</em></strong> was spent on <em>GC</em>. <strong><em>40.5%</em></strong> of all our threads time were in the <em>Running</em> state and <strong><em>59.5%</em></strong> in <em>Waiting</em>. Looking at the snapshot we can see that the cost of locking contention is a whopping <strong><em>35%</em></strong>, why? This is mainly due to the <em>Chunk Partitioning</em> if we were using <em>Range Partitioning</em>, we would only need to <em>lock</em> over the <code>result</code> once per thread at the end of its partition but for that we would need to load all the lines into an indexable collection such as an <code>Array</code> or an <code>IList</code> which would be fine if you had all the available RAM. In our case however, I was happy to pay the cost of having to <em>lock</em> more frequently (due to much smaller chunks).</p>

<h3 id="9-parallelforeach-concurrentdictionary">9. Parallel.ForEach (ConcurrentDictionary)</h3>

<p>In this section we are going to again use the <code>ConcurrentDictionary</code> and see what it gets us when used with <code>Parallel.ForEach</code>.</p>

<pre><code class="language-csharp">private static IDictionary&lt;string, uint&gt; GetTopWords()
{
    ConcurrentDictionary&lt;string, uint&gt; result = new(StringComparer.InvariantCultureIgnoreCase);
    Parallel.ForEach(
        File.ReadLines(InputFile.FullName),
        new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount },
        (line, state, index) =&gt;
        {
            foreach (var word in line.Split(Separators, StringSplitOptions.RemoveEmptyEntries))
            {
                if (!IsValidWord(word)) { continue; }
                result.AddOrUpdate(word, 1, (key, oldVal) =&gt; oldVal + 1);
            }
        }
    );

    return result
        .OrderByDescending(kv =&gt; kv.Value)
        .Take((int)TopCount)
        .ToDictionary(kv =&gt; kv.Key, kv =&gt; kv.Value);
}
</code></pre>

<p>Which outputs:</p>

<pre><code class="language-shell">Execution time: 19,622 ms
Gen-0: 13, Gen-1: 6, Gen-2: 3
Peak WrkSet: 853,209,088
</code></pre>

<p style="text-align: center;">
    <a href="/assets/imgs/2017-06-01-practical-parallelization-in-csharp-9.parallel.foreach.concurrent.dictionary.png" target="_blank">
    <img alt="picture of profiling result using dotTrace" src="/assets/imgs/2017-06-01-practical-parallelization-in-csharp-9.parallel.foreach.concurrent.dictionary.png" width="700" />
    </a>
</p>

<p>I don’t know about you but I quite like the <code>ConcurrentDictionary</code>! We have an average CPU utilization of <strong><em>52.8%</em></strong>, an execution time of <strong><em>19,622</em></strong> milliseconds out of which <strong><em>6.7%</em></strong> was spent on <em>GC</em>. <strong><em>61.6%</em></strong> of all our threads time were in the <em>Running</em> state and <strong><em>38.4%</em></strong> in <em>Waiting</em>. Looking at the snapshot reveals the cost of locking contention to be <strong><em>9.4%</em></strong>.</p>

<p>Despite the great result we can see from the profiling graph that we have <em>over loaded</em> the CPU. How can I tell? Well each of those pink sections on the graph is showing us the time intervals where the thread is ready to run on the next available CPU core; Therefore, long ready intervals (the time the thread is waiting so that it can switch its state from <em>Waiting</em> to <em>Running</em>) can mean thread starvation and CPU overload. To address it, we can try reducing the number of threads by playing with the <code>MaxDegreeOfParallelism</code>. So remember that CPU overloading/thread starvation <em>can</em> and <em>will</em> hurt the performance.</p>

<h3 id="10-producerconsumer-with-tasks">10. ProducerConsumer with Tasks</h3>

<p>We talked about the <em>ProducerConsumer</em> pattern in the <em>PLINQ</em> section, what we are doing here is pretty much identical to what we did before except we are going to use <a href="https://msdn.microsoft.com/en-us/library/system.threading.tasks.task(v=vs.110).aspx">Tasks</a> to execute our <em>consumers</em>.</p>

<p>Note the most important thing to remember about this pattern is that once the worker threads finish processing each item they get from the queue, they will stay blocked waiting for more items until the queue is marked as <em>complete</em>. So depending on the size of your input, you need to make sure that when you are assigning worker threads using <code>Task</code>s, you mark them with the [TaskCreationOptions.LongRunning])(https://msdn.microsoft.com/en-us/library/system.threading.tasks.taskcreationoptions(v=vs.110).aspx) flag otherwise the <a href="https://github.com/dotnet/coreclr/blob/master/src/vm/hillclimbing.cpp">Hill Climbing</a> aka <a href="http://mattwarren.org/2017/04/13/The-CLR-Thread-Pool-Thread-Injection-Algorithm/">Thread Injection</a> algorithm employed by <em>TPL</em> thinks that threads in the <code>ThreadPool</code> are blocked so in order to prevent against <em>dead-locks</em>, it kicks in and inject extra threads to the <code>ThreadPool</code> at a <a href="https://msdn.microsoft.com/en-gb/library/ff963549.aspx">rate of one thread every 500 milliseconds</a> which is not what we want. By using this flag you are telling <em>TPL</em> to spin up a dedicated thread for each of your workers/consumers.</p>

<pre><code class="language-csharp">private static IDictionary&lt;string, uint&gt; GetTopWords()
{
    const int WorkerCount = 12;
    const int BoundedCapacity = 10_000;
    ConcurrentDictionary&lt;string, uint&gt; result = new(StringComparer.InvariantCultureIgnoreCase);

    // Setup the queue
    BlockingCollection&lt;string&gt; blockingCollection = new(BoundedCapacity);

    // Declare the worker
    Action work = () =&gt;
    {
        foreach (var line in blockingCollection.GetConsumingEnumerable())
        {
            foreach (var word in line.Split(Separators, StringSplitOptions.RemoveEmptyEntries))
            {
                if (!IsValidWord(word)) { continue; }
                result.AddOrUpdate(word, 1, (key, oldVal) =&gt; oldVal + 1);
            }
        }
    };

    // Start the workers
    var tasks = Enumerable.Range(1, WorkerCount)
        .Select(n =&gt;
            Task.Factory.StartNew(
                work,
                CancellationToken.None,
                TaskCreationOptions.LongRunning,
                TaskScheduler.Default))
        .ToArray();

    // Begin producing
    foreach (var line in File.ReadLines(InputFile.FullName))
    {
        blockingCollection.Add(line);
    }
    blockingCollection.CompleteAdding();
    // End of producing

    // Wait for workers to finish their work
    Task.WaitAll(tasks);

    return result
        .OrderByDescending(kv =&gt; kv.Value)
        .Take((int)TopCount)
        .ToDictionary(kv =&gt; kv.Key, kv =&gt; kv.Value);
}
</code></pre>

<p>Which outputs:</p>

<pre><code class="language-shell">Execution time: 31,979 ms
Gen-0: 15, Gen-1: 8, Gen-2: 4
Peak WrkSet: 935,489,536
</code></pre>

<p style="text-align: center;">
    <a href="/assets/imgs/2017-06-01-practical-parallelization-in-csharp-10.task.producer.consumer.png" target="_blank">
    <img alt="picture of profiling result using dotTrace" src="/assets/imgs/2017-06-01-practical-parallelization-in-csharp-10.task.producer.consumer.png" width="700" />
    </a>
</p>

<p>We have an average CPU utilization of <strong><em>26.5%</em></strong>, an execution time of <strong><em>31,979</em></strong> milliseconds out of which <strong><em>4.3%</em></strong> was spent on <em>GC</em>. <strong><em>59.1%</em></strong> of all our threads time were in the <em>Running</em> state and <strong><em>40.9%</em></strong> in <em>Waiting</em>. Looking at the snapshot we can see that cost of locking contention was at <strong><em>2%</em></strong>.</p>

<h3 id="11-producerconsumer-with-tasks-easier">11. ProducerConsumer with Tasks (Easier)</h3>

<p>As I mentioned before, I use this pattern regularly therefore, over the years I have built an <em>opinionated</em> wrapper around it to reduce boiler plate as well as providing easy exception handling and control over the producers and consumers. It can also be used as a <em>single-thread</em> worker (<em>sequencer</em>) which is another pattern of its own that I may write about in another article. It is part of my <a href="https://github.com/NimaAra/Easy.Common">Easy.Common</a> library available on <a href="https://www.nuget.org/packages/Easy.Common/">NuGet</a>. So let us implement what we did in the previous section by using the <a href="https://github.com/NimaAra/Easy.Common/blob/master/Easy.Common/ProducerConsumerQueue.cs">ProducerConsumerQueue</a>.</p>

<pre><code class="language-csharp">private static IDictionary&lt;string, uint&gt; GetTopWords()
{
    const int WorkerCount = 12;
    const int BoundedCapacity = 10_000;
    ConcurrentDictionary&lt;string, uint&gt; result = new(StringComparer.InvariantCultureIgnoreCase);

    // Declare the worker
    Action&lt;string&gt; work = line =&gt;
    {
        foreach (var word in line.Split(Separators, StringSplitOptions.RemoveEmptyEntries))
        {
            if (!IsValidWord(word)) { continue; }
            result.AddOrUpdate(word, 1, (key, oldVal) =&gt; oldVal + 1);
        }
    };

    // Setup the queue
    ProducerConsumerQueue&lt;string&gt; pcq = new(work, WorkerCount, BoundedCapacity);
    pcq.OnException += (sender, ex) =&gt; Console.WriteLine("Oooops: " + ex.Message);

    // Begin producing
    foreach (var line in File.ReadLines(InputFile.FullName))
    {
        pcq.Add(line);
    }
    pcq.CompleteAdding();
    // End of producing

    // Wait for workers to finish their work
    pcq.Completion.Wait();

    return result
        .OrderByDescending(kv =&gt; kv.Value)
        .Take((int)TopCount)
        .ToDictionary(kv =&gt; kv.Key, kv =&gt; kv.Value);
}
</code></pre>

<p>With the following output:</p>

<pre><code class="language-shell">Execution time: 39,124 ms
Gen-0: 14, Gen-1: 7, Gen-2: 4
Peak WrkSet: 934,985,728
</code></pre>

<p style="text-align: center;">
    <a href="/assets/imgs/2017-06-01-practical-parallelization-in-csharp-11.task.producer.consumer.easier.png" target="_blank">
    <img alt="picture of profiling result using dotTrace" src="/assets/imgs/2017-06-01-practical-parallelization-in-csharp-11.task.producer.consumer.easier.png" width="700" />
    </a>
</p>

<p>We have an average CPU utilization of <strong><em>25.1%</em></strong>, an execution time of <strong><em>39,124</em></strong> milliseconds out of which <strong><em>3.4%</em></strong> was spent on <em>GC</em>. <strong><em>53.8%</em></strong> of all our threads time were in the <em>Running</em> state and <strong><em>46.2%</em></strong> in <em>Waiting</em>. The snapshot shows the cost of locking contention as <strong><em>2%</em></strong>.</p>

<h3 id="12-tpl-dataflow">12. TPL Dataflow</h3>

<p>Finally and for the sake of completion we are going to implement the same solution using <em>TPL Dataflow</em> which provides a pipeline based execution and is great for implementing <em>ActorModel</em> scenarios as it provides (among other things) <em>message passing</em>. I am not going to focus much on <em>Dataflow</em> or <em>ActorModel</em> as there is a lot to cover.</p>

<p>We are going to start by creating the <code>bufferBlock</code> to which we push our lines, the block is then linked to <code>splitLineToWordsBlock</code> which as its name suggests is responsible for turning our lines into words. The <code>splitLineToWordsBlock</code> itself is linked to the <code>batchWordsBlock</code> which batches up our words into arrays of length <em>5000</em>. Finally, each batch is then fed through the <code>trackWordsOccurrencBlock</code> which tracks the occurrence of each word.</p>

<p>Once we have all our blocks linked together, all we have to do is read our lines and feed them through the <code>bufferBlock</code>; When we are done pushing all the lines, we mark the <code>bufferBlock</code> as complete and wait for the <code>trackWordsOccurrencBlock</code> to finish consuming all its batches. Finally, just like the previous steps we order the result and return the top n entries.</p>

<pre><code class="language-csharp">private static IDictionary&lt;string, uint&gt; GetTopWords()
{
    const int WorkerCount = 12;
    ConcurrentDictionary&lt;string, uint&gt; result = new(StringComparer.InvariantCultureIgnoreCase);
    const int BoundedCapacity = 10_000;

    BufferBlock&lt;string&gt; bufferBlock = new(new DataflowBlockOptions { BoundedCapacity = BoundedCapacity });

    TransformManyBlock&lt;string, string&gt; splitLineToWordsBlock = new(
        line =&gt; line.Split(Separators, StringSplitOptions.RemoveEmptyEntries),
        new ExecutionDataflowBlockOptions
        {
            MaxDegreeOfParallelism = 1,
            BoundedCapacity = BoundedCapacity
        });

    BatchBlock&lt;string&gt; batchWordsBlock = new(5_000);

    ActionBlock&lt;string[]&gt; trackWordsOccurrencBlock = new(words =&gt;
        {
            foreach (var word in words)
            {
                if (!IsValidWord(word)) { continue; }
                result.AddOrUpdate(word, 1, (key, oldVal) =&gt; oldVal + 1);
            }
        },
        new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = WorkerCount });

    DataflowLinkOptions defaultLinkOptions = new () { PropagateCompletion = true };
    bufferBlock.LinkTo(splitLineToWordsBlock, defaultLinkOptions);
    splitLineToWordsBlock.LinkTo(batchWordsBlock, defaultLinkOptions);
    batchWordsBlock.LinkTo(trackWordsOccurrencBlock, defaultLinkOptions);

    // Begin producing
    foreach (var line in File.ReadLines(InputFile.FullName))
    {
        bufferBlock.SendAsync(line).Wait();
    }

    bufferBlock.Complete();
    // End of producing

    // Wait for workers to finish their work
    trackWordsOccurrencBlock.Completion.Wait();

    return result
        .OrderByDescending(kv =&gt; kv.Value)
        .Take((int)TopCount)
        .ToDictionary(kv =&gt; kv.Key, kv =&gt; kv.Value);
}
</code></pre>

<p>Which outputs:</p>

<pre><code class="language-shell">Execution time: 31,447 ms
Gen-0: 18, Gen-1: 10, Gen-2: 4
Peak WrkSet: 868,356,096
</code></pre>

<p style="text-align: center;">
    <a href="/assets/imgs/2017-06-01-practical-parallelization-in-csharp-12.tpl.dataflow.png" target="_blank">
    <img alt="picture of profiling result using dotTrace" src="/assets/imgs/2017-06-01-practical-parallelization-in-csharp-12.tpl.dataflow.png" width="700" />
    </a>
</p>

<p>We have an average CPU utilization of <strong><em>21.6%</em></strong>, an execution time of <strong><em>31,447</em></strong> milliseconds out of which <strong><em>4.3%</em></strong> was spent on <em>GC</em>. <strong><em>25.1%</em></strong> of all our threads time were in the <em>Running</em> state and <strong><em>74.9%</em></strong> in <em>Waiting</em>. Looking at the snapshot we can see the cost of locking contention was at <strong><em>0.01%</em></strong> which is not surprising as our entire processing was pipelined.</p>

<h3 id="conclusion">Conclusion</h3>

<p>Here is a quick a summary of what each implementation achieved:</p>

<p style="text-align: center;">
    <a href="/assets/imgs/2017-06-01-practical-parallelization-in-csharp-result.summary.png" target="_blank">
    <img alt="picture of a table showing the result of profiling of each variation compared to one another" src="/assets/imgs/2017-06-01-practical-parallelization-in-csharp-result.summary.png" width="700" />
    </a>
</p>

<p>We saw that both the <code>Parallel</code> class and <em>PLINQ</em> can efficiently partition tasks and execute them across all the available cores in our system. We also learned how choosing a different data type, library or even different overloads of the same library can help us achieve better performance and CPU utilization.</p>

<p>We then looked at some of the other approaches to achieving parallelism mainly <em>ProducerConsumer</em> and <em>ActorModel</em> which may not have necessarily performed well for our <a href="https://en.wikipedia.org/wiki/Data_parallelism">DataParallelism</a> scenario but can be suitable for <a href="https://en.wikipedia.org/wiki/Task_parallelism">TaskParallelism</a> problems you may face in the future.</p>

<p>Finally, in order to help you choose between <em>PLINQ</em> and <code>Parallel</code>, I would like to mention an important difference between the two which goes back to how they were designed.</p>

<p><code>Parallel</code> uses a concept referred to as <em>Replicating Tasks</em> which means a loop will start with one task for processing the loop body and if more threads are freed up to assist with the processing, additional tasks will be created to run on those threads which minimizes resource consumption in scenarios where most of the threads in the <code>ThreadPool</code> are busy doing other work. <em>PLINQ</em> on the other hand requires that a specific number of threads are actively involved for the query to make progress. This difference in design is the reason why there are <a href="https://blogs.msdn.microsoft.com/pfxteam/2009/05/29/paralleloptions-maxdegreeofparallelism-vs-plinqs-withdegreeofparallelism/">ParallelOptions.MaxDegreeOfParallelism &amp; PLINQ’s WithDegreeOfParallelism</a>.</p>

<p>I hope you enjoyed reading this article as much as I enjoyed writing it and I invite you to share the patterns and techniques that you use for <em>multi-threading</em> and <em>parallelism</em> in the comments section below.</p>

<p>Have fun and let’s:</p>

<p style="text-align: center;">
    <img alt="picture of a meme being excited to use parallelization in everything" src="/assets/imgs/2017-06-01-practical-parallelization-in-csharp-parallelize.all.the.things.jpg" width="400" />    
</p>]]></content><author><name>Nima Ara</name></author><category term="C#" /><category term=".NET" /><category term="Performance" /><category term="Threading" /><summary type="html"><![CDATA[The barrier of entry into multi-threading in .NET is relatively low as both Parallel Computing (making programs run faster) and Concurrent Programming (making programs more responsive) have been greatly simplified since the introduction of TPL and its friends (Parallel and PLINQ) in .NET4.0.]]></summary></entry><entry><title type="html">Local Functions, a C# 7 Feature</title><link href="https://nimaara.com/2017/04/01/local-functions-feature.html" rel="alternate" type="text/html" title="Local Functions, a C# 7 Feature" /><published>2017-04-01T00:00:00+00:00</published><updated>2017-04-01T00:00:00+00:00</updated><id>https://nimaara.com/2017/04/01/local-functions-feature</id><content type="html" xml:base="https://nimaara.com/2017/04/01/local-functions-feature.html"><![CDATA[<p><em>C# 7</em> has introduced a number of features which you can explore HERE; In this article we are going to take a look at <strong>Local Functions</strong> and why you may want to use them.</p>

<h3 id="what-are-they">What are they?</h3>

<p><em>Local Functions</em> enable the definition of functions inside other functions. You can think of them as helper functions that would only make sense within a given context. Such context could be a function, constructor or a property <em>getter</em> or <em>setter</em>. They are transformed by the compiler to <em>private</em> methods meaning there is no overhead in calling them.</p>

<p>The main goal of <em>Local Functions</em> is <em>encapsulation</em> so the compiler is enforcing that such functions cannot be called from anywhere else in the class. Consider the following overly simplified example:</p>

<pre><code class="language-csharp">public string Address
{
    get
    {
        return $@"{GetHouseNumber()}, {GetStreet()},
                  {GetCity()},
                  {GetCountry()}";

        int GetHouseNumber() =&gt; 10;
        string GetStreet() =&gt; "Liberty St";
        string GetCity() =&gt; "Amsterdam";
        string GetCountry() =&gt; "Jamaica";
    }
}
</code></pre>

<p>Here we have a <em>getter</em> property which is composing an address comprised of 4 different segments. Each segment is being retrieved via a separate method, we are also taking advantage of the <a href="https://msdn.microsoft.com/en-gb/magazine/dn802602.aspx">Expression Bodied</a> and <a href="https://msdn.microsoft.com/en-gb/magazine/dn879355.aspx">String Interpolation</a> syntax introduced as part of <em>C# 6</em> to keep our property clear and condensed.</p>

<p>Had we declared those methods as <em>private</em>, they could be invoked by any member in the class so by using <em>Local Functions</em> we have encapsulated their usage.</p>

<h3 id="but-we-could-do-this-with-lambdas-no">But we could do this with Lambdas, no?</h3>

<p>Yes, if you ignore the constraint forcing us to declare our lambdas before using them, you could technically achieve the same result:</p>

<pre><code class="language-csharp">public string Address
{
    get
    {
        Func&lt;int&gt; getHouseNumber = () =&gt; 10;
        Func&lt;string&gt; getStreet = () =&gt; "Liberty St";
        Func&lt;string&gt; getCity = () =&gt; "Amsterdam";
        Func&lt;string&gt; getCountry = () =&gt; "Jamaica";

        return $@"{getHouseNumber()}, {getStreet()},
                  {getCity()},
                  {getCountry()}";
    }
}
</code></pre>

<p><em>BUT</em>, doing so is not such a good idea for the following reasons:</p>

<ul>
  <li><strong>Allocation</strong>, By declaring those lambdas you are essentially allocating objects for the delegates on the heap so if your property is being invoked many times then you will end up putting non trivial unnecessary pressure on the <em>GC</em>.</li>
  <li><strong>No support for</strong> <code>ref</code>, <code>out</code>, <code>params</code> or <em>Optional Parameters</em>.</li>
  <li><strong>No recursion</strong>, in order to be able to call a Lambda recursively you would need to declare it in 2 steps which does not seem elegant to me:</li>
</ul>

<pre><code class="language-csharp">private uint GetFactorial(uint number)
{
    var factorial = default(Func&lt;uint, uint&gt;);
    factorial = n =&gt;
    {
        if (n &lt; 2) { return 1; }
        return n * factorial(n - 1);
    };

    return factorial(number);
}
</code></pre>

<h3 id="limitations">Limitations</h3>

<p><em>Local Functions</em> can be <em>generic</em>, <em>asynchronous</em>, <em>dynamic</em> and they can even have access to variables accessible in their enclosing scope however despite their flexibility they come with the following limitations:</p>

<ul>
  <li><strong>Cannot be static</strong>, you cannot declare a <em>Local Function</em> as static. (no longer true as of <em>C# 8</em>)</li>
  <li><strong>No attributes allowed</strong>, Unlike normal methods you cannot use attributes inside a <em>Local Function</em>. This means you cannot use <a href="https://msdn.microsoft.com/en-us/library/hh534540.aspx">Caller Information</a> so the following example does not compile:</li>
</ul>

<pre><code class="language-csharp">private void Greet()
{
    string GetCaller([CallerMemberName] string name = null) =&gt; name;
    Console.WriteLine("Hello " + GetCaller());
}
</code></pre>]]></content><author><name>Nima Ara</name></author><category term="C#" /><category term=".NET" /><summary type="html"><![CDATA[C# 7 has introduced a number of features which you can explore HERE; In this article we are going to take a look at Local Functions and why you may want to use them.]]></summary></entry><entry><title type="html">Beware of the .NET HttpClient</title><link href="https://nimaara.com/2016/11/01/beware-of-the-http-client.html" rel="alternate" type="text/html" title="Beware of the .NET HttpClient" /><published>2016-11-01T00:00:00+00:00</published><updated>2016-11-01T00:00:00+00:00</updated><id>https://nimaara.com/2016/11/01/beware-of-the-http-client</id><content type="html" xml:base="https://nimaara.com/2016/11/01/beware-of-the-http-client.html"><![CDATA[<p>In the old days of .NET (pre <em>4.5</em>) sending a HTTP request to a server could be accomplished by either using the <a href="https://msdn.microsoft.com/en-us/library/system.net.webclient(v=vs.110).aspx">WebClient</a> or at a much lower level via the <a href="https://msdn.microsoft.com/en-us/library/system.net.httpwebrequest(v=vs.110).aspx">HttpWebRequest</a>. In 2009 and as part of the <em>REST Starter Kit (RSK)</em> a new abstraction was born called the <a href="https://msdn.microsoft.com/en-us/library/system.net.http.httpclient(v=vs.118).aspx">HttpClient</a>; It took until the release of <em>.NET 4.5</em> however for it to be available to the wider audience.</p>

<p>This abstraction provides easier methods of communicating with a HTTP server in full asynchrony as well as allowing to set default headers for each and every request. This is all awesome an all but there are dark secrets about this class that if not addressed can cause serious performance and at times mind boggling bugs! In this article we will explore the <del>problems</del> <em>subtleties</em> that one would need to be aware of when working with the <code>HttpClient</code> class.</p>

<h3 id="so-whats-wrong">So what’s wrong?</h3>

<p>The <code>HttpClient</code> class implements <code>IDisposable</code> suggesting any object of this type must be disposed of after use; With that in mind, let us have a look at how I would use this class assuming that I am not aware of the problem:</p>

<pre><code class="language-csharp">Uri endpoint = new("http://localhost:1234/");
for (int i = 0; i &lt; 10; i++)
{
    using HttpClient client = new();
    string response = await client.GetStringAsync(endpoint);
    Console.WriteLine(response);
}
</code></pre>

<p>So here we are sending 10 requests to an endpoint sequentially and assuming there is a listener serving the requests on port 1234 or any other endpoint you choose to hit, you will see 10 responses written to the <code>Console</code>; This is all going well, right? <strong>WRONG!</strong></p>

<p>Let us run the command: <code>netstat -abn</code> on <em>CMD</em> which should return (depending on the endpoint you hit):</p>

<pre><code class="language-shell">...
TCP    [::1]:40968            [::1]:1234             TIME_WAIT
TCP    [::1]:40969            [::1]:1234             TIME_WAIT
TCP    [::1]:40970            [::1]:1234             TIME_WAIT
TCP    [::1]:40971            [::1]:1234             TIME_WAIT
TCP    [::1]:40972            [::1]:1234             TIME_WAIT
TCP    [::1]:40973            [::1]:1234             TIME_WAIT
TCP    [::1]:40975            [::1]:1234             TIME_WAIT
TCP    [::1]:40976            [::1]:1234             TIME_WAIT
TCP    [::1]:40977            [::1]:1234             TIME_WAIT
TCP    [::1]:40978            [::1]:1234             TIME_WAIT
...
</code></pre>

<p>What is this you ask? Well, this is showing us that our application has opened up 10 sockets to the server so <strong>one</strong> for <strong>every request</strong> but more importantly even though our application has now ended, the OS has 10 sockets still occupied and in the <em>TIME__WAIT</em> state.</p>

<p>This is due to the way <a href="https://en.wikipedia.org/wiki/Transmission_Control_Protocol">TCP/IP</a> has been designed to work as connections are not closed immediately to allow the packets to arrive out of order or re-transmitted after the connection has been closed. <em>TIMEWAIT</em> indicates that the local endpoint (the one on our side) has closed the connections but the connections are being kept around so that any delayed packets can be handled correctly. Once this happens the connections will then be removed after their timeout period of <strong>4 minutes</strong>. Remember, we sent 10 requests to the <strong>same</strong> endpoint and yet we have <strong>10 individual sockets</strong> still busy for at least 4 minutes!</p>

<p>The above example is an overly simplified one but have a look at this:</p>

<pre><code class="language-csharp">public class ProductController : ApiController
{
    public async Task&lt;Product&gt; GetProductAsync(string id)
    {
        using HttpClient httpClient = new();
        string result = await httpClient.GetStringAsync("http://somewhere/api/...");
        return new Product { Name = result };
    }
}
</code></pre>

<p>Doing this per incoming request will eventually result in <code>SocketException</code>, don’t believe me? Just run a load test, sit back and watch how many requests you can serve before you run out of sockets!</p>

<h3 id="what-can-we-do">What can we do?</h3>

<p>Well, the first obvious thing that comes to mind is reusing our client instead of creating a new one for every request but as you will see later in the post, that <strong>can cause yet another problem</strong>. Before we get to that point, let us first find out if we can even re-use a single instance. Is the <code>HTTPClient</code> thread-safe? The answer is <em>YES</em> it is, at least the following methods have been <a href="https://msdn.microsoft.com/en-us/library/system.net.http.httpclient(v=vs.110).aspx#Anchor_5">documented</a> to be thread-safe:</p>

<ul>
  <li><code>CancelPendingRequests</code></li>
  <li><code>DeleteAsync</code></li>
  <li><code>GetAsync</code></li>
  <li><code>GetByteArrayAsync</code></li>
  <li><code>GetStreamAsync</code></li>
  <li><code>GetStringAsync</code></li>
  <li><code>PostAsync</code></li>
  <li><code>PutAsync</code></li>
  <li><code>SendAsync</code></li>
</ul>

<p>However the following are not thread-safe and cannot be changed once the first request has been made:</p>

<ul>
  <li><code>BaseAddress</code></li>
  <li><code>Timeout</code></li>
  <li><code>MaxResponseContentBufferSize</code></li>
</ul>

<p>In fact on the same documentation page, under the <em>Remarks</em> section, it explains:</p>

<blockquote>
  <p><em>HttpClient</em> is intended to be instantiated once and re-used throughout the life of an application. Instantiating an HttpClient class for every request will exhaust the number of sockets available under heavy loads. This will result in <em>SocketException</em> errors.</p>
</blockquote>

<p>Okay so is that it? Create and reuse a single instance of our client and happy days? Well, <em>NO!</em> There is yet another very subtle but <strong>serious</strong> issue you may face.</p>

<h3 id="a-singleton-httpclient-does-not-respect-dns-changes">A Singleton HttpClient does not respect DNS changes</h3>

<p>Re-using an instance of <code>HttpClient</code> means that it holds on to the socket until it is closed so if you have a DNS record update occurring on the server the client will never know until that socket is closed and let me tell you DNS records change for different reasons all the time, for example a fail-over scenario is just one of them (albeit in such case the connection/socket would have faulted and closed) or an <em>Azure</em> deployment when you swap different instances e.g. <em>Production/Staging</em> in this case your client would still be hitting the old instance! In fact there is an issue on the <a href="https://github.com/dotnet/corefx/issues/11224">dotnet/corefx</a> repo about this behaviour.</p>

<p><code>HTTPClient</code> (for valid reasons) does not check the DNS records when the connection is open so how can we fix this? One <del>naive</del> easy workaround is to set the <em>keep-alive</em> header to <code>false</code> so the socket will be closed after each request, this obviously results in sub-optimal performance but if you do not care, then there is your answer; However, I think we can do better.</p>

<p>There is the lesser known <a href="https://msdn.microsoft.com/en-us/library/system.net.servicepoint(v=vs.110).aspx">ServicePoint</a> class which holds the solution to our problem. This class is responsible for managing different properties of a TCP connection and one of such properties is the <a href="https://msdn.microsoft.com/en-us/library/system.net.servicepoint.connectionleasetimeout(v=vs.110).aspx">ConnectionLeaseTimeout</a>. This guy as its name suggests specifies how long (in ms) the TCP socket can stay open. By default the value of this property is set to <strong>-1</strong> resulting in the socket staying open indefinitely (relatively speaking) so all we have to do is set it to a more realistic value:</p>

<pre><code class="language-csharp">ServicePointManager.FindServicePoint(endpoint)
    .ConnectionLeaseTimeout = (int)TimeSpan.FromMinutes(1).TotalMilliseconds;
</code></pre>

<p>The above override needs to be applied <strong>once</strong> for <strong>each endpoint</strong>. Note the method only cares about the <em>host</em>, <em>schema</em> and <em>port</em> everything else is ignored.</p>

<h3 id="almost-there">Almost There…</h3>

<p>So far we have taken care of force-closing the connections after a given period but that was just the first part. If our singleton client opens another connection it may still be pointed to the old server, why you ask? well all the DNS entries are cached which by default does not refresh for 2 minutes. So we also need to reduce the cache timeout which we can do by setting the <code>DnsRefreshTimeout</code> on the <code>ServicePointManager</code> class like so:</p>

<pre><code class="language-csharp">ServicePointManager.DnsRefreshTimeout = (int)1.Minutes().TotalMilliseconds;
</code></pre>

<p>I wanted to have a better abstraction and not have to remember to do all of this on every request, I also wanted the abstraction to implement an interface for dependency injection between my services.</p>

<h3 id="restclient">RestClient</h3>

<p><a href="https://github.com/NimaAra/Easy.Common/blob/master/Easy.Common/RestClient.cs">RestClient</a> is a thread-safe wrapper around <code>HttpClient</code> and internally keeps a cache of endpoints that it has already sent a request to and if it is asked to send a request to an endpoint it does not have in its cache, it updates the <code>ConnectionLeaseTimeout</code> for that endpoint. Here is a simple usage example:</p>

<pre><code class="language-csharp">// This is to show that IRestClient implements IDisposable
// just like HttpClient, you should not dispose it per request.
using IRestClient client = new RestClient();
await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, new Uri("http://localhost/api")));
</code></pre>

<p>Now you can safely hold on to the client and/or register it using your favorite <em>IoC</em> container and inject it where ever you require.</p>

<p>The class supports the same constructors as <code>HttpClient</code> and also provides a safe way of setting its default properties:</p>

<pre><code class="language-csharp">var defaultHeaders = new Dictionary&lt;string, string&gt;
{
    {"Accept", "application/json"},
    {"User-Agent", "foo-bar"}
};

using IRestClient client = new RestClient(defaultHeaders, timeout: 15.Seconds(), axResponseContentBufferSize: 10);
client.DefaultRequestHeaders.Count.ShouldBe(defaultHeaders.Count);
client.DefaultRequestHeaders["Accept"].ShouldBe("application/json");
client.DefaultRequestHeaders["UserAgent"].ShouldBe("foo-bar");

client.Endpoints.ShouldBeEmpty();
client.MaxResponseContentBufferSize.ShouldBe((uint)10);
client.Timeout.ShouldBe(15.Seconds());
</code></pre>

<p>The code is on <a href="https://github.com/NimaAra/Easy.Common/blob/master/Easy.Common/RestClient.cs">GitHub</a> and is available on <a href="https://www.nuget.org/packages/Easy.Common/">NuGet</a> as part of the <a href="https://github.com/NimaAra/Easy.Common">Easy.Common</a> library used in my other projects.</p>

<h3 id="update-2019">Update 2019</h3>

<p>Starting from <em>.NET Core 2.1</em>, Microsoft addressed some of the issues covered in this article by making available <a href="https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests">HttpClientFactory</a>. Despite the various features offered in this class, in my opinion, there is a little too much of ceremony involved with using this type also we would still need to deal with setting the DNS refresh timeout ourselves; Therefore, I still prefer to use <code>RestClient</code> in my projects.</p>

<p><code>HttpClient</code> was also overhauled in <em>.NET Core 2.1</em> with a rewritten <em>HttpMessageHandler</em> called <a href="https://docs.microsoft.com/en-us/dotnet/core/whats-new/dotnet-core-2-1">SocketsHttpHandler</a> which results in significant performance improvements it also introduces the <a href="https://apisof.net/catalog/System.Net.Http.SocketsHttpHandler.PooledConnectionLifetime">PooledConnectionLifetime</a> property which allows us to set the connection timeout without having to set the <code>ConnectionLeaseTimeout</code> for each endpoint.</p>

<p>As of version <a href="https://www.nuget.org/packages/Easy.Common/3.0.0">3.0.0 of Easy.Common</a>, the <code>RestClient</code> no longer needs to set the <code>ConnectionLeaseTimeout</code> when running on <em>.NET Core 2.1</em> or higher.</p>

<p>Have fun and happy <strong>REST</strong>ing.</p>

<h4 id="btw">BTW</h4>

<p>This post was inspired by <a href="http://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/">YOU’RE USING HTTPCLIENT WRONG AND IT IS DESTABILIZING YOUR SOFTWARE</a> by <a href="https://twitter.com/stimms">Simon Timms</a> and <a href="http://byterot.blogspot.co.uk/2016/07/singleton-httpclient-dns.html">Singleton HttpClient</a> by <a href="http://twitter.com/aliostad">Ali Ostad</a> as well as various great posts by <a href="http://stackoverflow.com/users/6819/darrel-miller">Darrel Miller</a>.</p>]]></content><author><name>Nima Ara</name></author><category term="C#" /><category term=".NET" /><category term="Performance" /><summary type="html"><![CDATA[In the old days of .NET (pre 4.5) sending a HTTP request to a server could be accomplished by either using the WebClient or at a much lower level via the HttpWebRequest. In 2009 and as part of the REST Starter Kit (RSK) a new abstraction was born called the HttpClient; It took until the release of .NET 4.5 however for it to be available to the wider audience.]]></summary></entry><entry><title type="html">High Resolution Clock in .NET</title><link href="https://nimaara.com/2016/07/06/high-resolution-clock-in-net.html" rel="alternate" type="text/html" title="High Resolution Clock in .NET" /><published>2016-07-06T00:00:00+00:00</published><updated>2016-07-06T00:00:00+00:00</updated><id>https://nimaara.com/2016/07/06/high-resolution-clock-in-net</id><content type="html" xml:base="https://nimaara.com/2016/07/06/high-resolution-clock-in-net.html"><![CDATA[<p>Obtaining high resolution time requires a clock which is both <em>precise</em> as well as <em>accurate</em> and those are different things. As <em>Eric Lippert</em> explains:</p>

<blockquote>
  <p>A stopped clock is exactly accurate twice a day, a clock a minute slow is never accurate at any time. But the clock a minute slow is always precise to the nearest minute, whereas a stopped clock has no useful precision at all.</p>
</blockquote>

<p>So we <a href="https://blogs.msdn.microsoft.com/ericlippert/2010/04/08/precision-and-accuracy-of-datetime/">know</a> that <code>DateTime</code> in .NET is very precise. why? well it is represented as a <code>struct</code> which internally keeps track of the number of <em>ticks</em> since a particular start date and those ticks are represented as a 64 bit number; And just for the context, 1 tick equals 100 nanoseconds and every second equals to <em>10,000,000</em> ticks so with such structure one could theoretically represent sub-microsecond times.</p>

<p>Of course having a precise <code>DateTime</code> is not all the story let us think about it for a second, I can represent the distance between point A and B as a high-precision floating point by using a <code>double</code> for example: <em>156.34214233234517974</em> meters but do I really have a method of measuring that distance to such accuracy? The same goes for <code>DateTime</code>; <a href="http://stackoverflow.com/a/19736972/1226568">Hans Passant</a> explains:</p>

<blockquote>
  <p><code>DateTime.UtcNow</code> is accurate to <strong>15.625</strong> milliseconds and stable over very long periods thanks to the time service updates. Going lower than that just doesn’t make much sense, you can’t get the execution guarantee you need in user mode to take advantage of it.</p>

  <p>You need lots of bigger tricks to get it accurate down to a millisecond. You can only get a guarantee like that for code that runs in kernel mode, running at interrupt priority so it cannot get pre-empted by other code and with its code and data pages page-locked so it can’t get hit with page faults Commercial solutions use a GPS radio to read the clock signal of the GPS satellites, backed up by an oscillator that runs in an oven to provide temperature stability.</p>
</blockquote>

<h3 id="how-accurate-is-datetime">How accurate is DateTime?</h3>

<p>With all of the above in mind and remembering that obtaining a time matching an atomic clock is almost impossible, we can start by measuring the (relative) accuracy of <code>DateTime.UtcNow</code> by:</p>

<pre><code class="language-csharp">var duration = TimeSpan.FromSeconds(5);
var distinctValues = new HashSet&lt;DateTime&gt;();
var stopWatch = Stopwatch.StartNew();

while (stopWatch.Elapsed &lt; duration)
{
    distinctValues.Add(DateTime.UtcNow);
}

Console.WriteLine("Samples: " + distinctValues.Count);
Console.WriteLine($"Accuracy: {stopWatch.Elapsed.TotalMilliseconds / distinctValues.Count:0.000000} ms");
</code></pre>

<p>he code above is telling us how many times <code>DateTime.UtcNow</code> is giving us distinct values in a period of 5 seconds which is the same as showing us how many times its value was updated in that period.</p>

<p>Running the code on my laptop returns:</p>

<pre><code class="language-shell">Samples: 320
Accuracy: 15.625348 ms
</code></pre>

<p>And on my server:</p>

<pre><code class="language-shell">Samples: 4980
Accuracy: 1.005322 ms
</code></pre>

<p>Both machines are running <code>Windows Server 2012</code> but as you saw one is more accurate than the other so it seems the accuracy depends on the hardware as well as software as we will cover shortly.</p>

<h3 id="can-we-get-more-accurate">Can we get more accurate?</h3>

<p>Absolutely! We are going to get some help from <code>StopWatch</code> which has a very high resolution and it is going to help us manually tune our <code>DateTime</code> in order to achieve a much higher accuracy.</p>

<p>The idea is to start with a base time using <code>DateTime</code> and then every time we need to obtain the value of current time we use the <code>Stopwatch</code> to supplement our base time. All good? not really!</p>

<p>One slight problem with <code>Stopwatch</code> is that after a while (30 minutes) it can get out of sync meaning it can get too far from the system time so in order compensate for that we need to reset our start time every let’s say 10 seconds. Sounds complicated? not really, here is the code:</p>

<pre><code class="language-csharp">public sealed class Clock
{
    private readonly long _maxIdleTime = TimeSpan.FromSeconds(10).Ticks;
    private const long TicksMultiplier = 1000 * TimeSpan.TicksPerMillisecond;

    private DateTime _startTime = DateTime.UtcNow;
    private double _startTimestamp = Stopwatch.GetTimestamp();

    public DateTime UtcNow
    {
        get
        {
            double endTimestamp = Stopwatch.GetTimestamp();

            var durationInTicks = (endTimestamp - _startTimestamp) / Stopwatch.Frequency * TicksMultiplier;
            if (durationInTicks &gt;= _maxIdleTime)
            {
                _startTimestamp = Stopwatch.GetTimestamp();
                _startTime = DateTime.UtcNow;
                return _startTime;
            }

            return _startTime.AddTicks((long)durationInTicks);
        }
    }
}
</code></pre>

<p>So let us run our test again to measure how accurate our hybrid clock is:</p>

<pre><code class="language-csharp">var clock = new Clock();
var duration = TimeSpan.FromSeconds(5);
var distinctValues = new HashSet&lt;DateTime&gt;();
var stopWatch = Stopwatch.StartNew();

while (stopWatch.Elapsed &lt; duration)
{
    distinctValues.Add(clock.UtcNow);
}

Console.WriteLine("Samples: " + distinctValues.Count);
Console.WriteLine($"Accuracy: {stopWatch.Elapsed.TotalMilliseconds / distinctValues.Count:0.000000} ms");
</code></pre>

<p>Which gives us:</p>

<pre><code class="language-shell">Samples: 11469019
Accuracy: 0.000436 ms
</code></pre>

<p>Great! so can you go and start using this code? Yes and No! you see this code is not thread-safe so if you are planning on using it in a multi-threaded scenario then continue reading….</p>

<h3 id="making-it-thread-safe">Making it thread-safe</h3>

<p>We can easily make our clock thread-safe by using <code>ThreadLocal</code>. This guy allows each thread to have its own instance of the <code>_startTime</code> and <code>_startTimestamp</code> instead of having to resort to a <em>lock</em>. So the modified clock now looks like:</p>

<pre><code class="language-csharp">public sealed class Clock : IDisposable
{
    private readonly long _maxIdleTime = TimeSpan.FromSeconds(10).Ticks;
        private const long TicksMultiplier = 1000 * TimeSpan.TicksPerMillisecond;

    private readonly ThreadLocal&lt;DateTime&gt; _startTime =
        new ThreadLocal&lt;DateTime&gt;(() =&gt; DateTime.UtcNow, false);

    private readonly ThreadLocal&lt;double&gt; _startTimestamp =
        new ThreadLocal&lt;double&gt;(() =&gt; Stopwatch.GetTimestamp(), false);

    public DateTime UtcNow
    {
        get
        {
            double endTimestamp = Stopwatch.GetTimestamp();

            var durationInTicks = (endTimestamp - _startTimestamp.Value) / Stopwatch.Frequency * TicksMultiplier;
            if (durationInTicks &gt;= _maxIdleTime)
            {
                _startTimestamp.Value = Stopwatch.GetTimestamp();
                _startTime.Value = DateTime.UtcNow;
                return _startTime.Value;
            }

            return _startTime.Value.AddTicks((long)durationInTicks);
        }
    }

    public void Dispose()
    {
        _startTime.Dispose();
        _startTimestamp.Dispose();
    }
}
</code></pre>

<p>Is that it? well, yes but….!</p>

<h3 id="can-we-do-better">Can we do better?</h3>

<p>Starting from <em>Windows 8</em> and <em>Windows Server 2012</em>, Microsoft has made available for us a very nice API. That API is <code>GetSystemTimePreciseAsFileTime</code>. This method obtains the current system time with the highest possible level of precision (we are talking about <em>&lt;1us</em>); Why not take advantage of this method in our hybrid clock.</p>

<p>The final version of our clock now looks like:</p>

<pre><code class="language-csharp">/// &lt;summary&gt;
/// This class provides a high resolution clock by using the new API available in &lt;c&gt;Windows 8&lt;/c&gt;/
/// &lt;c&gt;Windows Server 2012&lt;/c&gt; and higher. In all other operating systems it returns time by using
/// a manually tuned and compensated &lt;c&gt;DateTime&lt;/c&gt; which takes advantage of the high resolution
/// available in &lt;see cref="Stopwatch"/&gt;.
/// &lt;/summary&gt;
public sealed class Clock : IDisposable
{
    private readonly long _maxIdleTime = TimeSpan.FromSeconds(10).Ticks;
    private const long TicksMultiplier = 1000 * TimeSpan.TicksPerMillisecond;

    private readonly ThreadLocal&lt;DateTime&gt; _startTime =
        new ThreadLocal&lt;DateTime&gt;(() =&gt; DateTime.UtcNow, false);

    private readonly ThreadLocal&lt;double&gt; _startTimestamp =
        new ThreadLocal&lt;double&gt;(() =&gt; Stopwatch.GetTimestamp(), false);


    [DllImport("Kernel32.dll", CallingConvention = CallingConvention.Winapi)]
    private static extern void GetSystemTimePreciseAsFileTime(out long filetime);

    /// &lt;summary&gt;
    /// Creates an instance of the &lt;see cref="Clock"/&gt;.
    /// &lt;/summary&gt;
    public Clock()
    {
        try
        {
            long preciseTime;
            GetSystemTimePreciseAsFileTime(out preciseTime);
            IsPrecise = true;
        } catch (EntryPointNotFoundException)
        {
            IsPrecise = false;
        }
    }

    /// &lt;summary&gt;
    /// Gets the flag indicating whether the instance of &lt;see cref="Clock"/&gt; provides high resolution time.
    /// &lt;remarks&gt;
    /// &lt;para&gt;
    /// This only returns &lt;c&gt;True&lt;/c&gt; on &lt;c&gt;Windows 8&lt;/c&gt;/&lt;c&gt;Windows Server 2012&lt;/c&gt; and higher.
    /// &lt;/para&gt;
    /// &lt;/remarks&gt;
    /// &lt;/summary&gt;
    public bool IsPrecise { get; }

    /// &lt;summary&gt;
    /// Gets the date and time in &lt;c&gt;UTC&lt;/c&gt;.
    /// &lt;/summary&gt;
    public DateTime UtcNow
    {
        get
        {
            if (IsPrecise)
            {
                long preciseTime;
                GetSystemTimePreciseAsFileTime(out preciseTime);
                return DateTime.FromFileTimeUtc(preciseTime);
            }

            double endTimestamp = Stopwatch.GetTimestamp();

            var durationInTicks = (endTimestamp - _startTimestamp.Value) / Stopwatch.Frequency * TicksMultiplier;
            if (durationInTicks &gt;= _maxIdleTime)
            {
                _startTimestamp.Value = Stopwatch.GetTimestamp();
                _startTime.Value = DateTime.UtcNow;
                return _startTime.Value;
            }

            return _startTime.Value.AddTicks((long)durationInTicks);
        }
    }

    /// &lt;summary&gt;
    /// Releases all resources used by the instance of &lt;see cref="Clock"/&gt;.
    /// &lt;/summary&gt;
    public void Dispose()
    {
        _startTime.Dispose();
        _startTimestamp.Dispose();
    }
}
</code></pre>

<p>Now we are done!</p>]]></content><author><name>Nima Ara</name></author><category term="C#" /><category term=".NET" /><category term="Performance" /><summary type="html"><![CDATA[Obtaining high resolution time requires a clock which is both precise as well as accurate and those are different things. As Eric Lippert explains:]]></summary></entry><entry><title type="html">How to obtain the framework version of a .NET assembly</title><link href="https://nimaara.com/2016/06/23/how-to-obtain-framework-version-of-assembly.html" rel="alternate" type="text/html" title="How to obtain the framework version of a .NET assembly" /><published>2016-06-23T00:00:00+00:00</published><updated>2016-06-23T00:00:00+00:00</updated><id>https://nimaara.com/2016/06/23/how-to-obtain-framework-version-of-assembly</id><content type="html" xml:base="https://nimaara.com/2016/06/23/how-to-obtain-framework-version-of-assembly.html"><![CDATA[<p>If you have ever wondered what version of the .NET framework a given assembly has been built against this post may be of some help.</p>

<p>When working on any application, I have the habit of logging as much information as possible not just about the process but also about the assemblies which the process is referencing and one important part of such information is the version of .NET framework the assembly has been built for e.g. <em>.NET 2</em>, <em>.NET 4.5.1</em> etc. Note this is different from the run-time version.</p>

<h3 id="the-not-so-accurate">The not so accurate</h3>

<p>If you look at the assembly object you can find the <em>ImageRuntimeVersion</em> property which gets you the string representation of the <em>CLR</em> saved in the file containing the assembly manifest (which by the way you can view by using a decompiler such as <em>ILSpy</em> or <em>dotPeek</em>) however, this is not accurate as I explain below.</p>

<h3 id="the-problem">The problem</h3>

<p>The <em>ImageRuntimeVersion</em> property returns either <em>.NET 2.0</em> or <em>.NET 4.0</em> regardless of what framework version you have built your assembly against; Meaning that if you have an assembly built in VisualStudio to target <em>.NET 4.5.1</em>, the value returned by the ImageRuntimeVersion is <em>.NET 4.0</em>. Not so helpful is it.</p>

<h3 id="what-do-we-do">What do we do?</h3>

<p>There is <em>some</em> hope otherwise why write this article!? Assemblies targeting <em>.NET 4</em> and above are marked with the <code>TargetFrameworkAttribute</code> which conveniently includes the target framework we are after. This of course means that if your assembly is targeting a framework version less than <em>.NET 4</em> i.e. <em>.NET 2</em>, <em>3</em> and <em>3.5</em>, then as far as I am aware you are out of luck!</p>

<p>So armed with that knowledge one can obtain the version by calling an extension method such as:</p>

<pre><code class="language-csharp">public static string GetFrameworkVersion(this Assembly assembly)
{
    var targetFrameAttribute = assembly.GetCustomAttributes(true)
        .OfType&lt;TargetFrameworkAttribute&gt;().FirstOrDefault();
    if (targetFrameAttribute == null)
    {
        return ".NET 2, 3 or 3.5";
    }

    return targetFrameAttribute.FrameworkDisplayName.Replace(".NET Framework", ".NET");
}
</code></pre>]]></content><author><name>Nima Ara</name></author><category term="C#" /><category term=".NET" /><summary type="html"><![CDATA[If you have ever wondered what version of the .NET framework a given assembly has been built against this post may be of some help.]]></summary></entry><entry><title type="html">Beware of the IDictionary&amp;lt;TKey, TValue&amp;gt;</title><link href="https://nimaara.com/2016/03/06/beware-of-the-idictionary.html" rel="alternate" type="text/html" title="Beware of the IDictionary&amp;lt;TKey, TValue&amp;gt;" /><published>2016-03-06T00:00:00+00:00</published><updated>2016-03-06T00:00:00+00:00</updated><id>https://nimaara.com/2016/03/06/beware-of-the-idictionary</id><content type="html" xml:base="https://nimaara.com/2016/03/06/beware-of-the-idictionary.html"><![CDATA[<h3 id="background">Background</h3>

<p>As it is the case in most scenarios the source of latency is usually due to the .NET <em>Garbage Collection</em>, so we always try very hard to minimize object allocations specially in our performance-critical components.</p>

<p>We have a messaging API which is used by many of our micro services. Some of those services use the API to publish thousands of messages per second to the market so it is important to keep the latency as low as possible.</p>

<p>In my quest to reduce latency and CPU consumption of our components, I came across a very interesting and probably not so well known performance gotcha!</p>

<h3 id="problem">Problem</h3>

<p>The API has a method which accepts an <code>IDictionary&lt;string, string&gt;</code> and publishes them to a message bus like so:</p>

<pre><code class="language-csharp">public void Publish(IDictionary&lt;string, string&gt; data)
{
    foreach (var item in data)
    {
        _publisher.Publish(item);
    }
}
</code></pre>

<p>Nothing really complicated right? <strong>WRONG!</strong></p>

<h3 id="what-is-going-on">What is going on?</h3>

<p>Let’s do a quick and dirty profiling of an even simpler example:</p>

<pre><code class="language-csharp">void Main()
{
    Dictionary&lt;int, int&gt; dic = new();

    var sw = Stopwatch.StartNew();
    for (var i = 0; i &lt; 100000000; i++)
    {
        foreach (var item in dic) { ; }
    }
    sw.Stop();

    // compose the result
    StringBuilder result = new();
    result.AppendFormat("[Time]\t{0}", sw.Elapsed);
    result.AppendLine();
    result.AppendFormat("[Gen-0]\t{0}", GC.CollectionCount(0));
    result.AppendLine();
    result.AppendFormat("[Gen-1]\t{0}", GC.CollectionCount(1));
    result.AppendLine();
    result.AppendFormat("[Gen-2]\t{0}", GC.CollectionCount(2));

    Console.WriteLine(result.ToString());
}
</code></pre>

<p>What we have here is an empty dictionary where both the keys and values are of type <code>int</code>. We are then simply enumerating the dictionary a <strong>hundred million</strong> times. Note we are not doing anything in the body of the <em>foreach</em> so that we can focus only on the enumeration.</p>

<p>Finally, we record the total time it took for the enumeration as well as the number of times <em>GC</em> performed collections of our <em>GEN 0</em> to <em>GEN 2</em>. Running the above on a machine with a <em>Quad-Core 3.4GHz and 8GB of RAM</em> prints:</p>

<pre><code class="language-shell">[Time]  00:00:01.8128806
[Gen-0] 0
[Gen-1] 0
[Gen-2] 0
</code></pre>

<p>So it took almost <strong>2 seconds</strong> and resulted in no garbage collection, so far so good. Now let us try again but this time change our <em>dic</em> pointer to an <code>IDictionary&lt;int, int&gt;</code> instead:</p>

<pre><code class="language-csharp">... same as above
    IDictionary&lt;int, int&gt; dic = new Dictionary&lt;int, int&gt;();
... same as above
</code></pre>

<p>Which prints:</p>

<pre><code class="language-shell">[Time]  00:00:04.3902405
[Gen-0] 765
[Gen-1] 2
[Gen-2] 1
</code></pre>

<p>This time it took more than twice than enumerating a <code>Dictionary&lt;int, int&gt;</code> and resulted in <strong>765</strong> collections of <em>GEN 0</em>, <strong>2</strong> collections of <em>GEN 1</em> and <strong>1</strong> collection of <em>GEN 2</em>. This is <strong>MADNESS!</strong></p>

<p style="text-align: center;"><img alt="picture of homer simpson screaming" src="https://i.imgur.com/DuChpLR.gif?1" /></p>

<h3 id="and-here-is-why">And here is why</h3>

<p>Let us look at the <em>IL</em> generated in the case when we are using a <code>Dictionary&lt;int, int&gt;</code>:</p>

<pre><code class="language-csharp">... not important
IL_0013:  ldloc.0     // dic
IL_0014:  callvirt    System.Collections.Generic.Dictionary&lt;System.Int32,System.Int32&gt;.GetEnumerator
IL_0019:  stloc.s     04
IL_001B:  br.s        IL_0029
IL_001D:  ldloca.s    04
IL_001F:  call        System.Collections.Generic.Dictionary&lt;System.Int32,System.Int32&gt;+Enumerator.get_Current
IL_0024:  stloc.s     05 // item
...
IL_0029:  ldloca.s    04
IL_002B:  call        System.Collections.Generic.Dictionary&lt;System.Int32,System.Int32&gt;+Enumerator.MoveNext
IL_0030:  brtrue.s    IL_001D
IL_0032:  leave.s     IL_0043
IL_0034:  ldloca.s    04
IL_0036:  constrained. System.Collections.Generic.Dictionary&lt;,&gt;.Enumerator
... not important
</code></pre>

<p>Here we can see a call to <code>System.Collections.Generic.Dictionary&lt;System.Int32,System.Int32&gt;+Enumerator.get_Current</code> to get the current <code>Enumerator</code> and on every iteration we have a call to <code>System.Collections.Generic.Dictionary&lt;System.Int32,System.Int32&gt;+Enumerator.MoveNext</code> to move the <code>Enumerator</code> forward.</p>

<p>Let us compare that with the <em>IL</em> for the case of an <code>IDictionary&lt;int, int&gt;</code>:</p>

<pre><code class="language-csharp">... not important
IL_0013:  ldloc.0     // dic
IL_0014:  callvirt    System.Collections.Generic.IEnumerable&lt;System.Collections.Generic.KeyValuePair&lt;System.Int32,System.Int32&gt;&gt;.GetEnumerator
IL_0019:  stloc.s     04
IL_001B:  br.s        IL_0029
IL_001D:  ldloc.s     04
IL_001F:  callvirt    System.Collections.Generic.IEnumerator&lt;System.Collections.Generic.KeyValuePair&lt;System.Int32,System.Int32&gt;&gt;.get_Current
IL_0024:  stloc.s     05 // item
...
IL_0029:  ldloc.s     04
IL_002B:  callvirt    System.Collections.IEnumerator.MoveNext
IL_0030:  brtrue.s    IL_001D
IL_0032:  leave.s     IL_0041
... not important
</code></pre>

<p>Very interesting! This time we have a <code>callvirt</code> to <code>System.Collections.Generic.IEnumerable&lt;System.Collections.Generic.KeyValuePair&lt;System.Int32,System.Int32&gt;&gt;.GetEnumerator</code> followed by more <code>callvirt</code> to <code>System.Collections.Generic.IEnumerator</code>.</p>

<p>Aha! Allow me to explain in case it is not that obvious.</p>

<h3 id="virtual-call--interface-dispatch">Virtual Call / Interface Dispatch</h3>

<p>The first issue is the <em>Interface Dispatch</em> (the parts that do a non-inlineable <code>callvirt</code> to <code>System.Collections.Generic.IEnumerator</code>) which is in contrast to the case of <code>Dictionary&lt;int, int&gt;</code> where we are doing fast, non-virtual and inlineable calls.</p>

<h3 id="boxing">Boxing</h3>

<p>The second issue and by far the most significant performance hit is due to _<em>boxing</em>. Instead of returning a <code>Dictionary&lt;int, int&gt;.Enumerator</code>, we are boxing the <code>struct</code> and return an <code>IEnumerator&lt;KeyValuePair&lt;int, int&gt;&gt;</code> which explains the high number of <em>GC</em> collections across our heap.</p>

<p style="text-align: center;">
<img alt="picture of sherlock holmes smoking a pipe" src="https://i.imgur.com/nVrH5Nk.jpg" />
</p>

<h3 id="how-about-ilist-ireadonlylist-icollection--ienumerable-vs-list">How about IList<T>, IReadOnlyList<T>, ICollection<T> &amp; IEnumerable<T> vs List<T>?</T></T></T></T></T></h3>

<p><code>IList&lt;T&gt;</code> and <code>IReadOnlyList&lt;T&gt;</code> implement <code>ICollection&lt;T&gt;</code> which in turn implements <code>IEnumerable&lt;T&gt;</code> and therefore using any of those interfaces for the enumeration incurs the similar performance cost we covered above.</p>

<p>This is even more clear if you look at the source of <code>List&lt;T&gt;</code>:</p>

<pre><code class="language-csharp">public Enumerator GetEnumerator() =&gt; new Enumerator(this);

IEnumerator&lt;T&gt; IEnumerable&lt;T&gt;.GetEnumerator() =&gt; new Enumerator(this);

System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() =&gt; new Enumerator(this);
</code></pre>

<p>You can see in the last two <code>GetEnumerator()</code>s the <code>Enumerator struct</code> is being boxed to a generic an a non generic <code>IEnumerator</code>.</p>

<h3 id="summary">Summary</h3>

<p>It is a good idea to abstract yourself from an implementation, by that I mean programming against an interface rather than a concrete implementation <em>however</em> there are times where this can have a performance impact and what we covered in this article was one of such examples. In our case the problem was fixed by simply switching to a <code>Dictionary&lt;string, string&gt;</code> which is the cost we are prepared to pay in return of a more efficient API.</p>]]></content><author><name>Nima Ara</name></author><category term="C#" /><category term=".NET" /><category term="GC" /><category term="Performance" /><summary type="html"><![CDATA[Background]]></summary></entry></feed>