<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.3">Jekyll</generator><link href="http://axcoder.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="http://axcoder.github.io/" rel="alternate" type="text/html" /><updated>2023-06-10T20:59:01+00:00</updated><id>http://axcoder.github.io/feed.xml</id><title type="html">Max Belugin</title><subtitle>C# dev</subtitle><entry><title type="html">Puzzler with structs, generics and nullability</title><link href="http://axcoder.github.io/Structs-Puzzler/" rel="alternate" type="text/html" title="Puzzler with structs, generics and nullability" /><published>2023-06-10T00:00:00+00:00</published><updated>2023-06-10T00:00:00+00:00</updated><id>http://axcoder.github.io/Structs-Puzzler</id><content type="html" xml:base="http://axcoder.github.io/Structs-Puzzler/">&lt;p&gt;Recently I found a non-obvious behavior of combining structs with nullability.&lt;/p&gt;

&lt;p&gt;All code for this post is available at my &lt;a href=&quot;https://github.com/AxCoder/Examples/tree/main/StructsAndNullable&quot;&gt;GitHub&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;the-puzzler&quot;&gt;The puzzler&lt;/h2&gt;

&lt;p&gt;Let’s say we want to write a generic transform function for nullable:&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Transform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TSource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;TSource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TSource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;transformation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;source&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;transformation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It gets a nullable argument, a transformation (function that gets an argument and returns a result) and applies transformation if argument is not null. Otherwise, it returns null.&lt;/p&gt;

&lt;p&gt;It works great until you try to apply this to some value type, say DateTime:&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;DateTime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;source&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;DateTime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NullableStructsTransformer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Transform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddDays&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You are getting the following:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Severity	Code	Description	Project	File	Line	Suppression State
Error	CS1061	‘DateTime?’ does not contain a definition for ‘AddDays’ and no accessible extension method ‘AddDays’ accepting a first argument of type ‘DateTime?’ could be found&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ok you are are adding an overload with struct constrain and it compiles:&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Transform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TSource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;TSource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TSource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;transformation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TSource&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// &amp;lt;-- This one&lt;/span&gt;
        &lt;span class=&quot;err&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;source&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;transformation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;But… it does not work. For non-null values it return transformed values, but for nulls it returns default values.
For example, for dates it returns &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;0001-01-01 00:00:00.000&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The following test fails:&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Fact&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Transform_IfNullStruct_ReturnsNull&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;DateTime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;source&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;DateTime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NullableStructsTransformer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Transform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddDays&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Should&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;BeNull&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;blockquote&gt;
  &lt;p&gt;Did not expect result to have a value, but found &amp;lt;0001-01-01 00:00:00.000&amp;gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;the-fix&quot;&gt;The fix&lt;/h2&gt;

&lt;p&gt;The fixed version is below&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TransformFixed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TSource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;TSource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TSource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;transformation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TSource&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TResult&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// &amp;lt;-- Add constraint on result&lt;/span&gt;
        &lt;span class=&quot;err&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;source&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// &amp;lt;-- Specify  return type&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;transformation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;the-explanation&quot;&gt;The explanation&lt;/h2&gt;

&lt;p&gt;Lets insert our code into &lt;a href=&quot;https://sharplab.io/&quot;&gt;sharplab&lt;/a&gt; to compare:&lt;/p&gt;

&lt;p&gt;Not working version:&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Runtime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CompilerServices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Nullable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TResult&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Transform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TSource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Runtime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CompilerServices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Nullable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Nullable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TSource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Runtime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CompilerServices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Nullable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;})]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TSource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;transformation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TSource&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt;
    &lt;span class=&quot;err&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HasValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;transformation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Working version:&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Nullable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TransformFixed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TSource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Nullable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TSource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Runtime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CompilerServices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Nullable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;})]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TSource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;transformation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TSource&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TResult&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt;
    &lt;span class=&quot;err&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HasValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Nullable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;transformation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;.NET have two nullable types implementations:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;reference nullable type&lt;/li&gt;
  &lt;li&gt;value nullable types&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first kind is not a true .net runtime type, but just an attribute + compiler support.&lt;/p&gt;

&lt;p&gt;The second kind is a &lt;a href=&quot;https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1&quot;&gt;struct wrapper&lt;/a&gt; around value.&lt;/p&gt;

&lt;p&gt;When compiler does not know whether result will be value type or not it generates a generic method which returns a result, but marked with nullable attribute. Which works with reference types (since they are always nullable from runtime standpoint), but produces a strange hybrid in case of value types: struct marked with a nullable attribute instead of Nullable&amp;lt;T&amp;gt; for struct.&lt;/p&gt;

&lt;p&gt;So actually, instead of default(TResult?) in case of struct it produces default(TResult) which is empty value.&lt;/p&gt;

&lt;h2 id=&quot;further-steps&quot;&gt;Further steps&lt;/h2&gt;

&lt;p&gt;We have two versions: 1st one to transform structs to reference types; 2nd one to transform structs to structs.&lt;/p&gt;

&lt;p&gt;If somebody accidentally uses 1st version instead of second, we can have compiled code with a problem which will be found in runtime.&lt;/p&gt;

&lt;p&gt;Fortunately, we can prevent it easily: just add&lt;/p&gt;
&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;into type constraints of the first version.&lt;/p&gt;

&lt;p&gt;All code for this post is available at my &lt;a href=&quot;https://github.com/AxCoder/Examples/tree/main/StructsAndNullable&quot;&gt;GitHub&lt;/a&gt;&lt;/p&gt;</content><author><name></name></author><summary type="html">Recently I found a non-obvious behavior of combining structs with nullability.</summary></entry><entry><title type="html">Perfview in Dyn365FO. Part 5 - How to analyze X++ traces in perfview.</title><link href="http://axcoder.github.io/Perfview-How-to-analyze-xpp-etl/" rel="alternate" type="text/html" title="Perfview in Dyn365FO. Part 5 - How to analyze X++ traces in perfview." /><published>2021-05-22T00:00:00+00:00</published><updated>2021-05-22T00:00:00+00:00</updated><id>http://axcoder.github.io/Perfview-How-to-analyze-xpp-etl</id><content type="html" xml:base="http://axcoder.github.io/Perfview-How-to-analyze-xpp-etl/">&lt;p&gt;You can use PerfView for X++ traces analysis in troubleshooting scenarios.&lt;/p&gt;

&lt;p&gt;See the &lt;a href=&quot;/Perfview-in-dyn365fo/&quot;&gt;First part&lt;/a&gt; for the introduction and a list of posts.&lt;/p&gt;

&lt;h3 id=&quot;introduction&quot;&gt;Introduction&lt;/h3&gt;

&lt;p&gt;Dynamic 365 for Finance and Operations uses &lt;a href=&quot;https://docs.microsoft.com/en-us/windows/win32/etw/event-tracing-portal&quot;&gt;ETW&lt;/a&gt; technology for doing it’s own traces.&lt;/p&gt;

&lt;p&gt;Compiler generates code that inserts an event before and after each method call. Also database engine reports all queries as ETW events.&lt;/p&gt;

&lt;p&gt;Traces can be &lt;a href=&quot;https://docs.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/perf-test/trace-trace-tutorial&quot;&gt;collected&lt;/a&gt; from UI or by using Trace Parser.&lt;/p&gt;

&lt;p&gt;After that it can be opened in trace parser for analysis. Trace parser provides list of events, tree of calls and list of SQL queries.&lt;/p&gt;

&lt;p&gt;That works good. But in some trouble shooting scenarios it can be usefule to search across events. In that case we can use Perfview.&lt;/p&gt;

&lt;h3 id=&quot;how-to-use-perfview&quot;&gt;How to use PerfView&lt;/h3&gt;

&lt;p&gt;We can open eny ETL in PerfView since it shares the same ETW technology with TraceParser.&lt;/p&gt;

&lt;p&gt;Unfortunately, we cannot use stack viewer for X++ methods in this trace (you can use perfview to collect &lt;a href=&quot;/Perfview-in-dyn365fo/&quot;&gt;.NET trace&lt;/a&gt; ) though, but we can use this tool so see event sequence.&lt;/p&gt;

&lt;h4 id=&quot;opening-trace&quot;&gt;Opening trace&lt;/h4&gt;

&lt;p&gt;Do the following steps on a machine with Dyn365FO installed:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/perfview-opening-xpp-trace.png&quot; alt=&quot;Opening X++ trace&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Launch PerfView and navigate to a folder&lt;/li&gt;
  &lt;li&gt;Double click “events”&lt;/li&gt;
  &lt;li&gt;Select all event types at the left:
    &lt;ul&gt;
      &lt;li&gt;Click on any event type&lt;/li&gt;
      &lt;li&gt;Presss Ctrl+A&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Press F5 to refresh&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;analysing-trace&quot;&gt;Analysing trace&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;/assets/perfview-events-view.png&quot; alt=&quot;Perfview events view&quot; /&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Setup columns to display:
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FormattedMessage methodName sqlStatement *&lt;/code&gt; (where * means “all other columns” )&lt;/li&gt;
  &lt;li&gt;Filter events by text. Unfortunately Perfview shows limited number of events (MaxRet input box). We can reduce number of viewed events by:
    &lt;ul&gt;
      &lt;li&gt;excluding event types from the left pane&lt;/li&gt;
      &lt;li&gt;filtering by text (Text Filter)&lt;/li&gt;
      &lt;li&gt;limiting by time range (Start, End)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;After finding a time range where happens something that we are interested in, we can remove Text Filter and set Start and End instead.&lt;/li&gt;
  &lt;li&gt;We can also use text filter to filter by activity id (since TraceParser catches all the session on the same AOS).&lt;/li&gt;
&lt;/ol&gt;</content><author><name></name></author><summary type="html">You can use PerfView for X++ traces analysis in troubleshooting scenarios.</summary></entry><entry><title type="html">Perfview in Dyn365FO. Part 4 - Bottom up analysis</title><link href="http://axcoder.github.io/Perfview-bottom-up-analysis/" rel="alternate" type="text/html" title="Perfview in Dyn365FO. Part 4 - Bottom up analysis" /><published>2019-05-19T00:00:00+00:00</published><updated>2019-05-19T00:00:00+00:00</updated><id>http://axcoder.github.io/Perfview-bottom-up-analysis</id><content type="html" xml:base="http://axcoder.github.io/Perfview-bottom-up-analysis/">&lt;p&gt;How to find hot spots in your code.&lt;/p&gt;

&lt;p&gt;See the &lt;a href=&quot;/Perfview-in-dyn365fo/&quot;&gt;First part&lt;/a&gt; for the introduction and a list of posts.&lt;/p&gt;

&lt;h3 id=&quot;overall-plan&quot;&gt;Overall plan&lt;/h3&gt;

&lt;p&gt;When I do a bottom-up analysis the questions I am intereted in are the following:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;What resource is the bottleneck&lt;/strong&gt; – this one was discussed in previous post&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;What parts of my code eat most time/CPU&lt;/strong&gt; – so I can optimize them or reduce their usage&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;What parts of underlying platform consume most of resources&lt;/strong&gt; - I can not change them directly, but I can reduce their usage or change this usage somehow or ask an owner to optimize that code.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So, most time I do the bottom up analysis then I do the top down analysis of a hotspot then I decide how to optimize it.&lt;/p&gt;

&lt;h3 id=&quot;how-to-find-a-hot-spot&quot;&gt;How to find a hot spot&lt;/h3&gt;

&lt;p&gt;Actually I am inetested in 2 levels:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;My code (code I can change directly)&lt;/li&gt;
  &lt;li&gt;Code I call&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;PerfView can show very deep details of code execution, including windows kernel functions and ODBC calls, but for quickly finding bottleneck these details are too many.&lt;/p&gt;

&lt;p&gt;Fortunately, the tool have 2 very powerfull features: &lt;em&gt;grouping&lt;/em&gt; and &lt;em&gt;folding&lt;/em&gt;:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Grouping&lt;/strong&gt; allows to combine data from several calls into one (for example, you can summarize calls by class name and have total time for calls of specific class).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Folding&lt;/strong&gt; allows distribute statistics of some kind of calls to usages. For example, if I see that on the top of statistics there is some common operation like adding strings, I can fold it to see the whole picture - calls of this operation will receive it’s time and operation will disappear from view.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Therefore:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;If I want to see statictics of the bottom level of &lt;strong&gt;my&lt;/strong&gt; code, I:
    &lt;ul&gt;
      &lt;li&gt;group modules of my interest by functions&lt;/li&gt;
      &lt;li&gt;all other code group to a single path “Other”&lt;/li&gt;
      &lt;li&gt;fold the group “Other”&lt;/li&gt;
      &lt;li&gt;See what parts of my code consume the most time&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;If I want to see statistics of &lt;strong&gt;underlying&lt;/strong&gt; code I do the same steps but &lt;em&gt;“entry group”&lt;/em&gt; the group “other” - than means that PerfView will group by calls that are entry point to the group (so internal details of all other calls will be hidden, but I will be able to see, what specific calls of other code consue most time). In that case folding is not required.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;how-to-use-folding-and-grouping-in-perfview&quot;&gt;How to use folding and grouping in PerfView&lt;/h3&gt;

&lt;h4 id=&quot;quick-demo&quot;&gt;Quick demo&lt;/h4&gt;

&lt;p&gt;I want to profile and found of bottleneck in the loading of moodel mapping designer&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;I collect a trace &lt;a href=&quot;/Perfview-wall-clock-analysis-start/&quot;&gt;for the wall-clock analysis&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;I open the trace, select w3wp process and open the “Thread Time” view&lt;/li&gt;
  &lt;li&gt;I select “No grouping” in “group pats” and try to find thread in the “CallTree” tab: just enter “modelmapping” in the “Find” input box:
&lt;img src=&quot;/assets/perfview-finding-thread.png&quot; alt=&quot;Finding thread&quot; /&gt;&lt;/li&gt;
  &lt;li&gt;Now I see that find right thread (with ERModelMappingDesigner::Clicked) I can right click on and select “include item” and I will see only the thread I inetersted in, but I after that I edit the “IncPats” slightly - remove module name and arguments (will explain later) so I will have something like “Process% w3wp (7756);ERModelMappingDesigner::Clicked”&lt;/li&gt;
  &lt;li&gt;Then I switch to “By Name” tab:
&lt;img src=&quot;/assets/perfview-by-name-cputime.png&quot; alt=&quot;By name view&quot; /&gt;&lt;/li&gt;
  &lt;li&gt;I see than the process is CPU bound and can double click CPU_TIME to find a reason (pressing checkboxes in the tree):
&lt;img src=&quot;/assets/perfview-bottom-up-with-unnecessary-details.png&quot; alt=&quot;Bottom up with unnecessary details&quot; /&gt; but most of levels beween CPU and my code are unnecessary - I want to see the big picture.&lt;/li&gt;
  &lt;li&gt;So I apply grouping rules I prepared (load it to Presets, and select from presets ER -&amp;gt; Other) &lt;img src=&quot;/assets/perfview-with-grouping.png&quot; alt=&quot;With grouping&quot; /&gt; and repeat selecting CPU and see that all unnecessary details are grouped into node “Other”&lt;/li&gt;
  &lt;li&gt;Now I can switch back to “By Name” and fold all the ow level items including “Other” (folding means that item’s resources will be distributed across callers) &lt;img src=&quot;/assets/perfview-folding-system.png&quot; alt=&quot;How to fold&quot; /&gt;&lt;/li&gt;
  &lt;li&gt;Now we see a bottleneck and can optimize it (for example ungroup and perfrom a top-down analysis starting with the node)
&lt;img src=&quot;/assets/perfview-fold.png&quot; alt=&quot;Fold&quot; /&gt;&lt;/li&gt;
  &lt;li&gt;Other way is to look just under my code and see what calls of underlying platform eats much time: just switch to “ER =&amp;gt; Other” preset (then unfold all and fold cpu):
&lt;img src=&quot;/assets/perfview-entry-grouping.png&quot; alt=&quot;Fold&quot; /&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We see the most CPU time spend for moving between records - double clicking on the top row can show callers.&lt;/p&gt;

&lt;h4 id=&quot;explanation-of-grouping-presets&quot;&gt;Explanation of grouping presets&lt;/h4&gt;

&lt;p&gt;I have 2 presets:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;“ER -&amp;gt; Other” groups all modules I interested in by methods and all other item are grouped into single group named “Other”&lt;/li&gt;
  &lt;li&gt;“ER =&amp;gt; Other” is the same thing, but performs &lt;em&gt;entry grouping&lt;/em&gt; for other cals - that means that all methods from external code will be grouped only when my code calls it, all internal calls between external code will be inside those entry groups.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5 id=&quot;grouping-syntax&quot;&gt;Grouping syntax&lt;/h5&gt;

&lt;p&gt;This is my example (&lt;a href=&quot;/assets/ER_PerfViewPresets.xml&quot;&gt;download presets file&lt;/a&gt;)&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[ER=&amp;gt;Other] Microsoft.Dynamics365.{*}!{*}-&amp;gt;D365.$1.$2;dynamics.ax.applicationsuite!Dynamics.Ax.Application.{*}-&amp;gt;AppSuite.$1;dynamics.ax.electronicreporting{*}!Dynamics.Ax.Application.{*}-&amp;gt;ER$1.$2;!=&amp;gt;Other
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Explanation:&lt;/p&gt;

&lt;p&gt;“[ER=&amp;gt;Other]” - a name of the preset&lt;/p&gt;

&lt;p&gt;After the name goes sequence of grouping instructions, each intruction groups some type of paths and after that result is processed by the next instruction.&lt;/p&gt;

&lt;p&gt;Grouping instructions are in the following form:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Microsoft.Dynamics365.{*}!{*}-&amp;gt;D365.$1.$2;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;where:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;“Microsoft.Dynamics365.” - this is just a string to match
    - {*} - is like a .* regex matches any sequence of any symbol&lt;/li&gt;
  &lt;li&gt;! - in the method path it delimits module (dll) name and a method name&lt;/li&gt;
  &lt;li&gt;-&amp;gt; is grouping (=&amp;gt; entry grouping)&lt;/li&gt;
  &lt;li&gt;$1, $2 - like in regular expressions substitutes matches in corresponding curly braces&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So if this intruction will meet string Microsoft.Dynamics365.Application!MyClass.myMethod it will convert it to D365.Application.MyClass.MyMethod.&lt;/p&gt;

&lt;p&gt;Take into account that result does not contain the ! symbol so the alsready grouped strings will not be processed by the subsequent instructions.&lt;/p&gt;

&lt;p&gt;The last instruction !=&amp;gt;Other will take all previously onprocessed strings and put it to groups by entry points (or to the single group named “Other” in case of !-&amp;gt;Other)&lt;/p&gt;</content><author><name></name></author><summary type="html">How to find hot spots in your code.</summary></entry><entry><title type="html">Perfview in Dyn365FO. Part 3 - Wall clock analysis</title><link href="http://axcoder.github.io/Perfview-wall-clock-analysis-start/" rel="alternate" type="text/html" title="Perfview in Dyn365FO. Part 3 - Wall clock analysis" /><published>2018-11-17T00:00:00+00:00</published><updated>2018-11-17T00:00:00+00:00</updated><id>http://axcoder.github.io/Perfview-wall-clock-analysis-start</id><content type="html" xml:base="http://axcoder.github.io/Perfview-wall-clock-analysis-start/">&lt;p&gt;How to analyze actual time thread spend working or waiting for other threads.&lt;/p&gt;

&lt;p&gt;See the &lt;a href=&quot;/Perfview-in-dyn365fo/&quot;&gt;First part&lt;/a&gt; for the introduction and a list of posts.&lt;/p&gt;

&lt;p&gt;First step in analysis is detection, what kind of resource is a bottleneck. In my practice when testing performance on 1 box envinronment, most case is CPU bound tasks:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;On onebox we have a very low latency betwen AOS and SQL server so even if we have lots of queries, they are using CPU, not network or disk&lt;/li&gt;
  &lt;li&gt;Dyn365FO X++ code often use lots of small queries instead of one giant query with join - partly beacuse of it allows to use AOS caching, partly because many queries are in a separate methods (like “find”).&lt;/li&gt;
  &lt;li&gt;I work on Electronic Reporting module that itself is more like platform then like application code.&lt;/li&gt;
  &lt;li&gt;The reason for performance degradation can be locks on SQL server side, so it can be reproduced only with simultaneous work of multiple users&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Please keep in mind that test and production is a different environement and use other tools (like TraceParser and SQL server tools) to check whether a bottleneck is onthe same place there or not.&lt;/p&gt;

&lt;p&gt;Anyway lets strart.&lt;/p&gt;

&lt;h3 id=&quot;how-to-analyze-thread-time&quot;&gt;How to analyze thread time&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;/Perfview-collecting-trace/&quot;&gt;Collect a trace&lt;/a&gt; with thread time enabled&lt;/li&gt;
  &lt;li&gt;Filter by a thread you are interested in&lt;/li&gt;
  &lt;li&gt;See the most used resource&lt;/li&gt;
  &lt;li&gt;Recollect trace for CPU, if a task is CPU-bound&lt;/li&gt;
  &lt;li&gt;Perform top down or bottom up analysis&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After you press “Stop collection” and Perfview processed the trace, you will see the following window:
&lt;img src=&quot;/assets/perfview-selecting-threadtime.png&quot; alt=&quot;Opening thread time view&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Double click on thread time to select process and see details:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/perfview-selecting-process.png&quot; alt=&quot;Opening thread time view&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We see list of processes sorted by CPU time used and since I use perfromance test, I see the Visausl Studio test execution engine on top. If you use onebox you can probably see SQL server (if it do the most job). Also you can se AOS (w3wp) batch service.&lt;/p&gt;

&lt;p&gt;After pressing OK we will see data for callstacks:
&lt;img src=&quot;/assets/perfview-initial-tt-stacks.png&quot; alt=&quot;Initial thread time staks&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;filtering-by-thread&quot;&gt;Filtering by thread&lt;/h4&gt;

&lt;p&gt;This data is not very useful: since we measuring thread time it tells us all the time all thread spend on working and waiting, but we need to analyze only one thread - that is doing actual job.&lt;/p&gt;

&lt;p&gt;Also by default data is grouped by module. For selecting thread we&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Set “GroupPats” to nothing&lt;/li&gt;
  &lt;li&gt;Find the thread we actually want to explore: enter in “find” a name of the method that surely exist in callstacks that you are interested in. For my case it is “ERFormatMappingRun.run” and press enter&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src=&quot;/assets/perfview-found-and-ungrouped.png&quot; alt=&quot;Found and ungrouped&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Look at the pt.3 - perfview says that the whole method run is 0.6% of time. That’s because working and waiting time is summarized for &lt;strong&gt;all threads&lt;/strong&gt; and this is percentage from all that time.&lt;/p&gt;

&lt;p&gt;Lets tell PerfView to see only  stacks that include “ERFormatMappingRun.run” or method of your choice: type “;ERFormatMappingRun.run()” in the IncPats window and swithch to “by name” tab:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/perfview-by-name.png&quot; alt=&quot;By name and cpu&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We can see that most time (exclusive %) is spent by CPU - so actually calculating things, not waiting for SQL or network.&lt;/p&gt;

&lt;p&gt;The task is CPU bound.&lt;/p&gt;

&lt;p&gt;Now you shoould recollect trace for CPU to get better precision. Or, if you have a different result, you can start top down or bottom up analysis:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Go to CallTree tab and investigate perfromance of different parts from the top&lt;/li&gt;
  &lt;li&gt;Or doubleclick CPU and see the callers tree&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The later will be difficult since perfview now does not know what are  borders of your task and so it is started from OS internals.&lt;/p&gt;

&lt;p&gt;But the tool is very flexible and the next time we will see how to group stacks by meaningful properties.&lt;/p&gt;</content><author><name></name></author><summary type="html">How to analyze actual time thread spend working or waiting for other threads.</summary></entry><entry><title type="html">Perfview in Dyn365FO. Part 2 - Collecting a trace</title><link href="http://axcoder.github.io/Perfview-collecting-trace/" rel="alternate" type="text/html" title="Perfview in Dyn365FO. Part 2 - Collecting a trace" /><published>2018-11-11T00:00:00+00:00</published><updated>2018-11-11T00:00:00+00:00</updated><id>http://axcoder.github.io/Perfview-collecting-trace</id><content type="html" xml:base="http://axcoder.github.io/Perfview-collecting-trace/">&lt;p&gt;The first step in working with PerfView is collecting data.&lt;/p&gt;

&lt;p&gt;See the &lt;a href=&quot;/Perfview-in-dyn365fo/&quot;&gt;First part&lt;/a&gt; for the introduction and a list of posts.&lt;/p&gt;

&lt;p&gt;The overall plan is:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Prepare the scenario (use ~1-2 mins long period)&lt;/li&gt;
  &lt;li&gt;Select what to trace (trace CPU for CPU-bound tasks, trace thread time otherwise)&lt;/li&gt;
  &lt;li&gt;Record the trace&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;preparing-the-scenario&quot;&gt;Preparing the scenario&lt;/h3&gt;

&lt;p&gt;First of all, we need to prepare data. Perfview collects samples of callstak, the more samples to collect, the more precise statistics you will get, but trace file will be bigger. Therefore I usually prefer scenarios with duration about 1-2 mins.&lt;/p&gt;

&lt;p&gt;Prefview manual says that  10-20 secs would be enough.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Because the samples are taken every millisecond per processor, each sample represents 1 millisecond of CPU time.   However exactly where the sample is taken is effectively ‘random’, and so it is really ‘unfair’ to ‘charge’ the full millisecond to the routine that happened to be running at the time the sample was taken.   While this is true, it is also true that as more samples are taken this ‘unfairness’ decreases as the square root of the number of samples.   If a method has just 1 or 2 samples it could be just random chance that it happened in that particular method, but methods with 10 samples are likely to have truly used between 7 and 13 samples (30% error).  Routines with 100 samples are likely to be within 90 and 110 (10% error).    For ‘typical’ analysis this means you want at least 1000 and preferably more like 5000 samples (There are diminishing returns after 10K).   By collecting a few thousand samples you insure that even moderately ‘warm’ methods will have at least 10 samples, and ‘hot’ methods will have at least 100s, which keep the error acceptably small.   Because PerfView does not allow you to vary the sampling frequency, this means that you need to run the scenario for at least several seconds (for CPU bound tasks), and 10-20 seconds for less CPU bound activities.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
  &lt;li&gt;If I have shorter scenario I just insert loop into the code&lt;/li&gt;
  &lt;li&gt;if I have longer scenario, I either meaure part of it or reduce data to have 1-2 minutes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also, if you want to compare time, better to make sure that there is no other tasks on the same machine: open resource monitor (Win+R, resmon, enter) and watch for resource consumption.&lt;/p&gt;

&lt;p&gt;Also take into account, that possibly you need to measure warm run (so run scenario once before profiling to load caches, etc. But sometimes cold start is also interesting).&lt;/p&gt;

&lt;h3 id=&quot;collect-the-trace&quot;&gt;Collect the trace&lt;/h3&gt;

&lt;h4 id=&quot;collection-from-the-command-line&quot;&gt;Collection from the command line&lt;/h4&gt;

&lt;p&gt;You can instruct perfview to collect trace from the command line. For example below is a simple PowerShell script that I use for collecting thread time trace. It starts collection, builds a trace name from a timestamp,
and stops collection when Electroinic Reporting finishes format generation (it detects the moment using windows event log monitoring).&lt;/p&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;c:\programs\PerfView&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;collect&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;e:\traces\&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-format&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;ddMMyyyy_hhmm&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;etl&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot; &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;
     -CircularMB:20000 -ThreadTime &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;
     -NoNGenRundown &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;
     -StopOnEtwEvent:Microsoft-Dynamics-ElectronicReporting/FormatMappingRun/Stop
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;collection-from-the-gui&quot;&gt;Collection from the gui&lt;/h4&gt;

&lt;ol&gt;
  &lt;li&gt;Press Collect\Collect
&lt;img src=&quot;/assets/perfview-collect-collect.png&quot; alt=&quot;Perfview opening collect dialog&quot; /&gt;&lt;/li&gt;
  &lt;li&gt;Set parameters:
&lt;img src=&quot;/assets/perfview-collect-settings.png&quot; alt=&quot;Settings in collect dialog&quot; /&gt;
    &lt;ol&gt;
      &lt;li&gt;Name of the trace - set the name that will remind you of optimization phase and type of data (for example “initial-cpu.etw”) it can help to find baseline for comparison of traces later&lt;/li&gt;
      &lt;li&gt;Set trace length (1G is enough) - if it is too short, tool wil use it as a circular buffer, so events at start will be lost&lt;/li&gt;
      &lt;li&gt;Set “thread time”, if you are not sure that CPU is bottleneck, do not  set if you are 100% sure the task is CPU bound&lt;/li&gt;
      &lt;li&gt;Set “No V3.X NGEN Symbols”&lt;/li&gt;
      &lt;li&gt;Set “Zip” and “merge” if you want to take the trace from current machine to view on other machine (for example, if you have sources and symbols there)&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;Press “Start collection”. During collection pay some attention to the trace size
&lt;img src=&quot;/assets/perfview-collect-collection.png&quot; alt=&quot;Current trace size&quot; /&gt;&lt;/li&gt;
  &lt;li&gt;Press “Stop collection”&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Thats all for today, the next time we will start to analyze a trace.&lt;/p&gt;</content><author><name></name></author><summary type="html">The first step in working with PerfView is collecting data.</summary></entry><entry><title type="html">Using Perfview in Dynamics 365 for Finance and Operations</title><link href="http://axcoder.github.io/Perfview-in-dyn365fo/" rel="alternate" type="text/html" title="Using Perfview in Dynamics 365 for Finance and Operations" /><published>2018-11-04T00:00:00+00:00</published><updated>2018-11-04T00:00:00+00:00</updated><id>http://axcoder.github.io/Perfview-in-dyn365fo</id><content type="html" xml:base="http://axcoder.github.io/Perfview-in-dyn365fo/">&lt;p&gt;&lt;a href=&quot;https://github.com/Microsoft/perfview&quot;&gt;PerfView&lt;/a&gt; is my favorite .NET profiling tool. It uses &lt;a href=&quot;https://docs.microsoft.com/en-us/windows/desktop/etw/event-tracing-portal&quot;&gt;ETW&lt;/a&gt; to collect performance data.&lt;/p&gt;

&lt;p&gt;This post starts series on working with it for Dynamics 365 for Finance and Operation optimization tasks.&lt;/p&gt;

&lt;p&gt;Currently we have following posts:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Introduction - this post&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/Perfview-collecting-trace/&quot;&gt;Collecting a trace&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/Perfview-wall-clock-analysis-start/&quot;&gt;Wall clock analysis start&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/Perfview-bottom-up-analysis/&quot;&gt;Bottom-up analysis&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/Perfview-How-to-analyze-xpp-etl/&quot;&gt;How to analyze X++ etl in perfview&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Why do I like PerfView:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;It it is very flexible: it can answers questions like “what are the most resource consuming functions from the code under my control”, “what are the most consuming function from modules that are level below”, etc.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;It has rich (but not very intuitive UI) - flexible grouping, flamegraph, etc&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;It can collect data on the whole call stack (including AOS and ODBC calls).&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;It can accept data in an easy to understand XML format, that can be writen by tools under my control (for example, in the Electronic Reporting module for Dyn365FO 7.3 we can collect and output trace for configurations without exposing other user’s data)&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Perfview showing flamegraph for ER configration:
&lt;img src=&quot;/assets/perfview_ER.jpg&quot; alt=&quot;Perfview showing flamegraph for ER configration&quot; /&gt;&lt;/p&gt;
&lt;h3 id=&quot;perfview-vs-traceparser&quot;&gt;Perfview vs traceparser&lt;/h3&gt;

&lt;p&gt;What are upsides and downsides of using PerfView vs Trace parser?&lt;/p&gt;

&lt;p&gt;For me the main downside of PerfView in comparison with TraceParse is that it is unable to include SQL queries in the call stacks. While it can work with custom ETW providers, I still have not found a way to show SQL queries data there.&lt;/p&gt;

&lt;p&gt;Second, it is not integrated in the Dyn365FO so, you need to access particular box to collect the data. You can collect trace from Dyn365FO UI and use it in tre TraceParser, but for collecting Perfview trace you need to install PerfView or collect .NET related ETW events some other way.&lt;/p&gt;

&lt;p&gt;Third, the PerfView UI needs to be adapted to.&lt;/p&gt;

&lt;h3 id=&quot;how-to-collect-data-with-perfview&quot;&gt;How to collect data with perfview&lt;/h3&gt;

&lt;p&gt;The main sequence of steps to collect data is following. I hope I will cover each step in details in the future:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Determine a resource that limits performance (you can use other tools like resmon for that). If I don’t know, where is a bottleneck, I collect a thread time first, and then use the &lt;a href=&quot;https://channel9.msdn.com/Series/PerfView-Tutorial/Tutorial-12-Wall-Clock-Time-Investigation-Basics&quot;&gt;wall clock analysis&lt;/a&gt; to see what resource is limiting scenario performance.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Collect data targeted to bottleneck. Mostly in my practice there are 2 cases:&lt;/p&gt;
    &lt;ul&gt;
      &lt;li&gt;The scenario is CPU bound - “w3wp” or “batch” proceses use CPU up to 100% of one core and other resources wait for those processes to complete the task. In this case better to collect CPU usage because wall clock data can be inaccurate and affected by random factors. Also you will not have to deal with selecting the thread, which you want to analyze.&lt;/li&gt;
      &lt;li&gt;The scenario is IO bound or waiting for other processes to complete (for example sql server executing query). In this case better to collect thread time and prform wall clock analysis.
        &lt;ol&gt;
          &lt;li&gt;Perform top-down or bottom up analyze. You can use rich grouping and folding capabilities PerfView provides, flamegraph, call trees, etc.&lt;/li&gt;
        &lt;/ol&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;useful-links&quot;&gt;Useful links&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;PerfView has embedded html documentation.&lt;/li&gt;
  &lt;li&gt;Channel 9 contains old, but very usefull series of videos on PerfView - &lt;a href=&quot;https://channel9.msdn.com/Series/PerfView-Tutorial&quot;&gt;PerfView tutorial&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=eX644hod65s&quot;&gt;Excelent video&lt;/a&gt; by Sasha Goldshtein from DotNext SpB&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://randomascii.wordpress.com/2011/08/29/powerpoint-poor-performance-problem/&quot;&gt;Using ETW&lt;/a&gt; to profile and fix PowerPoint presentation&lt;/li&gt;
&lt;/ul&gt;</content><author><name></name></author><summary type="html">PerfView is my favorite .NET profiling tool. It uses ETW to collect performance data.</summary></entry><entry><title type="html">Hello, world!</title><link href="http://axcoder.github.io/New-Blog-Engine/" rel="alternate" type="text/html" title="Hello, world!" /><published>2018-04-11T00:00:00+00:00</published><updated>2018-04-11T00:00:00+00:00</updated><id>http://axcoder.github.io/New-Blog-Engine</id><content type="html" xml:base="http://axcoder.github.io/New-Blog-Engine/">&lt;h2 id=&quot;trying-a-new-blog-engine&quot;&gt;Trying a new blog engine&lt;/h2&gt;

&lt;p&gt;I like it because it uses markdown so I can easilly edit it offline and use version control.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;@AxCoder:HelloWord&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;</content><author><name></name></author><summary type="html">Trying a new blog engine</summary></entry></feed>