<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>StreamInsight Factotum</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/masimms/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/masimms/feed.xml</link>
    <description>Mark Simms&amp;#039; Blog about StreamInsight and building real-time event driven applications.</description>
    <lastBuildDate>Tue, 16 Apr 2019 05:19:39 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Azure Customer Advisory Team @ BUILD</title>
      <link>https://docs.microsoft.com/archive/blogs/masimms/azure-customer-advisory-team-build</link>
      <pubDate>Tue, 25 Jun 2013 17:33:13 GMT</pubDate>
      <dc:creator><![CDATA[Mark Simms [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/masimms/2013/06/25/azure-customer-advisory-team-build/</guid>
      <description><![CDATA[Next week, at Build, folks from the Windows Azure Customer Advisory Team (CAT), will be running a...]]></description>
      <content:encoded><![CDATA[<p>Next week, at Build, folks from the Windows Azure Customer Advisory Team (CAT), will be running a clinic in the Windows Azure are in the Big Room. We'll be there, whiteboard markers at the ready, to get hands-on with:</p>
<ul>
<li>Cloud scenarios</li>
<li>Design and architecture questions</li>
<li>Troubleshooting and diagnostics</li>
<li>Sharing best practices from customer deployments&nbsp;</li>
</ul>
<p>Look for us daily in the <strong>Windows Azure</strong> area in <strong>The Big Room</strong>, daily from 9am &ndash; 6pm and on Friday till 3pm. &nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>Fixing a gap in a prior post – Finding the Top Category with a Tumbling Window</title>
      <link>https://docs.microsoft.com/archive/blogs/masimms/fixing-a-gap-in-a-prior-post-finding-the-top-category-with-a-tumbling-window</link>
      <pubDate>Wed, 12 Jan 2011 14:05:04 GMT</pubDate>
      <dc:creator><![CDATA[Mark Simms [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/masimms/2011/01/12/fixing-a-gap-in-a-prior-post-finding-the-top-category-with-a-tumbling-window/</guid>
      <description><![CDATA[In a prior blog post –...]]></description>
      <content:encoded><![CDATA[<p>In a prior blog post – <a title="http://blogs.msdn.com/b/appfabriccat/archive/2010/11/03/streaminsight-query-pattern-find-the-top-category-using-order-by-take-and-applywithunion.aspx" href="http://blogs.msdn.com/b/appfabriccat/archive/2010/11/03/streaminsight-query-pattern-find-the-top-category-using-order-by-take-and-applywithunion.aspx">http://blogs.msdn.com/b/appfabriccat/archive/2010/11/03/streaminsight-query-pattern-find-the-top-category-using-order-by-take-and-applywithunion.aspx</a>– I discussed how to determine the top category in a set of events using order by and take.&#160; However, I only covered non-overlapping aggregate windows (i.e. Tumbling windows).&#160; I did not cover how you have to adjust your query definition for overlapping (Hopping) windows.&#160; Since this question came up in the forums, and it’s somewhat challenging to post a picture therein, here’s how you fix the problem.</p>  <p>Let’s start with our “working” top category query.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:389f7a41-8ffb-44b6-8306-edc8fdcbc13b" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #ddd; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="color:#808080">///</span><span style="color:#008000">/////////////////////////////////////////////////////////////////////////////////////////</span></li> <li style="background: #f3f3f3"><span style="color:#008000">// How can I find the group of events with the highest *average* value in the last 8 hours?</span></li> <li><span style="color:#808080">///</span><span style="color:#008000">/////////////////////////////////////////////////////////////////////////////////////////        </span></li> <li style="background: #f3f3f3"><span style="color:#0000ff">var</span><span style="color:#000000"> weatherData = </span><span style="color:#0000ff">new</span><span style="color:#000000">[]</span></li> <li><span style="color:#000000">{</span></li> <li style="background: #f3f3f3">    <span style="color:#000000"></span><span style="color:#0000ff">new</span><span style="color:#000000"> { Timestamp = DateTime.Parse(</span><span style="color:#dc1414">&quot;1/1/2010 0:00:00&quot;</span><span style="color:#000000">), Temperature = -</span><span style="color:#c81efa">9.0</span><span style="color:#000000">,    StationCode = </span><span style="color:#c81efa">71395</span><span style="color:#000000">,    WindSpeed = </span><span style="color:#c81efa">4    }</span><span style="color:#000000">, </span></li> <li>    <span style="color:#000000"></span><span style="color:#0000ff">new</span><span style="color:#000000"> { Timestamp = DateTime.Parse(</span><span style="color:#dc1414">&quot;1/1/2010 0:30:00&quot;</span><span style="color:#000000">), Temperature = -</span><span style="color:#c81efa">4.5</span><span style="color:#000000">,    StationCode = </span><span style="color:#c81efa">71395</span><span style="color:#000000">,    WindSpeed = </span><span style="color:#c81efa">41    }</span><span style="color:#000000">, </span></li> <li style="background: #f3f3f3">    <span style="color:#000000"></span><span style="color:#0000ff">new</span><span style="color:#000000"> { Timestamp = DateTime.Parse(</span><span style="color:#dc1414">&quot;1/1/2010 1:00:00&quot;</span><span style="color:#000000">), Temperature = -</span><span style="color:#c81efa">8.8</span><span style="color:#000000">,    StationCode = </span><span style="color:#c81efa">71395</span><span style="color:#000000">,    WindSpeed =    </span><span style="color:#c81efa">6    }</span><span style="color:#000000">, </span></li> <li>    <span style="color:#000000"></span><span style="color:#0000ff">new</span><span style="color:#000000"> { Timestamp = DateTime.Parse(</span><span style="color:#dc1414">&quot;1/1/2010 1:30:00&quot;</span><span style="color:#000000">), Temperature = -</span><span style="color:#c81efa">4.4</span><span style="color:#000000">,    StationCode = </span><span style="color:#c81efa">71801</span><span style="color:#000000">,    WindSpeed =    </span><span style="color:#c81efa">39    }</span><span style="color:#000000">, </span></li> <li style="background: #f3f3f3">    <span style="color:#000000"></span><span style="color:#0000ff">new</span><span style="color:#000000"> { Timestamp = DateTime.Parse(</span><span style="color:#dc1414">&quot;1/1/2010 2:00:00&quot;</span><span style="color:#000000">), Temperature = -</span><span style="color:#c81efa">9.7</span><span style="color:#000000">,    StationCode = </span><span style="color:#c81efa">71395</span><span style="color:#000000">,    WindSpeed =    </span><span style="color:#c81efa">9    }</span><span style="color:#000000">, </span></li> <li>    <span style="color:#000000"></span><span style="color:#0000ff">new</span><span style="color:#000000"> { Timestamp = DateTime.Parse(</span><span style="color:#dc1414">&quot;1/1/2010 2:30:00&quot;</span><span style="color:#000000">), Temperature = -</span><span style="color:#c81efa">4.6</span><span style="color:#000000">,    StationCode = </span><span style="color:#c81efa">71801</span><span style="color:#000000">,    WindSpeed =    </span><span style="color:#c81efa">59    }</span><span style="color:#000000">, </span></li> <li style="background: #f3f3f3">    <span style="color:#000000"></span><span style="color:#0000ff">new</span><span style="color:#000000"> { Timestamp = DateTime.Parse(</span><span style="color:#dc1414">&quot;1/1/2010 3:00:00&quot;</span><span style="color:#000000">), Temperature = -</span><span style="color:#c81efa">9.6</span><span style="color:#000000">,    StationCode = </span><span style="color:#c81efa">71801</span><span style="color:#000000">,    WindSpeed =    </span><span style="color:#c81efa">9    }</span></li> <li><span style="color:#000000">}</span><span style="color:#000000">;</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li><span style="color:#0000ff">var</span><span style="color:#000000"> weather = weatherData.ToPointStream(Application, t =&gt;</span></li> <li style="background: #f3f3f3">    <span style="color:#000000">PointEvent.CreateInsert(t.Timestamp, t),</span></li> <li>    <span style="color:#000000">AdvanceTimeSettings.IncreasingStartTime);</span></li> <li style="background: #f3f3f3">    <span style="color:#000000"></span></li> <li>        <span style="color:#000000"></span></li> <li style="background: #f3f3f3"><span style="color:#008000">// How do I find the category with the most events in the last 4 hours?</span></li> <li><span style="color:#0000ff">var</span><span style="color:#000000"> eventCount = </span><span style="color:#0000ff">from</span><span style="color:#000000"> e </span><span style="color:#0000ff">in</span><span style="color:#000000"> weather</span></li> <li style="background: #f3f3f3">                 <span style="color:#000000"></span><span style="color:#0000ff">group</span><span style="color:#000000"> e </span><span style="color:#0000ff">by</span><span style="color:#000000"> e.StationCode </span><span style="color:#0000ff">into</span><span style="color:#000000"> stationGroups</span></li> <li>                 <span style="color:#000000"></span><span style="color:#0000ff">from</span><span style="color:#000000"> win </span><span style="color:#0000ff">in</span><span style="color:#000000"> stationGroups.TumblingWindow(</span></li> <li style="background: #f3f3f3">                     <span style="color:#000000">TimeSpan.FromHours(</span><span style="color:#c81efa">2</span><span style="color:#000000">), HoppingWindowOutputPolicy.ClipToWindowEnd)</span></li> <li>                 <span style="color:#000000"></span><span style="color:#0000ff">select</span><span style="color:#000000"> </span><span style="color:#0000ff">new</span></li> <li style="background: #f3f3f3">             <span style="color:#000000">    </span><span style="color:#000000">{</span></li> <li>                     <span style="color:#000000">StationCode = stationGroups.Key,</span></li> <li style="background: #f3f3f3">                     <span style="color:#000000">Count = win.Count()</span></li> <li>                 <span style="color:#000000">};</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li><span style="color:#0000ff">var</span><span style="color:#000000"> topCategory = (</span><span style="color:#0000ff">from</span><span style="color:#000000"> win </span><span style="color:#0000ff">in</span><span style="color:#000000"> eventCount.SnapshotWindow(SnapshotWindowOutputPolicy.Clip)</span></li> <li style="background: #f3f3f3">                  <span style="color:#000000"></span><span style="color:#0000ff">from</span><span style="color:#000000"> e1 </span><span style="color:#0000ff">in</span><span style="color:#000000"> win</span></li> <li>                   <span style="color:#000000"></span><span style="color:#0000ff">orderby</span><span style="color:#000000"> e1.Count </span><span style="color:#0000ff">descending</span><span style="color:#000000">, e1.StationCode </span><span style="color:#0000ff">ascending</span></li> <li style="background: #f3f3f3">   <span style="color:#000000">                </span><span style="color:#000000"></span><span style="color:#0000ff">select</span><span style="color:#000000"> e1).Take(</span><span style="color:#c81efa">1</span><span style="color:#000000">);</span></li> <li><span style="color:#000000">\partopCategory.Dump(</span><span style="color:#dc1414">&quot;top category&quot;</span><span style="color:#000000">);        </span></li> <li style="background: #f3f3f3">&nbsp;</li> <li><span style="color:#008000">//</span></li> </ol> </div> </div> </div>  <p>What is actually happening here in terms of the event flow is described in the diagram below.&#160; The input stream, weather, is broken up into substreams by the station code, which then have Tumbling windows applied over top of them.&#160; This calculates the number of events in each category, which is then passed to the snapshot window (and then the order by and take).</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/metablogapi/2350.image_6F009935.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-metablogapi/2350.image_5F00_6F009935.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/metablogapi/3757.image_thumb_07240391.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-metablogapi/3757.image_5F00_thumb_5F00_07240391.png" width="900" height="309" /></a></p>  <p>This works so long as the input events to the snapshot window do not overlap.&#160; If they do, older “calculations” can be counted against the new ranking.&#160;&#160; For example, if a Hopping window is used, such as this query:</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:f3861b88-1932-4c4c-94c3-0150a6e350f9" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #ddd; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="color:#808080">///</span><span style="color:#008000">/////////////////////////////////////////////////////////////////////////////////////////</span></li> <li style="background: #f3f3f3"><span style="color:#008000">// How can I find the group of events with the highest *average* value in the last 8 hours?</span></li> <li><span style="color:#808080">///</span><span style="color:#008000">/////////////////////////////////////////////////////////////////////////////////////////        </span></li> <li style="background: #f3f3f3"><span style="color:#0000ff">var</span><span style="color:#000000"> weatherData = </span><span style="color:#0000ff">new</span><span style="color:#000000">[]</span></li> <li><span style="color:#000000">{</span></li> <li style="background: #f3f3f3">    <span style="color:#000000"></span><span style="color:#0000ff">new</span><span style="color:#000000"> { Timestamp = DateTime.Parse(</span><span style="color:#dc1414">&quot;1/1/2010 0:00:00&quot;</span><span style="color:#000000">), Temperature = -</span><span style="color:#c81efa">9.0</span><span style="color:#000000">,    StationCode = </span><span style="color:#c81efa">71395</span><span style="color:#000000">,    WindSpeed = </span><span style="color:#c81efa">4    }</span><span style="color:#000000">, </span></li> <li>    <span style="color:#000000"></span><span style="color:#0000ff">new</span><span style="color:#000000"> { Timestamp = DateTime.Parse(</span><span style="color:#dc1414">&quot;1/1/2010 0:30:00&quot;</span><span style="color:#000000">), Temperature = -</span><span style="color:#c81efa">4.5</span><span style="color:#000000">,    StationCode = </span><span style="color:#c81efa">71395</span><span style="color:#000000">,    WindSpeed = </span><span style="color:#c81efa">41    }</span><span style="color:#000000">, </span></li> <li style="background: #f3f3f3">    <span style="color:#000000"></span><span style="color:#0000ff">new</span><span style="color:#000000"> { Timestamp = DateTime.Parse(</span><span style="color:#dc1414">&quot;1/1/2010 1:00:00&quot;</span><span style="color:#000000">), Temperature = -</span><span style="color:#c81efa">8.8</span><span style="color:#000000">,    StationCode = </span><span style="color:#c81efa">71395</span><span style="color:#000000">,    WindSpeed =    </span><span style="color:#c81efa">6    }</span><span style="color:#000000">, </span></li> <li>    <span style="color:#000000"></span><span style="color:#0000ff">new</span><span style="color:#000000"> { Timestamp = DateTime.Parse(</span><span style="color:#dc1414">&quot;1/1/2010 1:30:00&quot;</span><span style="color:#000000">), Temperature = -</span><span style="color:#c81efa">4.4</span><span style="color:#000000">,    StationCode = </span><span style="color:#c81efa">71801</span><span style="color:#000000">,    WindSpeed =    </span><span style="color:#c81efa">39    }</span><span style="color:#000000">, </span></li> <li style="background: #f3f3f3">    <span style="color:#000000"></span><span style="color:#0000ff">new</span><span style="color:#000000"> { Timestamp = DateTime.Parse(</span><span style="color:#dc1414">&quot;1/1/2010 2:00:00&quot;</span><span style="color:#000000">), Temperature = -</span><span style="color:#c81efa">9.7</span><span style="color:#000000">,    StationCode = </span><span style="color:#c81efa">71395</span><span style="color:#000000">,    WindSpeed =    </span><span style="color:#c81efa">9    }</span><span style="color:#000000">, </span></li> <li>    <span style="color:#000000"></span><span style="color:#0000ff">new</span><span style="color:#000000"> { Timestamp = DateTime.Parse(</span><span style="color:#dc1414">&quot;1/1/2010 2:30:00&quot;</span><span style="color:#000000">), Temperature = -</span><span style="color:#c81efa">4.6</span><span style="color:#000000">,    StationCode = </span><span style="color:#c81efa">71801</span><span style="color:#000000">,    WindSpeed =    </span><span style="color:#c81efa">59    }</span><span style="color:#000000">, </span></li> <li style="background: #f3f3f3">    <span style="color:#000000"></span><span style="color:#0000ff">new</span><span style="color:#000000"> { Timestamp = DateTime.Parse(</span><span style="color:#dc1414">&quot;1/1/2010 3:00:00&quot;</span><span style="color:#000000">), Temperature = -</span><span style="color:#c81efa">9.6</span><span style="color:#000000">,    StationCode = </span><span style="color:#c81efa">71801</span><span style="color:#000000">,    WindSpeed =    </span><span style="color:#c81efa">9    }</span></li> <li><span style="color:#000000">}</span><span style="color:#000000">;</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li><span style="color:#0000ff">var</span><span style="color:#000000"> weather = weatherData.ToPointStream(Application, t =&gt;</span></li> <li style="background: #f3f3f3">    <span style="color:#000000">PointEvent.CreateInsert(t.Timestamp, t),</span></li> <li>    <span style="color:#000000">AdvanceTimeSettings.IncreasingStartTime);</span></li> <li style="background: #f3f3f3">    <span style="color:#000000"></span></li> <li>        <span style="color:#000000"></span></li> <li style="background: #f3f3f3"><span style="color:#008000">// How do I find the category with the most events in the last 4 hours?</span></li> <li><span style="color:#0000ff">var</span><span style="color:#000000"> eventCount = </span><span style="color:#0000ff">from</span><span style="color:#000000"> e </span><span style="color:#0000ff">in</span><span style="color:#000000"> weather</span></li> <li style="background: #f3f3f3">                 <span style="color:#000000"></span><span style="color:#0000ff">group</span><span style="color:#000000"> e </span><span style="color:#0000ff">by</span><span style="color:#000000"> e.StationCode </span><span style="color:#0000ff">into</span><span style="color:#000000"> stationGroups</span></li> <li>                 <span style="color:#000000"></span><span style="color:#0000ff">from</span><span style="color:#000000"> win </span><span style="color:#0000ff">in</span><span style="color:#000000"> stationGroups.HoppingWindow(</span></li> <li style="background: #f3f3f3">                     <span style="color:#000000">TimeSpan.FromHours(</span><span style="color:#c81efa">2</span><span style="color:#000000">), TimeSpan.FromHours(</span><span style="color:#c81efa">1</span><span style="color:#000000">),</span></li> <li>                    <span style="color:#000000">HoppingWindowOutputPolicy.ClipToWindowEnd)</span></li> <li style="background: #f3f3f3">                 <span style="color:#000000"></span><span style="color:#0000ff">select</span><span style="color:#000000"> </span><span style="color:#0000ff">new</span></li> <li>             <span style="color:#000000">    </span><span style="color:#000000">{</span></li> <li style="background: #f3f3f3">                     <span style="color:#000000">StationCode = stationGroups.Key,</span></li> <li>                     <span style="color:#000000">Count = win.Count()</span></li> <li style="background: #f3f3f3">                 <span style="color:#000000">};</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3"><span style="color:#0000ff">var</span><span style="color:#000000"> topCategory = (</span><span style="color:#0000ff">from</span><span style="color:#000000"> win </span><span style="color:#0000ff">in</span><span style="color:#000000"> eventCount.SnapshotWindow(SnapshotWindowOutputPolicy.Clip)</span></li> <li>                  <span style="color:#000000"></span><span style="color:#0000ff">from</span><span style="color:#000000"> e1 </span><span style="color:#0000ff">in</span><span style="color:#000000"> win</span></li> <li style="background: #f3f3f3">                   <span style="color:#000000"></span><span style="color:#0000ff">orderby</span><span style="color:#000000"> e1.Count </span><span style="color:#0000ff">descending</span><span style="color:#000000">, e1.StationCode </span><span style="color:#0000ff">ascending</span></li> <li>   <span style="color:#000000">                </span><span style="color:#000000"></span><span style="color:#0000ff">select</span><span style="color:#000000"> e1).Take(</span><span style="color:#c81efa">1</span><span style="color:#000000">);</span></li> <li style="background: #f3f3f3"><span style="color:#000000">\partopCategory.Dump(</span><span style="color:#dc1414">&quot;top category&quot;</span><span style="color:#000000">);        </span></li> <li>&nbsp;</li> <li style="background: #f3f3f3"><span style="color:#008000">//</span></li> </ol> </div> </div> </div>  <p>The following effect is observed – at points in the event stream the results of older Tumbling windows are passed to the snapshot window for ordering.&#160; This can produce incorrect results, as seen in this diagram.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/metablogapi/0118.image_4D34C0A4.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-metablogapi/0118.image_5F00_4D34C0A4.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/metablogapi/0131.image_thumb_5F115471.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-metablogapi/0131.image_5F00_thumb_5F00_5F115471.png" width="900" height="347" /></a></p>        <p><strong>In order to prevent this from happening, we need to stop the output of the hopping windows from overlapping in the snapshot window.&#160; There are a number of ways to do this, but the easiest is to convert the output of the Hopping window back into point events via the </strong><a href="http://msdn.microsoft.com/en-us/library/ee391517.aspx"><strong>ToPointEventStream</strong></a><strong> method.</strong></p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:a093868c-12ff-4591-a76f-ef9913110f63" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #ddd; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="color:#808080">///</span><span style="color:#008000">/////////////////////////////////////////////////////////////////////////////////////////</span></li> <li style="background: #f3f3f3"><span style="color:#008000">// How can I find the group of events with the highest *average* value in the last 8 hours?</span></li> <li><span style="color:#808080">///</span><span style="color:#008000">/////////////////////////////////////////////////////////////////////////////////////////        </span></li> <li style="background: #f3f3f3"><span style="color:#0000ff">var</span><span style="color:#000000"> weatherData = </span><span style="color:#0000ff">new</span><span style="color:#000000">[]</span></li> <li><span style="color:#000000">{</span></li> <li style="background: #f3f3f3">    <span style="color:#000000"></span><span style="color:#0000ff">new</span><span style="color:#000000"> { Timestamp = DateTime.Parse(</span><span style="color:#dc1414">&quot;1/1/2010 0:00:00&quot;</span><span style="color:#000000">), Temperature = -</span><span style="color:#c81efa">9.0</span><span style="color:#000000">,    StationCode = </span><span style="color:#c81efa">71395</span><span style="color:#000000">,    WindSpeed = </span><span style="color:#c81efa">4    }</span><span style="color:#000000">, </span></li> <li>    <span style="color:#000000"></span><span style="color:#0000ff">new</span><span style="color:#000000"> { Timestamp = DateTime.Parse(</span><span style="color:#dc1414">&quot;1/1/2010 0:30:00&quot;</span><span style="color:#000000">), Temperature = -</span><span style="color:#c81efa">4.5</span><span style="color:#000000">,    StationCode = </span><span style="color:#c81efa">71395</span><span style="color:#000000">,    WindSpeed = </span><span style="color:#c81efa">41    }</span><span style="color:#000000">, </span></li> <li style="background: #f3f3f3">    <span style="color:#000000"></span><span style="color:#0000ff">new</span><span style="color:#000000"> { Timestamp = DateTime.Parse(</span><span style="color:#dc1414">&quot;1/1/2010 1:00:00&quot;</span><span style="color:#000000">), Temperature = -</span><span style="color:#c81efa">8.8</span><span style="color:#000000">,    StationCode = </span><span style="color:#c81efa">71395</span><span style="color:#000000">,    WindSpeed =    </span><span style="color:#c81efa">6    }</span><span style="color:#000000">, </span></li> <li>    <span style="color:#000000"></span><span style="color:#0000ff">new</span><span style="color:#000000"> { Timestamp = DateTime.Parse(</span><span style="color:#dc1414">&quot;1/1/2010 1:30:00&quot;</span><span style="color:#000000">), Temperature = -</span><span style="color:#c81efa">4.4</span><span style="color:#000000">,    StationCode = </span><span style="color:#c81efa">71801</span><span style="color:#000000">,    WindSpeed =    </span><span style="color:#c81efa">39    }</span><span style="color:#000000">, </span></li> <li style="background: #f3f3f3">    <span style="color:#000000"></span><span style="color:#0000ff">new</span><span style="color:#000000"> { Timestamp = DateTime.Parse(</span><span style="color:#dc1414">&quot;1/1/2010 2:00:00&quot;</span><span style="color:#000000">), Temperature = -</span><span style="color:#c81efa">9.7</span><span style="color:#000000">,    StationCode = </span><span style="color:#c81efa">71395</span><span style="color:#000000">,    WindSpeed =    </span><span style="color:#c81efa">9    }</span><span style="color:#000000">, </span></li> <li>    <span style="color:#000000"></span><span style="color:#0000ff">new</span><span style="color:#000000"> { Timestamp = DateTime.Parse(</span><span style="color:#dc1414">&quot;1/1/2010 2:30:00&quot;</span><span style="color:#000000">), Temperature = -</span><span style="color:#c81efa">4.6</span><span style="color:#000000">,    StationCode = </span><span style="color:#c81efa">71801</span><span style="color:#000000">,    WindSpeed =    </span><span style="color:#c81efa">59    }</span><span style="color:#000000">, </span></li> <li style="background: #f3f3f3">    <span style="color:#000000"></span><span style="color:#0000ff">new</span><span style="color:#000000"> { Timestamp = DateTime.Parse(</span><span style="color:#dc1414">&quot;1/1/2010 3:00:00&quot;</span><span style="color:#000000">), Temperature = -</span><span style="color:#c81efa">9.6</span><span style="color:#000000">,    StationCode = </span><span style="color:#c81efa">71801</span><span style="color:#000000">,    WindSpeed =    </span><span style="color:#c81efa">9    }</span></li> <li><span style="color:#000000">}</span><span style="color:#000000">;</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li><span style="color:#0000ff">var</span><span style="color:#000000"> weather = weatherData.ToPointStream(Application, t =&gt;</span></li> <li style="background: #f3f3f3">    <span style="color:#000000">PointEvent.CreateInsert(t.Timestamp, t),</span></li> <li>    <span style="color:#000000">AdvanceTimeSettings.IncreasingStartTime);</span></li> <li style="background: #f3f3f3">    <span style="color:#000000"></span></li> <li>        <span style="color:#000000"></span></li> <li style="background: #f3f3f3"><span style="color:#008000">// How do I find the category with the most events in the last 4 hours?</span></li> <li><span style="color:#0000ff">var</span><span style="color:#000000"> eventCount = </span><span style="color:#0000ff">from</span><span style="color:#000000"> e </span><span style="color:#0000ff">in</span><span style="color:#000000"> weather</span></li> <li style="background: #f3f3f3">                 <span style="color:#000000"></span><span style="color:#0000ff">group</span><span style="color:#000000"> e </span><span style="color:#0000ff">by</span><span style="color:#000000"> e.StationCode </span><span style="color:#0000ff">into</span><span style="color:#000000"> stationGroups</span></li> <li>                 <span style="color:#000000"></span><span style="color:#0000ff">from</span><span style="color:#000000"> win </span><span style="color:#0000ff">in</span><span style="color:#000000"> stationGroups.HoppingWindow(</span></li> <li style="background: #f3f3f3">                     <span style="color:#000000">TimeSpan.FromHours(</span><span style="color:#c81efa">2</span><span style="color:#000000">), TimeSpan.FromHours(</span><span style="color:#c81efa">1</span><span style="color:#000000">),</span></li> <li>                    <span style="color:#000000">HoppingWindowOutputPolicy.ClipToWindowEnd)</span></li> <li style="background: #f3f3f3">                 <span style="color:#000000"></span><span style="color:#0000ff">select</span><span style="color:#000000"> </span><span style="color:#0000ff">new</span></li> <li>             <span style="color:#000000">    </span><span style="color:#000000">{</span></li> <li style="background: #f3f3f3">                     <span style="color:#000000">StationCode = stationGroups.Key,</span></li> <li>                     <span style="color:#000000">Count = win.Count()</span></li> <li style="background: #f3f3f3">                 <span style="color:#000000">};</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3"><span style="color:#0000ff">var</span><span style="color:#000000"> topCategory = (</span><span style="color:#0000ff">from</span><span style="color:#000000"> win </span><span style="color:#0000ff">in</span><span style="color:#000000"> eventCount.ToPointEventStream()</span></li> <li>                      <span style="color:#000000">.SnapshotWindow(SnapshotWindowOutputPolicy.Clip)</span></li> <li style="background: #f3f3f3">                  <span style="color:#000000"></span><span style="color:#0000ff">from</span><span style="color:#000000"> e1 </span><span style="color:#0000ff">in</span><span style="color:#000000"> win</span></li> <li>                   <span style="color:#000000"></span><span style="color:#0000ff">orderby</span><span style="color:#000000"> e1.Count </span><span style="color:#0000ff">descending</span><span style="color:#000000">, e1.StationCode </span><span style="color:#0000ff">ascending</span></li> <li style="background: #f3f3f3">   <span style="color:#000000">                </span><span style="color:#000000"></span><span style="color:#0000ff">select</span><span style="color:#000000"> e1).Take(</span><span style="color:#c81efa">1</span><span style="color:#000000">);</span></li> <li><span style="color:#000000">\partopCategory.Dump(</span><span style="color:#dc1414">&quot;top category&quot;</span><span style="color:#000000">);        </span></li> <li style="background: #f3f3f3">&nbsp;</li> <li><span style="color:#008000">//</span></li> </ol> </div> </div> </div>  <p>Which will produce the desired results:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/metablogapi/1373.image_05DF6AB2.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-metablogapi/1373.image_5F00_05DF6AB2.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/metablogapi/0121.image_thumb_7396A3EF.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-metablogapi/0121.image_5F00_thumb_5F00_7396A3EF.png" width="904" height="465" /></a></p>  <p>Note that the diagrams don’t entirely line up; I’ll polish this up a bit and add some information on tie-breaking before posting to the AppFabric CAT blog site next week.</p>]]></content:encoded>
    </item>
    <item>
      <title>Rounding up a few StreamInsight blog posts</title>
      <link>https://docs.microsoft.com/archive/blogs/masimms/rounding-up-a-few-streaminsight-blog-posts</link>
      <pubDate>Wed, 05 Jan 2011 15:12:43 GMT</pubDate>
      <dc:creator><![CDATA[Mark Simms [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/masimms/2011/01/05/rounding-up-a-few-streaminsight-blog-posts/</guid>
      <description><![CDATA[Wanted to throw together a quick list of a few recent blog posts on the AppFabric CAT team blog...]]></description>
      <content:encoded><![CDATA[<p>Wanted to throw together a quick list of a few recent blog posts on the <a href="http://blogs.msdn.com/b/appfabriccat/">AppFabric CAT team blog</a> (where most of my more ‘technical’ articles end up), as well as some of my favorite articles that I’ve come across lately.</p>  <h4>Working with LINQPad</h4>  <ul>   <li><a title="StreamInsight- Creating a LINQPad data context" href="http://blogs.msdn.com/b/appfabriccat/archive/2011/01/05/streaminsight-creating-a-linqpad-data-context.aspx">StreamInsight- Creating a LINQPad data context</a> (the short version)</li>    <li><a title="StreamInsight- Creating a custom data context for LINQPad, chock full of weathery goodness" href="http://blogs.msdn.com/b/appfabriccat/archive/2011/01/04/creating-a-custom-streaminsight-query-context-for-linqpad-chock-full-of-weathery-goodness.aspx">StreamInsight- Creating a custom data context for LINQPad, chock full of weathery goodness</a> (the not so short version)</li>    <li><a title="StreamInsight- Reading from other data contexts into StreamInsight with LINQPad" href="http://blogs.msdn.com/b/appfabriccat/archive/2010/12/03/streaminsight-reading-from-other-data-contexts-into-streaminsight-with-linqpad.aspx">StreamInsight- Reading from other data contexts into StreamInsight with LINQPad</a></li>    <li><a title="StreamInsight- Understanding dynamic query composition" href="http://blogs.msdn.com/b/appfabriccat/archive/2010/11/22/streaminsight-understanding-dynamic-query-composition.aspx">StreamInsight- Understanding dynamic query composition</a></li>    <li><a href="http://blogs.msdn.com/b/appfabriccat/archive/2010/12/02/streaminsight-where-did-that-query-result-come-from.aspx">StreamInsight- Where did that query result come from (using the Event Flow Debugger in LINQPad)</a></li> </ul>  <h4>Query Patterns</h4>  <ul>   <li><a title="StreamInsight Query Patterns- Fun with process data – calculating the wind chill factor" href="http://blogs.msdn.com/b/appfabriccat/archive/2010/12/13/streaminsight-query-patterns-fun-with-process-data-calculating-the-wind-chill-factor.aspx">StreamInsight Query Patterns- Fun with process data – calculating the wind chill factor</a></li>    <li><a title="StreamInsight Query Pattern- Find the top category (using Order By, Take and ApplyWithUnion)" href="http://blogs.msdn.com/b/appfabriccat/archive/2010/11/03/streaminsight-query-pattern-find-the-top-category-using-order-by-take-and-applywithunion.aspx">StreamInsight Query Pattern- Find the top category (using Order By, Take and ApplyWithUnion)</a></li> </ul>  <h4>Minor, yet annoying error messages</h4>  <ul>   <li><a title="StreamInsight- Obscure LINQ error - Stream other than apply input stream is cannot be referenced" href="http://blogs.msdn.com/b/appfabriccat/archive/2010/11/02/streaminsight-obscure-linq-error-stream-other-than-apply-input-stream-is-cannot-be-referenced-inside-apply-branch.aspx">StreamInsight- Obscure LINQ error - Stream other than apply input stream is cannot be referenced</a></li>    <li><a title="StreamInsight- Obscure LINQ error - The field &#39;Key&#39; of type &#39;IKey`1&#39; either contains a nested me" href="http://blogs.msdn.com/b/appfabriccat/archive/2010/10/23/streaminsight-obscure-linq-error-the-field-key-of-type-ikey-1-either-contains-a-nested-member-or-is-a-type-that-is-not-supported-as-event-type-field.aspx">StreamInsight- Obscure LINQ error - The field 'Key' of type 'IKey`1' either contains a nested me</a></li> </ul>  <h4>Some recent favorites from around the web</h4>  <ul>   <li><a title="Permanent link to 5 Quick Steps For Trying Out StreamInsight with LINQPad" href="http://seroter.wordpress.com/2010/12/23/5-quick-steps-for-trying-out-streaminsight-with-linqpad/">Permanent link to 5 Quick Steps For Trying Out StreamInsight with LINQPad</a></li>    <li><a title="StreamInsight Sequence Integration- Five Easy Pieces" href="http://blogs.msdn.com/b/meek/archive/2010/10/27/streaminsight-sequence-integration-five-easy-pieces.aspx">StreamInsight Sequence Integration- Five Easy Pieces</a></li>    <li><a title="LINQ Macros" href="http://blogs.msdn.com/b/meek/archive/2011/01/05/linq-macros.aspx">LINQ Macros</a></li> </ul>  <p>Working up my pipeline of interesting things to write about in the next month or two.&#160; Other than finishing (almost there!) the rest of the “<a href="http://blogs.msdn.com/b/masimms/archive/2010/09/16/101-ish-linq-samples-for-streaminsight.aspx">101 LINQ Samples” for StreamInsight,</a> wondering if there’s any suggestions out there on interesting topics.</p>]]></content:encoded>
    </item>
    <item>
      <title>Adventures in performance tuning</title>
      <link>https://docs.microsoft.com/archive/blogs/masimms/adventures-in-performance-tuning</link>
      <pubDate>Wed, 05 Jan 2011 10:17:06 GMT</pubDate>
      <dc:creator><![CDATA[Mark Simms [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/masimms/2011/01/05/adventures-in-performance-tuning/</guid>
      <description><![CDATA[Been a bit quiet on this blog lately, as most of my postings have ended up on the AppFabric CAT team...]]></description>
      <content:encoded><![CDATA[<p>Been a bit quiet on this blog lately, as most of my postings have ended up on the <a href="http://blogs.msdn.com/appfabriccat/">AppFabric CAT team blog</a>.&#160; As part of a recent effort to build a canned LINQPad data context to use with StreamInsight, I went through a few rounds of performance testing to create an application that could (in order of priority):</p>  <ol>   <li>Store a large number of events (&gt; 1,000,000) in a <strong>human readable</strong> format (by human readable, meaning being able to visually review the data through commonly available tools).&#160; This generally means text, nothing being friendlier to sharing, converting, manipulating, etc. </li>    <li>Provide a sufficiently <strong>small </strong>and <strong>portable </strong>data size (MB, not GB) to be easily downloaded and moved across the network (i.e. the data must be self-contained) </li>    <li>Be <strong>read performant</strong> – provide the ability to retrieve at least 60k events per second on my desktop (as writing the encoded data sets is a 1-time activity, not concerned about optimizing performance). </li> </ol>  <p>The intent for this system was to be able to store and replay “canned” data sets for StreamInsight applications.&#160; The performance metrics, in order of priority were:</p>  <ol>   <li>File size </li>    <li>Read throughput (target is 100k+ events / second) </li>    <li>Generic applicability – needs to be relatively non-specific to any conformant data set (see below) </li>    <li>CPU utilization </li>    <li>Memory consumption </li> </ol>  <p>The “tricks” (constraints, really) I was able to take advantage of were:</p>  <ul>   <li>Forward only access to data (i.e. did not need random access to specific data elements). </li>    <li>Only flat data record schema (StreamInsight doesn’t support nested types in streams). </li> </ul>  <p>The reference data set consisted of 733 MB of data downloaded from <a href="http://www.weatheroffice.gc.ca/canada_e.html">Environment Canada’s</a> <a href="http://www.climate.weatheroffice.gc.ca/climateData/canada_e.html">National Climate Archives</a> web site, in XML format.&#160; My first pass through performance tuning consisted of evaulating the following techniques:</p>  <ol>   <li>Raw XML (to establish a <strong>baseline </strong>for performance tuning) </li>    <li>Optimized XML (remove extraneous fields from source XML) </li>    <li>SQL Compact </li>    <li>CSV files </li>    <li>Compressed CSV files (via the most excellent <a href="http://msdn.microsoft.com/en-us/library/system.io.compression.gzipstream.aspx">GZipStream</a> class, introduced in .NET 4.0) </li> </ol>  <p>In order to perform the testing I needed a benchmark framework which could execute a deterministic test set and capture associated performance data.&#160; This framework needed to:</p>  <ul>   <li>Provide a pluggable interface for inserting the read/write code which would implement each store/format. </li>    <li>Measure the key performance metrics </li> </ul>  <p>&#160;</p>  <table border="0" cellspacing="0" cellpadding="2" width="800"><tbody>     <tr>       <td valign="top" width="76"><a href="http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=appfabriccat&amp;DownloadId=14735"><img title="3d Glossy Blue Orbs Business Typed Folded Page Corner Document Icon" alt="3d Glossy Blue Orbs Business Typed Folded Page Corner Document Icon" src="http://icons.mysitemyway.com/wp-content/gallery/3d-glossy-blue-orbs-icons-business/thumbs/thumbs_075750-3d-glossy-blue-orb-icon-business-document.png" width="64" height="64" /></a></td>        <td valign="top" width="724">Download the test frameworks <a href="http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=appfabriccat&amp;DownloadId=14735">here</a>.</td>     </tr>   </tbody></table>  <h3>Stage 1 - Evaluating File Size</h3>  <p>First pass with the full test set were pretty clear – compressed CSV and XML files look to be the clear winner for size (I threw in compressed XML just to be fair).&#160; We execute the tests by opening up and executing the PerformanceTests project.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/metablogapi/1663.image_774965F5.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-metablogapi/1663.image_5F00_774965F5.png"><img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/metablogapi/8510.image_thumb_1A55C367.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-metablogapi/8510.image_5F00_thumb_5F00_1A55C367.png" width="485" height="293" /></a></p>  <p>Or, if you prefer the raw data:</p>  <table style="line-height: normal; list-style-type: disc; width: ; border-collapse: collapse" border="0" cellspacing="0" cellpadding="0" width="292"><colgroup><col style="width: 77pt; mso-width-source: userset; mso-width-alt: 3730" width="102" /><col style="width: 48pt" width="64" /><col style="width: 94pt; mso-width-source: userset; mso-width-alt: 4571" width="125" /></colgroup><tbody>     <tr style="height: 15pt" height="20">       <td style="padding-left: 1px; width: ; padding-right: 1px; height: ; vertical-align: bottom; padding-top: 1px" height="20" width="102"><font face="Calibri"><font style="font-size: 11pt" color="#000000">Raw XML</font></font></td>        <td style="padding-left: 1px; width: ; padding-right: 1px; vertical-align: bottom; padding-top: 1px" width="64" align="right"><font face="Calibri"><font style="font-size: 11pt" color="#000000">699.61</font></font></td>        <td style="padding-left: 1px; width: ; padding-right: 1px; vertical-align: bottom; padding-top: 1px" width="125" align="right"><font face="Calibri"><font style="font-size: 11pt" color="#000000">1</font></font></td>     </tr>      <tr style="height: 15pt" height="20">       <td style="padding-left: 1px; padding-right: 1px; height: ; vertical-align: bottom; padding-top: 1px" height="20"><font face="Calibri"><font style="font-size: 11pt" color="#000000">Optimized XML</font></font></td>        <td style="padding-left: 1px; padding-right: 1px; vertical-align: bottom; padding-top: 1px" align="right"><font face="Calibri"><font style="font-size: 11pt" color="#000000">471.72</font></font></td>        <td style="padding-left: 1px; padding-right: 1px; vertical-align: bottom; padding-top: 1px" align="right"><font face="Calibri"><font style="font-size: 11pt" color="#000000">1.48</font></font></td>     </tr>      <tr style="height: 15pt" height="20">       <td style="padding-left: 1px; padding-right: 1px; height: ; vertical-align: bottom; padding-top: 1px" height="20"><font face="Calibri"><font style="font-size: 11pt" color="#000000">Compressed XML</font></font></td>        <td style="padding-left: 1px; padding-right: 1px; vertical-align: bottom; padding-top: 1px" align="right"><font face="Calibri"><font style="font-size: 11pt" color="#000000">27.38</font></font></td>        <td style="padding-left: 1px; padding-right: 1px; vertical-align: bottom; padding-top: 1px" align="right"><font face="Calibri"><font style="font-size: 11pt" color="#000000">25.55</font></font></td>     </tr>      <tr style="height: 15pt" height="20">       <td style="padding-left: 1px; padding-right: 1px; height: ; vertical-align: bottom; padding-top: 1px" height="20"><font face="Calibri"><font style="font-size: 11pt" color="#000000">SQLCE</font></font></td>        <td style="padding-left: 1px; padding-right: 1px; vertical-align: bottom; padding-top: 1px" align="right"><font face="Calibri"><font style="font-size: 11pt" color="#000000">102.32</font></font></td>        <td style="padding-left: 1px; padding-right: 1px; vertical-align: bottom; padding-top: 1px" align="right"><font face="Calibri"><font style="font-size: 11pt" color="#000000">6.84</font></font></td>     </tr>      <tr style="height: 15pt" height="20">       <td style="padding-left: 1px; padding-right: 1px; height: ; vertical-align: bottom; padding-top: 1px" height="20"><font face="Calibri"><font style="font-size: 11pt" color="#000000">CSV</font></font></td>        <td style="padding-left: 1px; padding-right: 1px; vertical-align: bottom; padding-top: 1px" align="right"><font face="Calibri"><font style="font-size: 11pt" color="#000000">90.08</font></font></td>        <td style="padding-left: 1px; padding-right: 1px; vertical-align: bottom; padding-top: 1px" align="right"><font face="Calibri"><font style="font-size: 11pt" color="#000000">7.77</font></font></td>     </tr>      <tr style="height: 15pt" height="20">       <td style="padding-left: 1px; padding-right: 1px; height: ; vertical-align: bottom; padding-top: 1px" height="20"><font face="Calibri"><font style="font-size: 11pt" color="#000000">CSV-GZIP</font></font></td>        <td style="padding-left: 1px; padding-right: 1px; vertical-align: bottom; padding-top: 1px" align="right"><font face="Calibri"><font style="font-size: 11pt" color="#000000">18.28</font></font></td>        <td style="padding-left: 1px; padding-right: 1px; vertical-align: bottom; padding-top: 1px" align="right"><font face="Calibri"><font style="font-size: 11pt" color="#000000">38.28</font></font></td>     </tr>   </tbody></table>  <p>&#160;</p>  <table border="0" cellspacing="0" cellpadding="2" width="802"><tbody>     <tr>       <td valign="top" width="76"><img title="3d Glossy Blue Orbs Alphanumeric Lucinda Exclamation Point Icon" alt="3d Glossy Blue Orbs Alphanumeric Lucinda Exclamation Point Icon" src="http://icons.mysitemyway.com/wp-content/gallery/3d-glossy-blue-orbs-icons-alphanumeric/thumbs/thumbs_067865-3d-glossy-blue-orb-icon-alphanumeric-exclamation-point1.png" width="64" height="64" /></td>        <td valign="top" width="724">Based on the first of our ranked performance criteria (<strong>file size)</strong>, we can now winnow down the field to two clear front runners – compressed XML and CSV format.&#160; Now we move on to reviewing read throughput for these two techniques.</td>     </tr>   </tbody></table>  <h3>Stage 2 - Evaluating Read Throughput</h3>  <p>Now that we’ve winnowed down the field to two candidates, let’s go and test them for read performance.&#160; We’ll run four tests here:</p>  <ul>   <li><a href="http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx">XML Serializer</a> – Compressed </li>    <li><a href="http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx">XML Serializer</a> - Uncompressed </li>    <li>CSV reader – Compressed </li>    <li>CSV reader – Uncompressed </li> </ul>  <p>Note that we expect the XmlSerializer read performance to suck, as it is designed (and intended) to pull the entire file into memory and provide random access as an in-memory object.&#160; Remember one of the constraints we can take advantage of&#160; - <strong>Forward only access to data </strong>– we don’t have to pay the price to load the entire data set into memory for random access.&#160; I could have written a forward-parser using <a href="http://msdn.microsoft.com/en-us/library/system.xml.xmltextreader.aspx">XmlTextReader</a> or <a href="http://msdn.microsoft.com/en-us/library/system.xml.linq.xelement.aspx">XElement</a>, but to be honest, making it generic was more work than I wanted to bother with (remember – this has to be readily applicable to all forms of StreamInsight compatible data).&#160;&#160; </p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/metablogapi/0181.image_65493436.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-metablogapi/0181.image_5F00_65493436.png"><img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/metablogapi/8103.image_thumb_731B7A31.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-metablogapi/8103.image_5F00_thumb_5F00_731B7A31.png" width="485" height="293" /></a></p>  <p>Or, if you prefer the raw data:</p>  <table style="line-height: normal; list-style-type: disc; width: ; border-collapse: collapse" border="0" cellspacing="0" cellpadding="0" width="229"><colgroup><col style="width: 86pt; mso-width-source: userset; mso-width-alt: 4169" width="114" /></colgroup><tbody>     <tr style="height: 15pt" height="20">       <td style="padding-left: 1px; width: ; padding-right: 1px; height: ; vertical-align: bottom; padding-top: 1px" height="20" width="114">&#160;</td>        <td style="padding-left: 1px; width: ; padding-right: 1px; vertical-align: bottom; padding-top: 1px" width="114"><font face="Calibri"><font style="font-size: 11pt" color="#000000">Read Throughput</font></font></td>     </tr>      <tr style="height: 15pt" height="20">       <td style="padding-left: 1px; padding-right: 1px; height: ; vertical-align: bottom; padding-top: 1px" height="20"><font face="Calibri"><font style="font-size: 11pt" color="#000000">Optimized XML</font></font></td>        <td style="padding-left: 1px; padding-right: 1px; vertical-align: bottom; padding-top: 1px" align="right"><font face="Calibri"><font style="font-size: 11pt" color="#000000">84141.3</font></font></td>     </tr>      <tr style="height: 15pt" height="20">       <td style="padding-left: 1px; padding-right: 1px; height: ; vertical-align: bottom; padding-top: 1px" height="20"><font face="Calibri"><font style="font-size: 11pt" color="#000000">Compressed XML</font></font></td>        <td style="padding-left: 1px; padding-right: 1px; vertical-align: bottom; padding-top: 1px" align="right"><font face="Calibri"><font style="font-size: 11pt" color="#000000">65799.71</font></font></td>     </tr>      <tr style="height: 15pt" height="20">       <td style="padding-left: 1px; padding-right: 1px; height: ; vertical-align: bottom; padding-top: 1px" height="20"><font face="Calibri"><font style="font-size: 11pt" color="#000000">CSV</font></font></td>        <td style="padding-left: 1px; padding-right: 1px; vertical-align: bottom; padding-top: 1px" align="right"><font face="Calibri"><font style="font-size: 11pt" color="#000000">35905.47</font></font></td>     </tr>      <tr style="height: 15pt" height="20">       <td style="padding-left: 1px; padding-right: 1px; height: ; vertical-align: bottom; padding-top: 1px" height="20"><font face="Calibri"><font style="font-size: 11pt" color="#000000">CSV-GZIP</font></font></td>        <td style="padding-left: 1px; padding-right: 1px; vertical-align: bottom; padding-top: 1px" align="right"><font face="Calibri"><font style="font-size: 11pt" color="#000000">34280.79</font></font></td>     </tr>   </tbody></table>  <p>Note that we only lose ~ 13% of our read throughput by leveraging the GZipStream class.&#160; That’s pretty awesome <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/metablogapi/3113.wlEmoticon-smile_00EDC02D.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-metablogapi/3113.wlEmoticon_2D00_smile_5F00_00EDC02D.png" /></p>  <table border="0" cellspacing="0" cellpadding="2" width="802"><tbody>     <tr>       <td valign="top" width="76"><img title="3d Glossy Blue Orbs Alphanumeric Lucinda Exclamation Point Icon" alt="3d Glossy Blue Orbs Alphanumeric Lucinda Exclamation Point Icon" src="http://icons.mysitemyway.com/wp-content/gallery/3d-glossy-blue-orbs-icons-alphanumeric/thumbs/thumbs_067865-3d-glossy-blue-orb-icon-alphanumeric-exclamation-point1.png" width="64" height="64" /></td>        <td valign="top" width="724">The numbers for our CSV reader weren’t actually all that good in comparison to the supposedly sucky XmlSerializer.&#160; Keep in mind that XmlSerializer is as <strong>optimized as it gets</strong>, and we haven’t <strong>done any optimization work on the CSV reader</strong>.&#160; Let’s dig a little deeper in to that code to see if we can’t get some solid performance improvements.           <br />          <br />It’s not measured in the test framework, but there’s a huge memory usage difference between the two (which makes sense, as XmlSerializer loads the whole thing into memory), Using the Red Gate Memory Profiler, companion tool to the Performance Profiler which I use extensively in the next section, the peak values are:           <br />          <br />          <table border="0" cellspacing="0" cellpadding="2" width="300"><tbody>             <tr>               <td valign="top" width="150"><font color="#ff0000">XmlSerializer</font></td>                <td valign="top" width="150"><font color="#ff0000"><strong>94 MB</strong></font></td>             </tr>              <tr>               <td valign="top" width="150">CSV reader</td>                <td valign="top" width="150">267 kB</td>             </tr>           </tbody></table>          <br />Looks like with some performance optimization, our CSV reader will be the winner!           <br /></td>     </tr>   </tbody></table>  <p>&#160;</p>  <h3>Stage 3 – Optimizing the Compressed CSV reader</h3>  <p>We’re now pretty close to our goals, but have plenty of room to push the performance envelope.&#160; Up to this point we’ve been using relatively simple measures and metrics to quantify and evaluate performance (file sizes via the <a href="http://msdn.microsoft.com/en-us/library/system.io.fileinfo.aspx">FileInfo</a> class, and elapsed time via the <a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx">Stopwatch</a> class).&#160; Now that we’re diving a bit deeper into performance tuning, it’s time to pull out the big guns.&#160; There are a number of excellent performance and profiling tools available for .NET (including the <a href="http://blogs.msdn.com/b/profiler/">Visual Studio Profiler</a>).&#160; My <strong>personal </strong>favorite is <a href="http://www.red-gate.com/">Red Gate’s</a> excellent, <a href="http://www.red-gate.com/products/dotnet-development/ants-performance-profiler/">ANTS Performance Profiler</a>, part of their line of <a href="http://www.red-gate.com/products/dotnet-development/">.NET Development tools</a>.&#160; </p>  <p>One of the reasons this is my go-to application for performance investigations is that when I’m working with customers whom don’t have (or can’t provide) an instrumented build, or cannot install Visual Studio on a live box – it’s a great lightweight experience for understanding how your application is burning CPU and memory.</p>  <p>To follow along through this next section, download an evaluation copy of the <a href="http://www.red-gate.com/products/dotnet-development/ants-performance-profiler/">ANTS Performance Profiler</a>.</p>  <p>The first thing we’ll do is turn off the other tests in the framework so we can focus on the Compressed CSV path, and disable the file writing (i.e. we just want to execute the file reading code path).&#160; To streamline this, we fork the framework into a a separate project, PerformanceTests_Profile.</p>  <p>Next, we run the test framework in the ANTS Performance Profiler:</p>  <ul>   <li>Start a copy of the ANTS Performance Profiler by clicking on <strong>Start</strong>, <strong>All Programs</strong>, <strong>Red Gate</strong>, <strong>ANTS Performance Profiler</strong>. </li>    <li>If the profiler configuration dialog (as per the image below) does not pop up, click on <strong>File</strong>, <strong>New Profiling Session</strong>. </li>    <li>In the .NET executable selection, type in the name of the executable to test (or use the ellipsis to bring up a file browse dialog). </li>    <li>Select the profiling mode <strong>Line-level and method-level timings; all methods (most detailed)</strong>. </li>    <li>Select the SQL and file I/O mode <strong>Do not record SQL and file I/O performance</strong>. </li>    <li>Click on <strong>Start Profiling</strong>. </li> </ul>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/metablogapi/3125.image_60D2B36F.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-metablogapi/3125.image_5F00_60D2B36F.png"><img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/metablogapi/4606.image_thumb_2BC6243F.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-metablogapi/4606.image_5F00_thumb_5F00_2BC6243F.png" width="694" height="523" /></a></p>  <p>The profiler will then start up the framework application, and read back the compressed CSV file.&#160; Wait until the profiler completes to get a full data set (note that this will take longer than normal due to the overhead of profiling).&#160; </p>  <p>Let’s start by looking at the Wall time view – ensure that the 3rd drop down box is set to wall-clock time.&#160; This shows two hot paths:</p>  <ul>   <li><strong>Waiting for Synchronization</strong>.&#160; This is busy-wait time while the process waits for the I/O infrastructure (as we’re using synchronous I/O). </li>    <li><strong>ISequenceRunner.ReadEventsBack</strong>.&#160; This is the interesting path right now – where are we spending time. </li> </ul>  <p>To focus on just our code paths, switch back to CPU time.&#160; Waiting for synchronization disappears, and we see MoveNext() – our enumerator method – popping to the top with 97% of time with children (remember that the .Count() method forces the enumerator to run through the entire file).&#160; This is where we’ll focus our efforts.</p>  <table border="0" cellspacing="0" cellpadding="2" width="802"><tbody>     <tr>       <td valign="top" width="76"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/perflogs/2476.weather_perf_csv_baseline.zip" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-perflogs/2476.weather_5F00_perf_5F00_csv_5F00_baseline.zip"><img title="3d Glossy Blue Orbs Business Typed Folded Page Corner Document Icon" alt="3d Glossy Blue Orbs Business Typed Folded Page Corner Document Icon" src="http://icons.mysitemyway.com/wp-content/gallery/3d-glossy-blue-orbs-icons-business/thumbs/thumbs_075750-3d-glossy-blue-orb-icon-business-document.png" width="64" height="64" /></a></td>        <td valign="top" width="724">         <p>Download the profile trace to walk through this section.&#160; We see the performance culprits being threefold:</p>          <ul>           <li>[35.8%] RuntimePropertyInfo.SetValue() </li>            <li>[19.6%] System.Convert.ChangeType() </li>            <li>[14.5%] DateTime.Parse() </li>         </ul>          <p>In order to get our performance up to where it needs to be, let’s focus on each of these in order (biggest bang for the buck first).</p>       </td>     </tr>   </tbody></table>  <h4>Performance fix 1 – Removing reflection / PropertyInfo.SetValue() and Convert.ChangeType()</h4>  <p>Our first approach will be to remove the use of reflection and change type for assigning values.&#160; Since we need to maintain a flexibility, we need another “generic” method of assigning values to variables.&#160; Since functional programming is cool, let’s approach this problem by defining a function delegate <strong><em>Action&lt;string[], T&gt; </em></strong>that is responsible for assigning values to an object of type T given an array of strings.&#160; </p>  <p>This involves updating the signature for ReadEvents&lt;T&gt; as below (the signature change on lines 1-2, and invoking the function delegate on line 25).</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:0043ed6a-58b4-4a7d-9491-d29ff0a129e7" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #ddd; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">public</span> <span style="color:#2b91af">IEnumerable</span>&lt;<span style="color:#2b91af">TypedEventPayload</span>&lt;T&gt;&gt; ReadEvents&lt;T&gt;(<span style="color:#2b91af">Stream</span> stream,</li> <li style="background: #f3f3f3">        <span style="color:#2b91af">Action</span>&lt;<span style="color:#0000ff">string</span>[], T&gt; assign) <span style="color:#0000ff">where</span> T : <span style="color:#0000ff">new</span>()</li> <li>{</li> <li style="background: #f3f3f3">    <span style="color:#2b91af">StreamReader</span> sr = <span style="color:#0000ff">new</span> <span style="color:#2b91af">StreamReader</span>(stream);</li> <li>    <span style="color:#2b91af">String</span> line = <span style="color:#0000ff">null</span>;</li> <li style="background: #f3f3f3">    <span style="color:#0000ff">var</span> fields = <span style="color:#0000ff">typeof</span>(T).GetProperties();</li> <li>    <span style="color:#0000ff">var</span> lastField = fields.Last();</li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="color:#0000ff">while</span> ((line = sr.ReadLine()) != <span style="color:#0000ff">null</span>)</li> <li style="background: #f3f3f3">    {</li> <li>        <span style="color:#0000ff">if</span> (line.StartsWith(<span style="color:#a31515">&quot;EventShape,&quot;</span>))</li> <li style="background: #f3f3f3">            <span style="color:#0000ff">continue</span>;</li> <li>        <span style="color:#0000ff">string</span>[] tokens = line.Split(<span style="color:#0000ff">new</span> <span style="color:#0000ff">char</span>[] { <span style="color:#a31515">&#39;,&#39;</span> });</li> <li style="background: #f3f3f3">        <span style="color:#2b91af">TypedEventPayload</span>&lt;T&gt; ep = <span style="color:#0000ff">new</span> <span style="color:#2b91af">TypedEventPayload</span>&lt;T&gt;();</li> <li>        ep.Payload = <span style="color:#0000ff">new</span> T();</li> <li style="background: #f3f3f3">&nbsp;</li> <li>        ep.Shape = (<span style="color:#2b91af">EventShape</span>)<span style="color:#2b91af">Enum</span>.Parse(<span style="color:#0000ff">typeof</span>(<span style="color:#2b91af">EventShape</span>), tokens[0]);</li> <li style="background: #f3f3f3">        ep.StartTime = <span style="color:#2b91af">DateTime</span>.Parse(tokens[1], <span style="color:#2b91af">CultureInfo</span>.CurrentCulture, <span style="color:#2b91af">DateTimeStyles</span>.AssumeUniversal);</li> <li>&nbsp;</li> <li style="background: #f3f3f3">        <span style="color:#0000ff">if</span> (<span style="color:#2b91af">String</span>.IsNullOrEmpty(tokens[2]))</li> <li>            ep.EndTime = ep.StartTime.AddTicks(1);</li> <li style="background: #f3f3f3">        <span style="color:#0000ff">else</span></li> <li>            ep.EndTime = <span style="color:#2b91af">DateTime</span>.Parse(tokens[2], <span style="color:#2b91af">CultureInfo</span>.CurrentCulture, <span style="color:#2b91af">DateTimeStyles</span>.AssumeUniversal);</li> <li style="background: #f3f3f3">&nbsp;</li> <li>        assign(tokens.Skip(3).ToArray(), ep.Payload);</li> <li style="background: #f3f3f3">&nbsp;</li> <li>        <span style="color:#0000ff">yield</span> <span style="color:#0000ff">return</span> ep;</li> <li style="background: #f3f3f3">    }</li> <li>}</li> </ol> </div> </div> </div>  <p>The function definition is fairly straightforward:</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:18c6bbba-f0e8-4e04-a372-868186eb4339" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #ddd; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">private</span> <span style="color:#2b91af">Action</span>&lt;<span style="color:#0000ff">string</span>[], <span style="color:#2b91af">WeatherReading</span>&gt; assign = (str, e) =&gt;</li> <li style="background: #f3f3f3">{</li> <li>    e.StationCode = <span style="color:#2b91af">Int32</span>.Parse(str[0]);</li> <li style="background: #f3f3f3">    e.Timestamp = <span style="color:#2b91af">DateTime</span>.Parse(str[1]);</li> <li>    e.Temperature = <span style="color:#2b91af">Double</span>.Parse(str[2]);</li> <li style="background: #f3f3f3">    e.DewpointTemperature = <span style="color:#2b91af">Double</span>.Parse(str[3]);</li> <li>    e.RelativeHumidity = <span style="color:#2b91af">Double</span>.Parse(str[4]);</li> <li style="background: #f3f3f3">&nbsp;</li> <li>    e.WindDirection = <span style="color:#2b91af">Double</span>.Parse(str[5]);</li> <li style="background: #f3f3f3">    e.WindSpeed = <span style="color:#2b91af">Double</span>.Parse(str[6]);</li> <li>    e.Visibility = <span style="color:#2b91af">Double</span>.Parse(str[7]);</li> <li style="background: #f3f3f3">    e.Humidex = <span style="color:#2b91af">Double</span>.Parse(str[8]);</li> <li>    e.WindChill = <span style="color:#2b91af">Double</span>.Parse(str[9]);</li> <li style="background: #f3f3f3">    e.WeatherConditions = <span style="color:#2b91af">Int32</span>.Parse(str[9]);</li> <li>};</li> </ol> </div> </div> </div>  <p>This preserves our need for the Csv reading code to be generic (as the parsing code is externally defined and passed in), as well as keeping complexity reasonable.&#160; Let’s have a look at our updated performance results.</p>  <table border="0" cellspacing="0" cellpadding="2" width="802"><tbody>     <tr>       <td valign="top" width="76"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/perflogs/4370.weather_perf_csv_perf_fix1.zip" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-perflogs/4370.weather_5F00_perf_5F00_csv_5F00_perf_5F00_fix1.zip"><img title="3d Glossy Blue Orbs Business Typed Folded Page Corner Document Icon" alt="3d Glossy Blue Orbs Business Typed Folded Page Corner Document Icon" src="http://icons.mysitemyway.com/wp-content/gallery/3d-glossy-blue-orbs-icons-business/thumbs/thumbs_075750-3d-glossy-blue-orb-icon-business-document.png" width="64" height="64" /></a></td>        <td valign="top" width="724">         <table border="0" cellspacing="0" cellpadding="2" width="300"><tbody>             <tr>               <td valign="top" width="67">Before:</td>                <td valign="top" width="233">33920 events / second</td>             </tr>              <tr>               <td valign="top" width="67">After:</td>                <td valign="top" width="233"><strong>65804 events / second</strong></td>             </tr>           </tbody></table>          <p>Much better!&#160; Download the profile trace to walk through this section.&#160; We see the performance culprits being threefold:</p>          <ul>           <li>[29.8%] Assign function (of which 14.9% is DateTime.Parse) </li>            <li>[15.0%] DateTime.Parse </li>            <li>[ 7.6%] Double.Parse() </li>         </ul>          <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/metablogapi/7848.image_24A6E7C7.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-metablogapi/7848.image_5F00_24A6E7C7.png"><img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/metablogapi/8510.image_thumb_64049B57.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-metablogapi/8510.image_5F00_thumb_5F00_64049B57.png" width="244" height="131" /></a></p>       </td>     </tr>   </tbody></table>  <p>Based on our profiler results, parsing DateTime values account for 30% of our current CPU time.&#160; We have a number of potential performance fixes we can apply here:</p>  <ul>   <li>Convert the DateTime storage format to a more easily parsed value (such as raw ticks) </li>    <li>Parse the date time value using a more optimal parsing routine (such as ParseExact) </li> </ul>  <h4>Performance fix 2 – Better DateTime parsing</h4>  <p>Let’s start by investigating the use of a more optimized DateTime parsing routine – that provided by the <a href="http://msdn.microsoft.com/en-us/library/system.xml.xmlconvert.aspx">XmlConvert</a> class.&#160; As XML serialization has been heavily optimized as .NET has evolved, it stands to reason that there may be some optimal parsing algorithms buried in there.&#160; Let’s find out <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/metablogapi/3113.wlEmoticon-smile_00EDC02D.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-metablogapi/3113.wlEmoticon_2D00_smile_5F00_00EDC02D.png" /></p>  <p>In order to use XmlConvert.ToDateTime, we also need to change the format in which we encode date time values by altering the WriteEvents method and recreating the data file:</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:677d99a6-bbc1-4010-ab63-8da7e2fd7744" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #ddd; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="color:#008000">// Write out the event kind, start time and end time                </span></li> <li style="background: #f3f3f3">sb.Append(<span style="color:#a31515">&quot;Point,&quot;</span>);</li> <li>sb.Append(<span style="color:#2b91af">XmlConvert</span>.ToString(dtFunc(e)));</li> <li style="background: #f3f3f3">sb.Append(<span style="color:#a31515">&quot;,,&quot;</span>);</li> <li>&nbsp;</li> <li style="background: #f3f3f3"><span style="color:#0000ff">foreach</span> (<span style="color:#0000ff">var</span> o <span style="color:#0000ff">in</span> fields)</li> <li>{</li> <li style="background: #f3f3f3">    <span style="color:#008000">// Need special type conversion for DateTime fields</span></li> <li>    <span style="color:#0000ff">if</span> (o.PropertyType == <span style="color:#0000ff">typeof</span>(<span style="color:#2b91af">DateTime</span>))</li> <li style="background: #f3f3f3">    {</li> <li>        sb.Append(<span style="color:#2b91af">XmlConvert</span>.ToString((<span style="color:#2b91af">DateTime</span>)</li> <li style="background: #f3f3f3">            o.GetValue(e, <span style="color:#0000ff">null</span>), <span style="color:#2b91af">XmlDateTimeSerializationMode</span>.Utc));</li> <li>    }</li> <li style="background: #f3f3f3">    <span style="color:#0000ff">else</span></li> <li>        sb.Append(o.GetValue(e, <span style="color:#0000ff">null</span>).ToString());</li> <li style="background: #f3f3f3">    <span style="color:#0000ff">if</span> (o != lastField)</li> <li>        sb.Append(<span style="color:#a31515">&quot;,&quot;</span>);</li> <li style="background: #f3f3f3">}</li> </ol> </div> </div> </div>  <p>Note the use of XmlConvert on line 3 (using <a href="http://msdn.microsoft.com/en-us/library/bb517387.aspx">ToString(DateTimeOffset)</a>) and on line 11 (using <a href="http://msdn.microsoft.com/en-us/library/ms162344.aspx">ToString(DateTime, XmlDateTimeSerializationMode)</a>).</p>  <p>Next, we need to update our parsing methods in ReadEvents&lt;T&gt; </p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:3b4a8d7f-c46d-41ed-9896-ed3a260f5316" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #ddd; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;"> <li>ep.StartTime = <span style="color:#2b91af">XmlConvert</span>.ToDateTime(tokens[1], </li> <li style="background: #f3f3f3">              <span style="color:#2b91af">XmlDateTimeSerializationMode</span>.Utc);</li> </ol> </div> </div> </div>  <p>And in the assignment function:</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:4e6837c4-34f0-449c-8d4a-5a6e71cd27b2" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #ddd; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">private</span> <span style="color:#2b91af">Action</span>&lt;<span style="color:#0000ff">string</span>[], <span style="color:#2b91af">WeatherReading</span>&gt; assign = (str, e) =&gt;</li> <li style="background: #f3f3f3">{            </li> <li>    e.StationCode = <span style="color:#2b91af">Int32</span>.Parse(str[0]);</li> <li style="background: #f3f3f3">    e.Timestamp = <span style="color:#2b91af">XmlConvert</span>.ToDateTime(str[1], </li> <li>        <span style="color:#2b91af">XmlDateTimeSerializationMode</span>.Utc);</li> <li style="background: #f3f3f3">    e.Temperature = <span style="color:#2b91af">Double</span>.Parse(str[2]);</li> <li>    e.DewpointTemperature = <span style="color:#2b91af">Double</span>.Parse(str[3]);</li> <li style="background: #f3f3f3">    e.RelativeHumidity = <span style="color:#2b91af">Double</span>.Parse(str[4]);</li> <li>&nbsp;</li> <li style="background: #f3f3f3">    e.WindDirection = <span style="color:#2b91af">Double</span>.Parse(str[5]);</li> <li>    e.WindSpeed = <span style="color:#2b91af">Double</span>.Parse(str[6]);</li> <li style="background: #f3f3f3">    e.Visibility = <span style="color:#2b91af">Double</span>.Parse(str[7]);</li> <li>    e.Humidex = <span style="color:#2b91af">Double</span>.Parse(str[8]);</li> <li style="background: #f3f3f3">    e.WindChill = <span style="color:#2b91af">Double</span>.Parse(str[9]);</li> <li>    e.WeatherConditions = <span style="color:#2b91af">Int32</span>.Parse(str[9]);</li> <li style="background: #f3f3f3">};</li> </ol> </div> </div> </div>  <p>Let’s go ahead and run this and observe the results.</p>  <p>   <table border="0" cellspacing="0" cellpadding="2" width="802"><tbody>       <tr>         <td valign="top" width="76"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/perflogs/6014.weather_perf_csv_perf_fix2.zip" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-perflogs/6014.weather_5F00_perf_5F00_csv_5F00_perf_5F00_fix2.zip"><img title="3d Glossy Blue Orbs Business Typed Folded Page Corner Document Icon" alt="3d Glossy Blue Orbs Business Typed Folded Page Corner Document Icon" src="http://icons.mysitemyway.com/wp-content/gallery/3d-glossy-blue-orbs-icons-business/thumbs/thumbs_075750-3d-glossy-blue-orb-icon-business-document.png" width="64" height="64" /></a></td>          <td valign="top" width="724">           <table border="0" cellspacing="0" cellpadding="2" width="300"><tbody>               <tr>                 <td valign="top" width="67">Before:</td>                  <td valign="top" width="233">65804 events / second</td>               </tr>                <tr>                 <td valign="top" width="67">After:</td>                  <td valign="top" width="233"><strong>87744 events / second</strong></td>               </tr>             </tbody></table>            <p>Now we’re getting there! Download the profile trace to walk through this section.&#160; We see the performance culprits being twofold:</p>            <ul>             <li>[21.8%] XmlConvert.DateTime for retrieving the event start time value. </li>              <li>[21.2%] Assign function (10% of which is Double.Parse(), and only 2.215% of which is XmlConvert.ToDateTime). </li>           </ul>            <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/metablogapi/3323.image_71D6E152.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-metablogapi/3323.image_5F00_71D6E152.png"><img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/metablogapi/2727.image_thumb_18A4F793.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-metablogapi/2727.image_5F00_thumb_5F00_18A4F793.png" width="244" height="126" /></a></p>            <p><strong>Weird</strong>.&#160; Apparently the format in which we’re storing the StartTime values is more expensive to parse (it stands to reason they’re different – StartTime value is being parsed from a DateTimeOffset record.&#160; Wait – we wrote out a DateTimeOffset, but are reading in a DateTime.&#160; <strong>Could that make a difference?</strong></p>         </td>       </tr>     </tbody></table> </p>  <h4>Performance fix 3 – Parsing StartTime - DateTimeOffsets not DateTimes&#160; </h4>  <p>Going back to our change in ReadEvents&lt;T&gt;(), let’s modify it to use XmlConvert.ToDateTimeOffset instead.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:0a070312-3151-48ad-97a2-fb8b0718998e" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #ddd; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;"> <li> ep.StartTime = <span style="color:#2b91af">XmlConvert</span>.ToDateTimeOffset(tokens[1]);</li> </ol> </div> </div> </div>  <table border="0" cellspacing="0" cellpadding="2" width="802"><tbody>     <tr>       <td valign="top" width="76"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/perflogs/6507.weather_perf_csv_perf_fix3.zip" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-perflogs/6507.weather_5F00_perf_5F00_csv_5F00_perf_5F00_fix3.zip"><img title="3d Glossy Blue Orbs Business Typed Folded Page Corner Document Icon" alt="3d Glossy Blue Orbs Business Typed Folded Page Corner Document Icon" src="http://icons.mysitemyway.com/wp-content/gallery/3d-glossy-blue-orbs-icons-business/thumbs/thumbs_075750-3d-glossy-blue-orb-icon-business-document.png" width="64" height="64" /></a></td>        <td valign="top" width="724">         <table border="0" cellspacing="0" cellpadding="2" width="300"><tbody>             <tr>               <td valign="top" width="67">Before:</td>                <td valign="top" width="233">87744 events / second</td>             </tr>              <tr>               <td valign="top" width="67">After:</td>                <td valign="top" width="233"><strong>116392 events / second</strong></td>             </tr>           </tbody></table>          <p>Wow.&#160; <strong>Huge</strong> difference!&#160; Download the profile trace to walk through this section.&#160; We now see the performance culprits being centered in the assign function:</p>          <ul>           <li>[13.1%] Double.Parse()&#160; </li>            <li>[3.3%] Int32.Parse(). </li>         </ul>          <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/metablogapi/0412.image_4A9C981D.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-metablogapi/0412.image_5F00_4A9C981D.png"><img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/metablogapi/7357.image_thumb_0A667EA3.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-metablogapi/7357.image_5F00_thumb_5F00_0A667EA3.png" width="244" height="131" /></a></p>          <p>Almost there.&#160; Let’s make a few small changes to finish this out – let’s switch in the XmlConvert functions for Double.Parse() and Int32.Parse().</p>       </td>     </tr>   </tbody></table>  <h4>Performance fix 4 – Parsing numbers with XmlConvert</h4>  <p>Ok, let’s modify the assignment method to use XmlConvert instead of Double.Parse:</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:d50ac5a8-e45c-4e12-b03e-2caa46bb56b0" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #ddd; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">private</span> <span style="color:#2b91af">Action</span>&lt;<span style="color:#0000ff">string</span>[], <span style="color:#2b91af">WeatherReading</span>&gt; assign = (str, e) =&gt;</li> <li style="background: #f3f3f3">{            </li> <li>    e.StationCode = <span style="color:#2b91af">Int32</span>.Parse(str[0]);</li> <li style="background: #f3f3f3">    e.Timestamp = <span style="color:#2b91af">XmlConvert</span>.ToDateTime(str[1], </li> <li>        <span style="color:#2b91af">XmlDateTimeSerializationMode</span>.Utc);</li> <li style="background: #f3f3f3">    e.Temperature = <span style="color:#2b91af">XmlConvert</span>.ToDouble(str[2]);</li> <li>    e.DewpointTemperature = <span style="color:#2b91af">XmlConvert</span>.ToDouble(str[3]);</li> <li style="background: #f3f3f3">    e.RelativeHumidity = <span style="color:#2b91af">XmlConvert</span>.ToDouble(str[4]);</li> <li>&nbsp;</li> <li style="background: #f3f3f3">    e.WindDirection = <span style="color:#2b91af">XmlConvert</span>.ToDouble(str[5]);</li> <li>    e.WindSpeed = <span style="color:#2b91af">XmlConvert</span>.ToDouble(str[6]);</li> <li style="background: #f3f3f3">    e.Visibility = <span style="color:#2b91af">XmlConvert</span>.ToDouble(str[7]);</li> <li>    e.Humidex = <span style="color:#2b91af">XmlConvert</span>.ToDouble(str[8]);</li> <li style="background: #f3f3f3">    e.WindChill = <span style="color:#2b91af">XmlConvert</span>.ToDouble(str[9]);</li> <li>    e.WeatherConditions = <span style="color:#2b91af">Int32</span>.Parse(str[9]);</li> <li style="background: #f3f3f3">};</li> </ol> </div> </div> </div>  <table border="0" cellspacing="0" cellpadding="2" width="802"><tbody>     <tr>       <td valign="top" width="76"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/perflogs/5531.weather_perf_csv_perf_fix4.zip" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-perflogs/5531.weather_5F00_perf_5F00_csv_5F00_perf_5F00_fix4.zip"><img title="3d Glossy Blue Orbs Business Typed Folded Page Corner Document Icon" alt="3d Glossy Blue Orbs Business Typed Folded Page Corner Document Icon" src="http://icons.mysitemyway.com/wp-content/gallery/3d-glossy-blue-orbs-icons-business/thumbs/thumbs_075750-3d-glossy-blue-orb-icon-business-document.png" width="64" height="64" /></a></td>        <td valign="top" width="724">         <table border="0" cellspacing="0" cellpadding="2" width="300"><tbody>             <tr>               <td valign="top" width="67">Before:</td>                <td valign="top" width="233">116392 events / second</td>             </tr>              <tr>               <td valign="top" width="67">After:</td>                <td valign="top" width="233"><strong><font color="#ff0000">112083 events / second</font></strong></td>             </tr>           </tbody></table>          <p>Uh-oh – <strong><font color="#ff0000">performance regression</font></strong>!&#160; Looks like the Double.Parse() is the better function&#160; Download the profile trace to walk through this section.&#160; </p>          <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/metablogapi/7433.image_6A4B71E5.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-metablogapi/7433.image_5F00_6A4B71E5.png"><img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/metablogapi/6355.image_thumb_2A15586B.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-metablogapi/6355.image_5F00_thumb_5F00_2A15586B.png" width="244" height="131" /></a></p>          <p>Looks like our version 3 is the most performant reader.&#160; <strong>Having achieved all of our performance goals – let’s call it done!</strong></p>       </td>     </tr>   </tbody></table>  <h3>Stage 4 – Review</h3>  <p>Now that we’ve finished our performance exploration, let’s run the full test suite and review our results and key learnings.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/metablogapi/7026.image_22F61BF3.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-metablogapi/7026.image_5F00_22F61BF3.png"><img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/metablogapi/8507.image_thumb_30C861EE.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-metablogapi/8507.image_5F00_thumb_5F00_30C861EE.png" width="485" height="293" /></a></p>  <p>Or, for the raw data:</p>  <table style="line-height: normal; list-style-type: disc; width: ; border-collapse: collapse" border="0" cellspacing="0" cellpadding="0" width="353"><colgroup><col style="width: 93pt; mso-width-source: userset; mso-width-alt: 4534" width="124" /><col style="width: 172pt; mso-width-source: userset; mso-width-alt: 8374" width="229" /></colgroup><tbody>     <tr style="height: 15pt" height="20">       <td style="padding-left: 1px; width: ; padding-right: 1px; height: ; vertical-align: bottom; padding-top: 1px" height="20" width="124"><font face="Calibri"><font style="font-size: 11pt" color="#000000">Approach</font></font></td>        <td style="padding-left: 1px; width: ; padding-right: 1px; vertical-align: bottom; padding-top: 1px" width="229"><font face="Calibri"><font style="font-size: 11pt" color="#000000">Read Throughput (Events / Second)</font></font></td>     </tr>      <tr style="height: 15pt" height="20">       <td style="padding-left: 1px; padding-right: 1px; height: ; vertical-align: bottom; padding-top: 1px" height="20"><font face="Calibri"><font style="font-size: 11pt" color="#000000">CSV-GZIP-Baseline</font></font></td>        <td style="padding-left: 1px; padding-right: 1px; vertical-align: bottom; padding-top: 1px" align="right"><font face="Calibri"><font style="font-size: 11pt" color="#000000">34066.12</font></font></td>     </tr>      <tr style="height: 15pt" height="20">       <td style="padding-left: 1px; padding-right: 1px; height: ; vertical-align: bottom; padding-top: 1px" height="20"><font face="Calibri"><font style="font-size: 11pt" color="#000000">CSV-GZIP-PerfFix1</font></font></td>        <td style="padding-left: 1px; padding-right: 1px; vertical-align: bottom; padding-top: 1px" align="right"><font face="Calibri"><font style="font-size: 11pt" color="#000000">66975.93</font></font></td>     </tr>      <tr style="height: 15pt" height="20">       <td style="padding-left: 1px; padding-right: 1px; height: ; vertical-align: bottom; padding-top: 1px" height="20"><font face="Calibri"><font style="font-size: 11pt" color="#000000">CSV-GZIP-PerfFix2</font></font></td>        <td style="padding-left: 1px; padding-right: 1px; vertical-align: bottom; padding-top: 1px" align="right"><font face="Calibri"><font style="font-size: 11pt" color="#000000">87323.21</font></font></td>     </tr>      <tr style="height: 15pt" height="20">       <td style="padding-left: 1px; padding-right: 1px; height: ; vertical-align: bottom; padding-top: 1px" class="xl65" height="20"><font face="Calibri"><font style="font-size: 11pt" color="#000000"><strong>CSV-GZIP-PerfFix3</strong></font></font></td>        <td style="padding-left: 1px; padding-right: 1px; vertical-align: bottom; padding-top: 1px" class="xl65" align="right"><font face="Calibri"><font style="font-size: 11pt" color="#000000"><strong>118614.56</strong></font></font></td>     </tr>      <tr style="height: 15pt" height="20">       <td style="padding-left: 1px; padding-right: 1px; height: ; vertical-align: bottom; padding-top: 1px" height="20"><font face="Calibri"><font style="font-size: 11pt" color="#000000">CSV-GZIP-PerfFix4</font></font></td>        <td style="padding-left: 1px; padding-right: 1px; vertical-align: bottom; padding-top: 1px" align="right"><font face="Calibri"><font style="font-size: 11pt" color="#000000">112726.88</font></font></td>     </tr>   </tbody></table>  <p>The key learnings are:</p>  <ul>   <li><strong>Know what to measure</strong>.&#160; Understand what the key performance metrics are, and their relative priority.&#160; If you don’t understand where you’re going, you won’t know when you’re there. </li>    <li><strong>Know how to measure how you got there</strong>.&#160; Having the right measurement framework in place (matching up with your performance metrics), and the right tooling is <strong>critical</strong>!&#160; <ul>       <li>In this case we were measuring for performance, so a performance profiler was the critical tool that let us achieve a 4x performance gain with about half an hour’s worth of work.&#160; </li>        <li>Having this detailed, repeatable insight is not an option – if you want to be able to tackle performance issues with confidence (and deliver on your projects) you MUST have the right tools, and be able to understand how to profile and tune your code. </li>     </ul>   </li>    <li><strong>Know when to stop</strong>.&#160; Performance tuning can become a never ending death spiral if you let it.&#160; Understand your performance goals, work towards them, but realize when you start encountering regressions past your performance goals. </li>    <li>It’s a balance between conflicting priorities.&#160; </li> </ul>  <p>For more reading on Red Gate’s ANTS Performance profiler check out:</p>  <ul>   <li><strong><a href="http://www.red-gate.com/products/dotnet-development/ants-performance-profiler/">ANTS Performance Profiler 6.1</a></strong> </li>    <li><strong><a href="http://www.red-gate.com/supportcenter/Content?p=ANTS%20Performance%20Profiler&amp;c=ANTS_Performance_Profiler/help/6.1/app_Worked_example_performance.htm&amp;toc=ANTS_Performance_Profiler/help/6.1/toc125374.htm">Learning ANTS Performance Profiler - 6.1 - Worked example: profiling the performance of an application</a></strong> </li> </ul>]]></content:encoded>
    </item>
    <item>
      <title>Attending and presenting at SQL PASS 2010 next week</title>
      <link>https://docs.microsoft.com/archive/blogs/masimms/attending-and-presenting-at-sql-pass-2010-next-week</link>
      <pubDate>Fri, 05 Nov 2010 17:36:40 GMT</pubDate>
      <dc:creator><![CDATA[Mark Simms [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/masimms/2010/11/05/attending-and-presenting-at-sql-pass-2010-next-week/</guid>
      <description><![CDATA[A number of us will be attending SQL PASS 2010 next week, both presenting some great content around...]]></description>
      <content:encoded><![CDATA[<p>A number of us will be attending <a href="http://www.sqlpass.org/summit/na2010/">SQL PASS 2010</a> next week, both presenting some great content around AppFabric, StreamInsight and SQL Server, and hanging out with our <a href="http://sqlcat.com/">SQLCAT</a> colleagues (wearing the same shiny green shirts!) in the SQL Server Clinic and Ask-The-Experts.&#160; We’ll be presenting:</p>  <h4><a href="http://sqlpass.eventpoint.com/topic/details/AD485A">AD485A SQLCAT: Next Generation Real Time Data Processing using StreamInsight</a></h4>  <p><strong>Thursday, November 11 4:00 PM - 5:15 PM </strong></p>  <p>StreamInsight ships with SQL Server 2008 R2, and provides complex event processing for tackling high volume, low latency analytics and data processing challenges. This talk will explain the business goals and target scenarios for StreamInsight, its architecture, and how to leverage StreamInsight to complement extant data processing and BI capabilities by exploring a series of customer implementations (including Sunday Night Football, and the 2010 Winter Olympics) for large scale real time web analytics.</p>  <h4><a href="http://sqlpass.eventpoint.com/topic/details/AD386A">AD386A SQLCAT: Optimizing application workload &amp; performance by leveraging AppFabric Cache along with SQL Server</a></h4>  <p><strong>Tuesday, November 9 3:00 PM - 4:15 PM</strong></p>  <p>Today, more and more data is being exposed via interactive web applications such as social networking, news, sports, video sharing, etc. Such web sites can now be accessed via different devices such as mobile phones, netbooks and easily exposed to 1000s of users. Hence, application architectures must leverage distributed application caching along with the database tier for building highly scalable, high throughput and highly available systems. In this session, we will cover some of the lessons learned based on customer engagements for AppFabric Cache, Microsoft's distributed caching solution, with some performance data.</p>  <h4><a href="http://sqlpass.eventpoint.com/topic/details/AD211CT">AD211CT AppFabric Cache and SQL Server 2008</a></h4>  <p><strong>Wednesday, November 10 1:30 PM - 2:10 PM </strong></p>  <p>With all the hype about NoSQL going around in the SQL community its about time we looked at a Microsoft's distributed cache-aside solution, AppFabric Cache. In this session we will briefly go over what AppFabric Cache is, what it can and cannot do, as well as some of the compelling features that make it a complimentary product to SQL Server. We will go over some real-world examples on how AppFabric Cache can co-exist with SQL Server and increase performance. In addition, we will compare the speed of the AppFabric Cache in comparison to SQL Server 2008 in both queries and inserts/updates. This chalk-talk will go more in-depth into some of the information presented in the SQLCAT Optimizing application workload &amp; performance by leveraging AppFabric Cache along with SQL Server session.</p>  <p>In addition, don’t forget to check out all of the great SQLCAT presentations!</p>]]></content:encoded>
    </item>
    <item>
      <title>See you at PASS next week – presenting on StreamInsight and real-time analytics</title>
      <link>https://docs.microsoft.com/archive/blogs/masimms/see-you-at-pass-next-week-presenting-on-streaminsight-and-real-time-analytics</link>
      <pubDate>Fri, 05 Nov 2010 16:54:42 GMT</pubDate>
      <dc:creator><![CDATA[Mark Simms [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/masimms/2010/11/05/see-you-at-pass-next-week-presenting-on-streaminsight-and-real-time-analytics/</guid>
      <description><![CDATA[While a pile of folks are off in Europe delivering some great content at TechED Europe with some...]]></description>
      <content:encoded><![CDATA[<p>While a pile of folks are off in Europe delivering some great content at <a href="http://europe.msteched.com/default.aspx">TechED Europe</a> with some great sessions:</p>  <ul>   <li>     <h5>DAT301 - Introduction to Complex Event Processing with SQL Server 2008 R2 StreamInsight</h5>   </li>    <li>     <h5>DAT301-LNC - Building Operational Intelligence Solutions with Microsoft SQL Server and StreamInsight</h5>   </li>    <li>     <h5>DAT302 - Advanced SQL Server 2008 R2 StreamInsight Query Design Techniques</h5>   </li> </ul>  <h5><font style="font-weight: normal">I’ll be at SQL PASS 2010 with the rest of my CAT (SQL and AppFabric) folks, hanging out in the SQL clinic and discussing interesting StreamInsight scenarios and solutions.&#160; I’ll be presenting a <a href="http://sqlpass.eventpoint.com/topic/details/AD485A">StreamInsight session on Thursday</a> about some of the cool stuff we’ve been doing regarding real-time web analytics and telemetry (that I’ve been alluding to in a few recent blog posts).</font></h5>  <p>Hope to see folks there!</p>]]></content:encoded>
    </item>
    <item>
      <title>Two new blog posts on StreamInsight over on the AppFabric CAT Blog</title>
      <link>https://docs.microsoft.com/archive/blogs/masimms/two-new-blog-posts-on-streaminsight-over-on-the-appfabric-cat-blog</link>
      <pubDate>Sat, 23 Oct 2010 10:08:00 GMT</pubDate>
      <dc:creator><![CDATA[Mark Simms [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/masimms/2010/10/23/two-new-blog-posts-on-streaminsight-over-on-the-appfabric-cat-blog/</guid>
      <description><![CDATA[Two new blog posts over on the AppFabric CAT blog on StreamInsight:


StreamInsight: Obscure LINQ...]]></description>
      <content:encoded><![CDATA[<p>Two new blog posts over on the AppFabric CAT blog on StreamInsight:</p>
<ul>
<li>
<p><a href="http://blogs.msdn.com/b/appfabriccat/archive/2010/10/23/streaminsight-obscure-linq-error-the-field-key-of-type-ikey-1-either-contains-a-nested-member-or-is-a-type-that-is-not-supported-as-event-type-field.aspx">StreamInsight: Obscure LINQ error - The field 'Key' of type 'IKey`1' either contains a nested member, or is a type that is not supported as event type field</a>.&nbsp; A walkthrough of resolving a little issue I ran into while building out a project this week, related to proper use and definition of grouping keys.</p>
</li>
<li>
<p><a href="http://blogs.msdn.com/b/appfabriccat/archive/2010/10/21/streaminsight-getting-started-with-using-the-event-flow-debugger-viewing-diagnostics-and-exposing-the-management-service.aspx">StreamInsight: Getting started with using the (Event Flow) debugger, viewing diagnostics, and exposing the management service.</a>&nbsp; Everything you ever wanted to know about ensuring you can connect to the StreamInsight management service with the Event Flow Debugger.</p>
</li>
</ul>]]></content:encoded>
    </item>
    <item>
      <title>StreamInsight and reference data (lists, databases, etc)</title>
      <link>https://docs.microsoft.com/archive/blogs/masimms/streaminsight-and-reference-data-lists-databases-etc</link>
      <pubDate>Wed, 13 Oct 2010 13:11:21 GMT</pubDate>
      <dc:creator><![CDATA[Mark Simms [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/masimms/2010/10/13/streaminsight-and-reference-data-lists-databases-etc/</guid>
      <description><![CDATA[Using reference data in StreamInsight is a very common scenarios; some examples would be:...]]></description>
      <content:encoded><![CDATA[<p>Using reference data in StreamInsight is a very common scenarios; some examples would be:</p>  <ul>   <li>Monitoring process control event streams for values that exceed a given threshold (for example, a valve’s pressure exceeding a certain safety threshold).</li>    <li>Enriching utility usage information in a smart metering scenario with user and geography information (for example, to allow visualization of power usage by geography).</li> </ul>  <p>This reference data is commonly held in some form of repository, such as SQL Server, a process historian’s metadata store (e.g. OSIsoft’s PI Asset Framework), which then needs to be integrated into a StreamInsight query.</p>  <p>In my <a href="http://blogs.msdn.com/b/appfabriccat/archive/2010/10/05/streaminsight-synchronizing-slow-moving-reference-streams-with-fast-moving-data-streams-time-import.aspx">previous post</a>, I showed how to use the TimeImport capability on streams to synchronize a slow moving reference stream with a fast moving data stream.&#160; I did not, however, walk through the process of creating a reference stream from a relatively static source (such as a database table or file).&#160; I intend to now correct that minor, and somewhat deliberate oversight <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/metablogapi/8461.wlEmoticon-smile_3AA285AE.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-metablogapi/8461.wlEmoticon_2D00_smile_5F00_3AA285AE.png" /></p>  <p>The project referenced in this blog post, along with the source data files is available <a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/2018.BlogStaticReferenceData.zip" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98/2018.BlogStaticReferenceData.zip">here</a>.</p>  <p>Reference data can be integrated into StreamInsight in a couple of different ways, each with their own pros and cons:</p>  <table border="0" cellspacing="0" cellpadding="2" width="583"><tbody>     <tr>       <td valign="top" width="177">Technique</td>        <td valign="top" width="178">Pros</td>        <td valign="top" width="226">Cons</td>     </tr>      <tr>       <td valign="top" width="177">         <ul>           <li>User-defined lookup function </li>         </ul>       </td>        <td valign="top" width="178">         <ul>           <li>Relatively simple to implement </li>         </ul>       </td>        <td valign="top" width="226">         <ul>           <li>Not suitable for large dynamic data sets or data that changes over time </li>            <li>Cumbersome to import more than one data element </li>            <li>Cannot take advantage of or incorporate stream data </li>         </ul>       </td>     </tr>      <tr>       <td valign="top" width="177">         <ul>           <li>Reference data stream </li>         </ul>       </td>        <td valign="top" width="178">         <ul>           <li>Seamless integration with StreamInsight query experience </li>            <li>Very performant and flexible </li>         </ul>       </td>        <td valign="top" width="226">         <ul>           <li>Additional work required to import and maintain the stream </li>         </ul>       </td>     </tr>   </tbody></table>  <p>Let’s look at an example of each technique, step by step.&#160; </p>  <h3>The Scenario</h3>  <p>For this illustration, let’s consider the following scenario:</p>  <ul>   <li>Stream of data events, each containing a user ID, an activity code and a status (user 7, logged in, success). </li>    <li>Set of user metadata, contained in a file (for the purposes of illustration – a database would be a more likely source).&#160; This metadata contains information such as user ID, user name, etc. </li>    <li>Want to annotate the data events with the user metadata. </li> </ul>  <p>We’ll use the following data sets:</p>  <p><strong>Data Events</strong></p>  <table border="0" cellspacing="0" cellpadding="2" width="514"><tbody>     <tr>       <td valign="top" width="129">Start Time</td>        <td valign="top" width="56">End Time</td>        <td valign="top" width="57">User Id</td>        <td valign="top" width="85">Activity Code</td>        <td valign="top" width="185">Status</td>     </tr>      <tr>       <td valign="top" width="129">         <p>6/25/2009 0:00:00</p></td>               <td valign="top" width="56">&nbsp;</td>        <td valign="top" width="57">1</td>        <td valign="top" width="85">Logon</td>        <td valign="top" width="185">Success</td>     </tr>      <tr>       <td valign="top" width="129">         <p>6/25/2009 0:00:01</p></td>               <td valign="top" width="56">&nbsp;</td>        <td valign="top" width="57">2</td>        <td valign="top" width="85">Logon</td>        <td valign="top" width="185">Fail</td>     </tr>      <tr>       <td valign="top" width="129">         <p>6/25/2009 0:00:05</p></td>               <td valign="top" width="56">&nbsp;</td>        <td valign="top" width="57">1</td>        <td valign="top" width="91">Browse</td>        <td valign="top" width="185">Success</td>     </tr>      <tr>       <td valign="top" width="129">         <p>6/25/2009 0:00:06 </p></td>               <td valign="top" width="56">&nbsp;</td>        <td valign="top" width="57">2</td>        <td valign="top" width="91">Logon</td>        <td valign="top" width="185">Success</td>     </tr>   </tbody></table>  <p>Or, in the .csv format that we’ll use:</p>  <table border="1"><tbody>     <tr>       <td>         <pre>StartTime,EndTime,UserId,ActivityCode,Status
6/25/2009 0:00:00,,1,Logon,Success
6/25/2009 0:00:01,,2,Logon,Fail
6/25/2009 0:00:05,,1,Browse,Success
6/25/2009 0:00:06,,2,Logon,Success</pre>
      </td>
    </tr>
  </tbody></table>

<p><strong>Reference Events</strong></p>

<table border="0" cellspacing="0" cellpadding="2" width="450"><tbody>
    <tr>
      <td valign="top" width="163">Start Time</td>

      <td valign="top" width="67">End Time</td>

      <td valign="top" width="65">User Id</td>

      <td valign="top" width="86">User Name</td>

      <td valign="top" width="67">Location</td>
    </tr>

    <tr>
      <td valign="top" width="163">
        <p>6/25/2009 0:00:00</p>
      </td>

      


      <td valign="top" width="72">&nbsp;</td>

      <td valign="top" width="71">1</td>

      <td valign="top" width="95">Fred Jones</td>

      <td valign="top" width="84">Seattle</td>
    </tr>

    <tr>
      <td valign="top" width="163">
        <p>6/25/2009 0:00:01</p>
      </td>

      <td valign="top" width="72">&nbsp;</td>

      <td valign="top" width="71">2</td>

      <td valign="top" width="95">Bob Murphy</td>

      <td valign="top" width="84">Portland</td>
    </tr>
  </tbody></table>

<p>Or, in the .csv format that we’ll use:</p>

<table border="1"><tbody>
    <tr>
      <td>
        <pre>StartTime,EndTime,UserId,UserName,Location
6/24/2009 0:00:00,,1,Fred Jones,Seattle
6/24/2009 0:00:01,,2,Bob Murphy,Portland</pre>
      </td>
    </tr>
  </tbody></table>

<br />

<h3>User-Defined Lookup Function</h3>

<p>With a user defined lookup function, we need to load the list of metadata into an associative array (i.e. a hashtable), and create a lookup function that allows us to grab user metadata from the dictionary on demand.</p>

<p><strong>Note</strong>: Why did I use the hard coded dictionary rather than reading from a file?&#160; I wanted to illustrate the technique of a truly static data source.&#160; If you want to see the code that parses a .csv file into a dictionary object suitable for using in a lookup function, this is covered in the appendix section of the blog).</p>

<p><strong>Note</strong>: Why didn’t I simply join the dictionary with the data stream?&#160; StreamInsight needs to join <strong>streams</strong> both relationally and temporally.&#160; Since a dictionary isn’t a stream (and has no concept of time, it’s not possible to directly join.&#160; Converting a reference source into a stream and joining is the other technique covered in the next section.</p>

<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:af378d40-35bd-4faf-a5c4-bb5f7696c1a9" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div>
<div style="background: #ddd; overflow: auto">
<ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color:#0000ff">static</span> <span style="color:#2b91af">Query</span> CreateUserDefinedFunction(<span style="color:#2b91af">Application</span> cepApp)</li>
<li style="background: #f3f3f3">{</li>
<li>    <span style="color:#0000ff">var</span> dataStream = <span style="color:#2b91af">CepStream</span>&lt;<span style="color:#2b91af">DataEvent</span>&gt;.Create(<span style="color:#a31515">&quot;dataStream&quot;</span>,</li>
<li style="background: #f3f3f3">        <span style="color:#0000ff">typeof</span>(<span style="color:#2b91af">TextFileReaderFactory</span>), <span style="color:#0000ff">new</span> <span style="color:#2b91af">TextFileReaderConfig</span>()</li>
<li>        {</li>
<li style="background: #f3f3f3">                InputFileName = <span style="color:#a31515">&quot;dataEvents.csv&quot;</span>,</li>
<li>                CtiFrequency = 1,</li>
<li style="background: #f3f3f3">                CultureName = <span style="color:#2b91af">CultureInfo</span>.InvariantCulture.Name,</li>
<li>                Delimiter = <span style="color:#a31515">&#39;,&#39;</span>                       </li>
<li style="background: #f3f3f3">        },  <span style="color:#2b91af">EventShape</span>.Point);</li>
<li>&nbsp;</li>
<li style="background: #f3f3f3">    <span style="color:#008000">// Populate the reference data statically</span></li>
<li>    refData.Add(1, <span style="color:#0000ff">new</span> <span style="color:#2b91af">ReferenceData</span>() </li>
<li style="background: #f3f3f3">        { UserId = 1, UserName = <span style="color:#a31515">&quot;Fred Jones&quot;</span>, Location = <span style="color:#a31515">&quot;Seattle&quot;</span> } );</li>
<li>    refData.Add(2, <span style="color:#0000ff">new</span> <span style="color:#2b91af">ReferenceData</span>() </li>
<li style="background: #f3f3f3">        { UserId = 2, UserName = <span style="color:#a31515">&quot;Bob Murphy&quot;</span>, Location = <span style="color:#a31515">&quot;Portland&quot;</span> } );</li>
<li>            </li>
<li style="background: #f3f3f3">    <span style="color:#008000">// Create a stream with the user name added to the query</span></li>
<li>    <span style="color:#0000ff">var</span> joinedStream = <span style="color:#0000ff">from</span> e <span style="color:#0000ff">in</span> dataStream</li>
<li style="background: #f3f3f3">        <span style="color:#0000ff">select</span> <span style="color:#0000ff">new</span></li>
<li>        {</li>
<li style="background: #f3f3f3">            UserId = e.UserId,</li>
<li>            Activity = e.ActivityCode,</li>
<li style="background: #f3f3f3">            Status = e.Status,</li>
<li>            <span style="color:#008000">// Use a static lookup function to retrieve the name</span></li>
<li style="background: #f3f3f3">            Name = LookupName(e.UserId),</li>
<li>            <span style="color:#008000">// Use a static lookup function to retrieve the location</span></li>
<li style="background: #f3f3f3">            Location = LookupLocation(e.UserId)</li>
<li>        };</li>
<li style="background: #f3f3f3">&nbsp;</li>
<li>    <span style="color:#008000">// Attach a trace output adapter to the stream</span></li>
<li style="background: #f3f3f3">    <span style="color:#0000ff">var</span> query = joinedStream.ToQuery(cepApp, <span style="color:#a31515">&quot;outputLookup&quot;</span>, <span style="color:#a31515">&quot;&quot;</span>,</li>
<li>        <span style="color:#0000ff">typeof</span>(<span style="color:#2b91af">TracerFactory</span>), <span style="color:#0000ff">new</span> <span style="color:#2b91af">TracerConfig</span>()</li>
<li style="background: #f3f3f3">        {</li>
<li>            DisplayCtiEvents = <span style="color:#0000ff">false</span>,</li>
<li style="background: #f3f3f3">            SingleLine = <span style="color:#0000ff">false</span>,</li>
<li>            TraceName = <span style="color:#a31515">&quot;REF&quot;</span>,</li>
<li style="background: #f3f3f3">            TracerKind = <span style="color:#2b91af">TracerKind</span>.Console</li>
<li>        }, <span style="color:#2b91af">EventShape</span>.Point, <span style="color:#2b91af">StreamEventOrder</span>.FullyOrdered);</li>
<li style="background: #f3f3f3">&nbsp;</li>
<li>    <span style="color:#0000ff">return</span> query;</li>
<li style="background: #f3f3f3">}</li>
<li>&nbsp;</li>
<li style="background: #f3f3f3"><span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> <span style="color:#0000ff">string</span> LookupName(<span style="color:#0000ff">int</span> userId)</li>
<li>{</li>
<li style="background: #f3f3f3">    <span style="color:#0000ff">if</span> (refData.ContainsKey(userId))</li>
<li>        <span style="color:#0000ff">return</span> refData[userId].UserName;</li>
<li style="background: #f3f3f3">    <span style="color:#0000ff">else</span></li>
<li>        <span style="color:#0000ff">return</span> <span style="color:#a31515">&quot;Unknown&quot;</span>;</li>
<li style="background: #f3f3f3">}</li>
<li>&nbsp;</li>
<li style="background: #f3f3f3"><span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> <span style="color:#0000ff">string</span> LookupLocation(<span style="color:#0000ff">int</span> userId)</li>
<li>{</li>
<li style="background: #f3f3f3">    <span style="color:#0000ff">if</span> (refData.ContainsKey(userId))</li>
<li>        <span style="color:#0000ff">return</span> refData[userId].Location;</li>
<li style="background: #f3f3f3">    <span style="color:#0000ff">else</span></li>
<li>        <span style="color:#0000ff">return</span> <span style="color:#a31515">&quot;Unknown&quot;</span>;</li>
<li style="background: #f3f3f3">}</li>
</ol>
</div>
</div>
</div>

<p>Upon running this function with the supplied data files, we observe the merged output:</p>

<table border="1"><tbody>
    <tr>
      <td>
        <pre>Press &lt;enter&gt; to close application
REF,Point,12:00:00.000
        Activity = Logon
        Location = Seattle
        Name = Fred Jones
        Status = Success
        UserId = 1
REF,Point,12:00:01.000
        Activity = Logon
        Location = Portland
        Name = Bob Murphy
        Status = Fail
        UserId = 2
REF,Point,12:00:05.000
        Activity = Browse
        Location = Seattle
        Name = Fred Jones
        Status = Success
        UserId = 1
REF,Point,12:00:06.000
        Activity = Logon
        Location = Portland
        Name = Bob Murphy
        Status = Success
        UserId = 2</pre>
      </td>
    </tr>
  </tbody></table>

<h3>Reference Data Stream (static data)</h3>

<p>Using the more robust reference data stream approach, we:</p>

<ul>
  <li>Use a TextFileInputFactory to import the contents of the text file </li>

  <li>Convert the series of point events into “infinite” signals. </li>

  <li>Join the reference stream with the data stream. </li>
</ul>

<p><strong>Note</strong>: this addresses conditions where the reference data DOES NOT CHANGE.&#160; This is not a very real-world scenario – we’ll cover the additions required to incorporate changing data in the next blog post, showing how to pull data from SQL Server.&#160; </p>

<p><strong>Note</strong>: I don’t use the <a href="http://blogs.msdn.com/b/appfabriccat/archive/2010/10/05/streaminsight-synchronizing-slow-moving-reference-streams-with-fast-moving-data-streams-time-import.aspx">CTI import technique</a> in this example.&#160; This is due to the text file input adapter sending an “infinite time” CTI when it reaches the end of the file.&#160; If we were using a continuous or changing reference data source (such as SQL Server), I’d need to employ that technique.</p>

<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:a59ac0ad-789e-4295-b1ef-a282b0244deb" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div>
<div style="background: #ddd; max-height: 500px; overflow: auto">
<ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color:#0000ff">static</span> <span style="color:#2b91af">Query</span> CreateThresholdStream(<span style="color:#2b91af">Application</span> cepApp)</li>
<li style="background: #f3f3f3">{</li>
<li>    <span style="color:#008000">// Pull the data events from the dataEvents.csv file</span></li>
<li style="background: #f3f3f3">    <span style="color:#0000ff">var</span> dataStream = <span style="color:#2b91af">CepStream</span>&lt;<span style="color:#2b91af">DataEvent</span>&gt;.Create(<span style="color:#a31515">&quot;dataStream&quot;</span>,</li>
<li>        <span style="color:#0000ff">typeof</span>(<span style="color:#2b91af">TextFileReaderFactory</span>), <span style="color:#0000ff">new</span> <span style="color:#2b91af">TextFileReaderConfig</span>()</li>
<li style="background: #f3f3f3">        {</li>
<li>                InputFileName = <span style="color:#a31515">&quot;dataEvents.csv&quot;</span>,</li>
<li style="background: #f3f3f3">            CtiFrequency = 1,</li>
<li>            CultureName = <span style="color:#2b91af">CultureInfo</span>.InvariantCulture.Name,</li>
<li style="background: #f3f3f3">            Delimiter = <span style="color:#a31515">&#39;,&#39;</span>                     </li>
<li>        }, <span style="color:#2b91af">EventShape</span>.Point);</li>
<li style="background: #f3f3f3">&nbsp;</li>
<li>    <span style="color:#008000">// Create a reference stream using the datastream as a time reference</span></li>
<li style="background: #f3f3f3">    <span style="color:#0000ff">var</span> refStream = <span style="color:#2b91af">CepStream</span>&lt;<span style="color:#2b91af">ReferenceData</span>&gt;.Create(<span style="color:#a31515">&quot;refStream&quot;</span>,</li>
<li>        <span style="color:#0000ff">typeof</span>(<span style="color:#2b91af">TextFileReaderFactory</span>), <span style="color:#0000ff">new</span> <span style="color:#2b91af">TextFileReaderConfig</span>()</li>
<li style="background: #f3f3f3">        {</li>
<li>            InputFileName = <span style="color:#a31515">&quot;refEvents.csv&quot;</span>,</li>
<li style="background: #f3f3f3">            CtiFrequency = 1,</li>
<li>            CultureName = <span style="color:#2b91af">CultureInfo</span>.InvariantCulture.Name,</li>
<li style="background: #f3f3f3">            Delimiter = <span style="color:#a31515">&#39;,&#39;</span></li>
<li>        }, <span style="color:#2b91af">EventShape</span>.Point);</li>
<li style="background: #f3f3f3">&nbsp;</li>
<li>    <span style="color:#008000">// Stretch the ref stream points events out to infinity (i.e. must have </span></li>
<li style="background: #f3f3f3">    <span style="color:#008000">// relational and temporal matches to join, and for this example, the data</span></li>
<li>    <span style="color:#008000">// doesn&#39;t change.</span></li>
<li style="background: #f3f3f3">    <span style="color:#0000ff">var</span> referenceEvents = <span style="color:#0000ff">from</span> e <span style="color:#0000ff">in</span> refStream.AlterEventDuration(</li>
<li>                                e =&gt; <span style="color:#2b91af">TimeSpan</span>.MaxValue)</li>
<li style="background: #f3f3f3">                            <span style="color:#0000ff">select</span> e;</li>
<li>&nbsp;</li>
<li style="background: #f3f3f3">    <span style="color:#008000">// Join the two streams</span></li>
<li>    <span style="color:#0000ff">var</span> joinedStream = <span style="color:#0000ff">from</span> e1 <span style="color:#0000ff">in</span> dataStream</li>
<li style="background: #f3f3f3">                        <span style="color:#0000ff">join</span> e2 <span style="color:#0000ff">in</span> referenceEvents</li>
<li>        <span style="color:#0000ff">on</span> e1.UserId <span style="color:#0000ff">equals</span> e2.UserId</li>
<li style="background: #f3f3f3">        <span style="color:#0000ff">select</span> <span style="color:#0000ff">new</span></li>
<li>        {</li>
<li style="background: #f3f3f3">            UserId = e1.UserId,</li>
<li>            Activity = e1.ActivityCode,</li>
<li style="background: #f3f3f3">            Status = e1.Status,</li>
<li>            <span style="color:#008000">// Use the reference stream to retrieve the name</span></li>
<li style="background: #f3f3f3">            Name = e2.UserName,</li>
<li>            <span style="color:#008000">// Use the reference stream to retrieve the location</span></li>
<li style="background: #f3f3f3">            Location = e2.Location</li>
<li>        };</li>
<li style="background: #f3f3f3">&nbsp;</li>
<li>    <span style="color:#0000ff">var</span> query = joinedStream.ToQuery(cepApp, <span style="color:#a31515">&quot;outputStream&quot;</span>, <span style="color:#a31515">&quot;&quot;</span>,</li>
<li style="background: #f3f3f3">        <span style="color:#0000ff">typeof</span>(<span style="color:#2b91af">TracerFactory</span>), <span style="color:#0000ff">new</span> <span style="color:#2b91af">TracerConfig</span>()</li>
<li>        {</li>
<li style="background: #f3f3f3">            DisplayCtiEvents = <span style="color:#0000ff">false</span>,</li>
<li>            SingleLine = <span style="color:#0000ff">false</span>,</li>
<li style="background: #f3f3f3">            TraceName = <span style="color:#a31515">&quot;STREAM&quot;</span>,</li>
<li>            TracerKind = <span style="color:#2b91af">TracerKind</span>.Console</li>
<li style="background: #f3f3f3">        }, <span style="color:#2b91af">EventShape</span>.Point, <span style="color:#2b91af">StreamEventOrder</span>.FullyOrdered);</li>
<li>&nbsp;</li>
<li style="background: #f3f3f3">    <span style="color:#0000ff">return</span> query;</li>
<li>}</li>
</ol>
</div>
</div>
</div>



<p>Upon running this query with the supplied data sets, we observe:</p>

<table border="1"><tbody>
    <tr>
      <td>
        <pre>STREAM,Point,12:00:00.000
        Activity = Logon
        Location = Seattle
        Name = Fred Jones
        Status = Success
        UserId = 1
STREAM,Point,12:00:01.000
        Activity = Logon
        Location = Portland
        Name = Bob Murphy
        Status = Fail
        UserId = 2
STREAM,Point,12:00:05.000
        Activity = Browse
        Location = Seattle
        Name = Fred Jones
        Status = Success
        UserId = 1
STREAM,Point,12:00:06.000
        Activity = Logon
        Location = Portland
        Name = Bob Murphy
        Status = Success
        UserId = 2</pre>
      </td>
    </tr>
  </tbody></table>

<h3>Compare and Contrast</h3>

<p>For sake of clarity, let’s put the two techniques side by side.</p>

<table border="0" cellspacing="0" cellpadding="2" width="1076"><tbody>
    <tr>
      <td valign="top" width="476">Lookup </td>

      <td valign="top" width="598">Reference Stream</td>
    </tr>

    <tr>
      <td valign="top" width="476">
        <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:39b791f8-0f64-42b8-9d10-83c8ca667de1" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div>
<div style="background: #fff; max-height: 300px; overflow: auto">
<ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;">
<li><span style="color:#008000">// Create a stream with the user name added to the query</span></li>
<li style="background: #f3f3f3"><span style="color:#0000ff">var</span> joinedStream = <span style="color:#0000ff">from</span> e <span style="color:#0000ff">in</span> dataStream</li>
<li><span style="color:#0000ff">select</span> <span style="color:#0000ff">new</span></li>
<li style="background: #f3f3f3">{</li>
<li>    UserId = e.UserId,</li>
<li style="background: #f3f3f3">    Activity = e.ActivityCode,</li>
<li>    Status = e.Status,</li>
<li style="background: #f3f3f3">    <span style="color:#008000">// Use a static lookup function to retrieve the name</span></li>
<li>    Name = LookupName(e.UserId),</li>
<li style="background: #f3f3f3">    <span style="color:#008000">// Use a static lookup function to retrieve the location</span></li>
<li>    Location = LookupLocation(e.UserId)</li>
<li style="background: #f3f3f3">};</li>
</ol>
</div>
</div>
</div>
      </td>

      <td valign="top" width="598">
        <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:1515e2f7-64b7-4126-8b3d-f6fe71b48915" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div>
<div style="background: #ddd; overflow: auto">
<ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;">
<li><span style="color:#008000">// Stretch the ref stream points events out to infinity (i.e. must have </span></li>
<li style="background: #f3f3f3"><span style="color:#008000">// relational and temporal matches to join, and for this example, the data</span></li>
<li><span style="color:#008000">// doesn&#39;t change.</span></li>
<li style="background: #f3f3f3"><span style="color:#0000ff">var</span> referenceEvents = <span style="color:#0000ff">from</span> e <span style="color:#0000ff">in</span> refStream.AlterEventDuration(</li>
<li>                        e =&gt; <span style="color:#2b91af">TimeSpan</span>.MaxValue)</li>
<li style="background: #f3f3f3">                    <span style="color:#0000ff">select</span> e;</li>
<li>&nbsp;</li>
<li style="background: #f3f3f3"><span style="color:#008000">// Join the two streams</span></li>
<li><span style="color:#0000ff">var</span> joinedStream = <span style="color:#0000ff">from</span> e1 <span style="color:#0000ff">in</span> dataStream</li>
<li style="background: #f3f3f3">                <span style="color:#0000ff">join</span> e2 <span style="color:#0000ff">in</span> referenceEvents</li>
<li><span style="color:#0000ff">on</span> e1.UserId <span style="color:#0000ff">equals</span> e2.UserId</li>
<li style="background: #f3f3f3"><span style="color:#0000ff">select</span> <span style="color:#0000ff">new</span></li>
<li>{</li>
<li style="background: #f3f3f3">    UserId = e1.UserId,</li>
<li>    Activity = e1.ActivityCode,</li>
<li style="background: #f3f3f3">    Status = e1.Status,</li>
<li>    <span style="color:#008000">// Use the reference stream to retrieve the name</span></li>
<li style="background: #f3f3f3">    Name = e2.UserName,</li>
<li>    <span style="color:#008000">// Use the reference stream to retrieve the location</span></li>
<li style="background: #f3f3f3">    Location = e2.Location</li>
<li>};</li>
</ol>
</div>
</div>
</div>
      </td>
    </tr>
  </tbody></table>]]></content:encoded>
    </item>
    <item>
      <title>StreamInsight: Synchronizing slow-moving reference streams with fast-moving data streams (time import)</title>
      <link>https://docs.microsoft.com/archive/blogs/masimms/streaminsight-synchronizing-slow-moving-reference-streams-with-fast-moving-data-streams-time-import</link>
      <pubDate>Mon, 27 Sep 2010 15:44:56 GMT</pubDate>
      <dc:creator><![CDATA[Mark Simms [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/masimms/2010/09/27/streaminsight-synchronizing-slow-moving-reference-streams-with-fast-moving-data-streams-time-import/</guid>
      <description><![CDATA[One of the common tasks in StreamInsight is to use a reference stream to integrate metadata or...]]></description>
      <content:encoded><![CDATA[<p>One of the common tasks in StreamInsight is to use a reference stream to integrate metadata or reference data from a relatively static source (such as a SQL Server table).&#160; One of the challenges in integrating the reference stream has to do with liveliness; that is to say:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/metablogapi/3771.image_35C82ACC.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-metablogapi/3771.image_5F00_35C82ACC.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/metablogapi/7180.image_thumb_74B9AB67.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-metablogapi/7180.image_5F00_thumb_5F00_74B9AB67.png" width="585" height="268" /></a></p>    <p>In this diagram we see two streams (data and reference) joined together to create a joined stream, with a LINQ syntax such as:</p>  <pre class="code"><span style="color: #2b91af">CepStream</span>&lt;<span style="color: #2b91af">SensorReading</span>&gt; dataStream = <span style="color: blue">...</span>;
<span style="color: #2b91af">CepStream</span>&lt;<span style="color: #2b91af">SensorMetadata</span>&gt; metadataStream = <span style="color: blue">...</span>;

<span style="color: blue">var </span>joinedQuery = <span style="color: blue">from </span>e1 <span style="color: blue">in </span>dataStream
                    <span style="color: blue">join </span>e2 <span style="color: blue">in </span>metadataStream
                    <span style="color: blue">on </span>e1.SensorId <span style="color: blue">equals </span>e2.SensorId
                    <span style="color: blue">select </span>e1;</pre>

<p>From the diagram above, we see that we’ll only get two output events for (1) and (2).&#160; This is as a result of how the StreamInsight engine produces output – based on the application time (which is updated by the CTIs).&#160; In this case the engine sees:</p>

<ul>
  <li>I have a time of T5 on the data stream</li>

  <li>I have a time of T0 (ish) on the reference stream</li>

  <li>Since I have joined these two streams together I can only produce output when I have received <strong>all of the events for a given time period</strong>.&#160; Since the reference stream lags behind the data stream, I can only output events at the speed of the reference stream.</li>
</ul>

<p>In general, this is absolutely the correct behavior.&#160; However, we know something about the reference stream that the StreamInsight engine does not – that the reference stream is slowly changing, and we don’t want to wait for it to catch up.&#160; That is to say, we want to produce output at the pace of the data stream.&#160; How do we do this?</p>

<p>By <strong>importing </strong>the CTIs from the data stream <strong>into </strong>the reference stream:</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/metablogapi/4834.image_062A0C40.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-metablogapi/4834.image_5F00_062A0C40.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/metablogapi/6406.image_thumb_0C04AFD9.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-metablogapi/6406.image_5F00_thumb_5F00_0C04AFD9.png" width="585" height="268" /></a></p>

<p>This operation is performed by one of the overloads on the CepStream&lt;&gt;.Create() method, as per the syntax below (reading from this <a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/101linq/6646.SensorDataSmall.txt" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-101linq/6646.SensorDataSmall.txt">csv file</a> as the sample data source, and this <a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/101linq/3465.refDataSmall.txt" original-url="http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-101linq/3465.refDataSmall.txt">csv file</a> as the sample reference source).&#160; The entire project can be downloaded from <a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/101linq/7563.101LinqSamples.zip" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-101linq/7563.101LinqSamples.zip">here</a> (look in the SimpleJoin.cs class).</p>

<pre class="code"><span style="color: green">////////////////////////////////////////////////////////////////////
// Create a time import settings definition that states that a stream
// will import its CTI settings from dataStream 
</span><span style="color: blue">var </span>timeImportSettings = <span style="color: blue">new </span><span style="color: #2b91af">AdvanceTimeSettings</span>(<span style="color: blue">null</span>,
    <span style="color: blue">new </span><span style="color: #2b91af">AdvanceTimeImportSettings</span>(<span style="color: #a31515">&quot;dataStream&quot;</span>),
    <span style="color: #2b91af">AdvanceTimePolicy</span>.Adjust);

<span style="color: green">////////////////////////////////////////////////////////////////////
// Create a reference data stream from the refStream.csv file; use
// the CTIs from the dataStream as defined by the timeImportSettings
// object
</span><span style="color: #2b91af">CepStream</span>&lt;<span style="color: #2b91af">SensorMetadata</span>&gt; metadataStream = <span style="color: #2b91af">CepStream</span>&lt;<span style="color: #2b91af">SensorMetadata</span>&gt;
    .Create(<span style="color: #a31515">&quot;refStream&quot;</span>, <span style="color: blue">typeof</span>(<span style="color: #2b91af">TextFileReaderFactory</span>),
        <span style="color: blue">new </span><span style="color: #2b91af">TextFileReaderConfig</span>()
        {
                CtiFrequency = 1,
                CultureName = <span style="color: #2b91af">CultureInfo</span>.CurrentCulture.Name,
                Delimiter = <span style="color: #a31515">','</span>,
                InputFileName = <span style="color: #a31515">&quot;refStream.csv&quot;
        </span>}, <span style="color: #2b91af">EventShape</span>.Point, timeImportSettings);</pre>



<p>Note that this syntax assumes the presence of a “dataStream” stream.&#160; At this point, we should be able to join the two streams and see a steady flow of output.&#160; However, if we simply want to look at the raw output of metadata stream as per:</p>

<pre class="code"><span style="color: blue">var </span>rawData = metadataStream.ToQuery(cepApp, <span style="color: #a31515">&quot;MetadataStream&quot;</span>, <span style="color: #a31515">&quot;&quot;</span>,
    <span style="color: blue">typeof</span>(<span style="color: #2b91af">TracerFactory</span>), traceConfig, <span style="color: #2b91af">EventShape</span>.Interval,
    <span style="color: #2b91af">StreamEventOrder</span>.FullyOrdered);</pre>



<p>Here is the error that is returned:</p>

<table border="1"><tbody>
    <tr>
      <td>
        <pre>Error in query: Microsoft.ComplexEventProcessing.ManagementException: Advance time import stream 'dataStream' does not exist. ---&gt; </pre>

        <pre>Microsoft.ComplexEventProcessing.Compiler.CompilerException: <strong>Advance time import stream 'dataStream' does not exist</strong>.</pre>
      </td>
    </tr>
  </tbody></table>

<p>Huh?&#160; What do you mean the time import stream does not exist?&#160; I already defined it!&#160; What’s actually happening here is that the <strong>import stream has not yet been physically joined with the stream</strong>.&#160; In order to resolve this issue, you need to <strong>join the two streams before binding an output adapter (i.e. creating a query)</strong>.</p>

<pre class="code"><span style="color: green">////////////////////////////////////////////////////////////////////
// Create a join of the two streams, and bind the output to the 
// console
</span><span style="color: blue">var </span>joinedQuery = <span style="color: blue">from </span>e1 <span style="color: blue">in </span>dataStream
                    <span style="color: blue">join </span>e2 <span style="color: blue">in </span>metadataStream
                    <span style="color: blue">on </span>e1.SensorId <span style="color: blue">equals </span>e2.SensorId
                    <span style="color: blue">select </span>e1;

<span style="color: blue">var </span>query = joinedQuery.ToQuery(cepApp, <span style="color: #a31515">&quot;JoinedOutput&quot;</span>, <span style="color: #a31515">&quot;&quot;</span>,
    <span style="color: blue">typeof</span>(<span style="color: #2b91af">TracerFactory</span>), traceConfig, <span style="color: #2b91af">EventShape</span>.Interval,
    <span style="color: #2b91af">StreamEventOrder</span>.FullyOrdered);</pre>

<p>Ok, now let’s look at the output:</p>

<table border="1"><tbody>
    <tr>
      <td>
        <pre>REF,Interval from 06/25/2009 00:00:00 +00:00 to 06/25/2009 00:00:00 +00:00:,MySensor_1001,1001,14
REF: CTI at 06/25/2009 00:00:00 +00:00
REF: CTI at 06/25/2009 00:00:09 +00:00
REF: CTI at 12/31/9999 23:59:59 +00:00</pre>
      </td>
    </tr>
  </tbody></table>

<p>Huh?&#160; Where’s all of my output?&#160; Look at the data sources in question – the reference data is a sequence of point events.&#160; If we want to truly use it as a reference stream, we need to convert the series of point events into edge events (i.e. this value is good until replaced by a new value).&#160; In order to do this, we need to apply an AlterEventDuration and a Clip operator:</p>

<pre class="code"><span style="color: green">// Convert the point events from the reference stream into edge events
</span><span style="color: blue">var </span>edgeEvents = <span style="color: blue">from </span>e <span style="color: blue">in </span>metadataStream
                        .AlterEventDuration(e =&gt; <span style="color: #2b91af">TimeSpan</span>.MaxValue)
                        .ClipEventDuration(metadataStream, (e1, e2) =&gt; (e1.SensorId == e2.SensorId))
                    <span style="color: blue">select </span>e;</pre>

<p>What this bit of code does is:</p>

<ul>
  <li>Stretch the point events out to infinity (i.e. these reference values are good “forever”)</li>

  <li>Clip each point event by any arriving event <strong>with the same sensor ID</strong>.&#160; For example, given a value of (1001, SensorId_1001), if another event later arrives with the values (1001, MySensor), the initial event will be clipped off and the new value will be MySensor</li>
</ul>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/metablogapi/4846.image_6053E5DC.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-metablogapi/4846.image_5F00_6053E5DC.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/metablogapi/6011.image_thumb_040D0D77.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-metablogapi/6011.image_5F00_thumb_5F00_040D0D77.png" width="612" height="125" /></a></p>

<p>Then, putting the whole thing together:</p>

<pre class="code"><span style="color: green">// Convert the point events from the reference stream into edge events
</span><span style="color: blue">var </span>edgeEvents = <span style="color: blue">from </span>e <span style="color: blue">in </span>metadataStream
                        .AlterEventDuration(e =&gt; <span style="color: #2b91af">TimeSpan</span>.MaxValue)
                        .ClipEventDuration(metadataStream, (e1, e2) =&gt; (e1.SensorId == e2.SensorId))
                    <span style="color: blue">select </span>e;

    <span style="color: green">////////////////////////////////////////////////////////////////////
    // Create a join of the two streams, and bind the output to the 
    // console
</span><span style="color: blue">var </span>joinedQuery = <span style="color: blue">from </span>e1 <span style="color: blue">in </span>dataStream
                    <span style="color: blue">join </span>e2 <span style="color: blue">in </span>edgeEvents
                    <span style="color: blue">on </span>e1.SensorId <span style="color: blue">equals </span>e2.SensorId
                    <span style="color: blue">select new
                    </span>{
                        SensorId = e1.SensorId,
                        Name = e2.Name,
                        Value = e1.Value
                    };</pre>


<p>Results in:</p>

<p>&#160;</p>

<table border="1"><tbody>
    <tr>
      <td>
        <pre>REF,Interval,12:00:00.000,12:00:00.000,,<strong>MySensor_1001</strong>,1001,14
REF: CTI at 06/25/2009 00:00:00 +00:00
REF,Interval,12:00:01.000,12:00:01.000,,<strong>MySensor_1001</strong>,1001,4
REF,Interval,12:00:02.000,12:00:02.000,,<strong>MySensor_1001</strong>,1001,77
REF,Interval,12:00:03.000,12:00:03.000,,<strong>MySensor_1001</strong>,1001,44
REF,Interval,12:00:04.000,12:00:04.000,,<strong>MySensor_1001</strong>,1001,22
REF,Interval,12:00:05.000,12:00:05.000,,<strong>MySensor_1001</strong>,1001,51
REF,Interval,12:00:06.000,12:00:06.000,,<strong>MySensor_1001</strong>,1001,46
REF,Interval,12:00:07.000,12:00:07.000,,<strong>MySensor_1001</strong>,1001,71
REF,Interval,12:00:08.000,12:00:08.000,,<strong>MySensor_1001</strong>,1001,37
REF,Interval,12:00:09.000,12:00:09.000,,<strong>MySensor_1001</strong>,1001,45
REF: CTI at 12/31/9999 23:59:59 +00:00</pre>
      </td>
    </tr>
  </tbody></table>]]></content:encoded>
    </item>
    <item>
      <title>101’ish LINQ Samples for StreamInsight (part 1 - filtering and aggregation)</title>
      <link>https://docs.microsoft.com/archive/blogs/masimms/101ish-linq-samples-for-streaminsight-part-1-filtering-and-aggregation</link>
      <pubDate>Thu, 16 Sep 2010 09:20:00 GMT</pubDate>
      <dc:creator><![CDATA[Mark Simms [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/masimms/2010/09/16/101ish-linq-samples-for-streaminsight-part-1-filtering-and-aggregation/</guid>
      <description><![CDATA[Following in the great tradition of other learn through example...]]></description>
      <content:encoded><![CDATA[<!-- Include required JS files -->
<p>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js" type="text/javascript"></script>
</p>
<!--     At least one brush, here we choose JS. You need to include a brush for every      
         language you want to highlight -->
<p>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCSharp.js" type="text/javascript"></script>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPlain.js" type="text/javascript"></script>
</p>
<!-- Include *at least* the core style and default theme -->
<p>
<link href="http://alexgorbatchev.com/pub/sh/current/styles/shCore.css" type="text/css" rel="stylesheet" />
<link href="http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css" type="text/css" rel="stylesheet" />
</p>
<!-- Finally, to actually run the highlighter, you need to include this JS on your page -->
<p>
<script type="text/javascript"><!--
      SyntaxHighlighter.all()
// --></!--
></script>
</p>
<p>Following in the great tradition of other learn through example LINQ example pages, such as <a href="http://msdn.microsoft.com/en-us/vcsharp/aa336746.aspx">101 LINQ Samples</a>, here&rsquo;s the first in a series of posts on StreamInsight query examples.&nbsp; This will first show up on this blog, then get migrated over to a centralized site on the StreamInsight <a href="http://msdn.microsoft.com/en-us/sqlserver/ee476990.aspx">developer center</a>.&nbsp; We&rsquo;ve got a fairly hefty queue we&rsquo;re working through, but if there are specific examples or query patterns of interest, please post them in the comments.</p>
<p>Each query pattern will consist of a description of the input set (.csv file samples for most of these, for ease of use), the full query and the output result.&nbsp; For more complicated query structures the query pattern will also be described visually, using a Visio stencil (to be described in future posts).&nbsp; </p>
<p>The full application framework that I use to run all of these queries, associate with the data sources, etc, is available <a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/101linq/3583.101LinqSamples.zip" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-101linq/3583.101LinqSamples.zip">here</a>.&nbsp; Illustration of the techniques in this codebase will be left for a future post.&nbsp; </p>
<p>In this post:</p>
<ul>
<li>Filtering 
<ul>
<li><a href="#f1">How do I filter a stream, keeping only specific events?</a> </li>
<li><a href="#f2">How do I filter on multiple conditions?</a> </li>
</ul>
</li>
<li>Windows and Aggregates 
<ul>
<li><a href="#wa1">How can I calculate aggregates, such as averages, over a set of events?</a> </li>
<li><a href="#wa2">How can I calculate the average of all events in the last 5 seconds? </a></li>
<li><a href="#wa3">How can I calculate the average of all events in the past 5 seconds, every 2 seconds? </a></li>
<li><a href="#wa4">How can I calculate the average of all events in the past 5 seconds, every time a new event arrives? </a></li>
<li><a href="#wa5">How can I calculate the average of the past 5 events? </a></li>
<li><a href="#wa6">How do I measure the rate of arriving events every two seconds? </a></li>
<li><a href="#wa7">How can I calculate the average of each group of events in the last 10 seconds?&nbsp; </a></li>
<li><a href="#wa8">How can I calculate the average of each group of events in the last 20 seconds, every 10 seconds?&nbsp; </a></li>
<li><a href="#wa9">How can I calculate the average of each group of events in the past 10 seconds, every time a new event in that group arrives? </a></li>
<li><a href="#wa10">How can I find the events with the largest value every 10 seconds? </a></li>
<li><a href="#wa11">How can I find the events with the two smallest values in the last 10 seconds, every 5 seconds? </a></li>
<li><a href="#wa12">How can I find the group of events with the highest average value in the last 10 seconds? </a></li>
<li><a href="#wa13">How can I find the group of events with the highest maximum value in the last 10 seconds, every 5 seconds? </a></li>
<li><a href="#wa14">How can I detect if two events with the same ID value are received within a specific time frame, such as a 5 minute window?</a> </li>
</ul>
</li>
</ul>
<hr />
<p><strong><a name="f1">[Where] - How do I filter a stream, keeping only specific events?</a></strong></p>
<pre class="brush: csharp">var filterQuery = from e in inputStream
    where e.Value &gt; 20
    select e;</pre>
<p>[<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/101linq/6646.SensorDataSmall.txt" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-101linq/6646.SensorDataSmall.txt">Input</a>] Result:</p>
<table border="1">
<tbody>
<tr>
<td>
<pre>SimpleFilter,Point,12:00:02.000,1001,77
SimpleFilter,Point,12:00:03.000,1001,44
SimpleFilter,Point,12:00:04.000,1001,22
SimpleFilter,Point,12:00:05.000,1001,51
SimpleFilter,Point,12:00:06.000,1001,46
SimpleFilter,Point,12:00:07.000,1001,71
SimpleFilter,Point,12:00:08.000,1001,37
SimpleFilter,Point,12:00:09.000,1001,45</pre>
</td>
</tr>
</tbody>
</table>
<p><strong><a name="f2">How do I filter on multiple conditions?</a></strong></p>
<pre class="brush: csharp;">var filterQuery = from e in inputStream
where e.Value &gt; 70 &amp;&amp; e.SensorId == 1001
select e;</pre>
<p>[<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/101linq/6327.SensorDataMedium.txt" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-101linq/6327.SensorDataMedium.txt">Input</a>] Result:</p>
<table border="1">
<tbody>
<tr>
<td>
<pre>MediumFilter,Point,12:00:01.001,1001,77
MediumFilter,Point,12:00:03.010,1001,72
MediumFilter,Point,12:00:12.082,1001,73
MediumFilter,Point,12:00:14.145,1001,75
MediumFilter,Point,12:00:14.154,1001,71
MediumFilter,Point,12:00:15.163,1001,74
MediumFilter,Point,12:00:15.172,1001,73</pre>
</td>
</tr>
</tbody>
</table>
<p><strong><a name="wa1">How can I calculate aggregates, such as averages, over a set of events?</a></strong></p>
<p>All aggregates, such as averages, min, max, etc are calculated over a set of events.&nbsp; Sets of events in StreamInsight are defined as those events falling into a window.&nbsp; Windows operate over a period of time (hopping, tumbling and sliding), or over a specific number of events (count).</p>
<p><strong><a name="wa2">How can I calculate the average of all events in the last 5 seconds?</a></strong></p>
<pre class="brush: csharp;">var query = from window in inputStream.TumblingWindow(
    TimeSpan.FromSeconds(5),
    HoppingWindowOutputPolicy.ClipToWindowEnd)
select new 
{
    Average = window.Avg(e =&gt; e.Value)
};</pre>
<p>[<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/101linq/6646.SensorDataSmall.txt" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-101linq/6646.SensorDataSmall.txt">Input</a>] Result:</p>
<table border="1">
<tbody>
<tr>
<td>
<pre>SimpleTumblingWindow,Point,12:00:00.000,32.2
SimpleTumblingWindow,Point,12:00:05.000,50</pre>
</td>
</tr>
</tbody>
</table>
<p><strong><a name="wa3">How can I calculate the average of all events in the past 5 seconds, every 2 seconds?</a></strong></p>
<pre class="brush: csharp; ">var query = from window in inputStream.HoppingWindow(
                TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(2), 
                HoppingWindowOutputPolicy.ClipToWindowEnd)
            select new
            {
                Average = window.Avg(e =&gt; e.Value)
            };</pre>
<p>[<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/101linq/6646.SensorDataSmall.txt" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-101linq/6646.SensorDataSmall.txt">Input</a>] Result:</p>
<table border="1">
<tbody>
<tr>
<td>
<pre>SimpleHoppingWindow,Point,11:59:56.000,14
SimpleHoppingWindow,Point,11:59:58.000,31.66666
SimpleHoppingWindow,Point,12:00:00.000,32.2
SimpleHoppingWindow,Point,12:00:02.000,48
SimpleHoppingWindow,Point,12:00:04.000,45.4
SimpleHoppingWindow,Point,12:00:06.000,49.75
SimpleHoppingWindow,Point,12:00:08.000,41</pre>
</td>
</tr>
</tbody>
</table>
<p><strong><a name="wa4">How can I calculate the average of all events in the past 5 seconds, every time a new event arrives?</a></strong></p>
<pre sizset="4" sizcache="3" class="brush: csharp; ">var query = from window in inputStream
    .AlterEventDuration(e =&gt; TimeSpan.FromSeconds(5))
    .SnapshotWindow(SnapshotWindowOutputPolicy.Clip)
select new
{
    Average = window.Avg(e =&gt; e.Value)
};</pre>
<p>[<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/101linq/6646.SensorDataSmall.txt" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-101linq/6646.SensorDataSmall.txt">Input</a>] Result:</p>
<table border="1">
<tbody>
<tr>
<td>
<pre>SimpleSlidingWindow,Point,12:00:00.000,14
SimpleSlidingWindow,Point,12:00:01.000,9
SimpleSlidingWindow,Point,12:00:02.000,31.66
SimpleSlidingWindow,Point,12:00:03.000,34.75
SimpleSlidingWindow,Point,12:00:04.000,32.2
SimpleSlidingWindow,Point,12:00:05.000,39.6
SimpleSlidingWindow,Point,12:00:06.000,48
SimpleSlidingWindow,Point,12:00:07.000,46.8
SimpleSlidingWindow,Point,12:00:08.000,45.4
SimpleSlidingWindow,Point,12:00:09.000,50
SimpleSlidingWindow,Point,12:00:10.000,49.75
SimpleSlidingWindow,Point,12:00:11.000,51
SimpleSlidingWindow,Point,12:00:12.000,41
SimpleSlidingWindow,Point,12:00:13.000,45</pre>
</td>
</tr>
</tbody>
</table>
<p><strong><a name="wa5">How can I calculate the average of the past 5 events?</a></strong></p>
<p>Aggregates over a set number of events are produced using Count windows.&nbsp; As of StreamInsight v1, Count Windows cannot use the built-in aggregate functions (Count, Avg, Min, Max), but must instead use user-defined aggregates.&nbsp; The code sample below shows the use of a simple averaging function with a count window with the user defined aggregate.</p>
<pre class="brush: csharp; ">var query = from window in inputStream.CountByStartTimeWindow(
            5, CountWindowOutputPolicy.PointAlignToWindowEnd)
        select new
        {
            Average = window.UserDefinedAverage(e =&gt; e.Value)
        };

 public class SimpleAggregate : CepAggregate&lt;double, double&gt;
{
    public override double GenerateOutput(IEnumerable&lt;double&gt; payloads)
    {
        return payloads.Average();
    }
}

public static class MyExtensions
{
    [CepUserDefinedAggregate(typeof(SimpleAggregate))]
    public static double UserDefinedAverage&lt;InputT&gt;(this CepWindow&lt;InputT&gt; window, 
        Expression&lt;Func&lt;InputT, double&gt;&gt; map)
    {
        throw CepUtility.DoNotCall();
    }

}</pre>
<p>[<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/101linq/6646.SensorDataSmall.txt" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-101linq/6646.SensorDataSmall.txt">Input</a>] Result:</p>
<table border="1">
<tbody>
<tr>
<td>
<pre>SimpleCountWindow,Point,12:00:04.000,32.2
SimpleCountWindow,Point,12:00:05.000,39.6
SimpleCountWindow,Point,12:00:06.000,48
SimpleCountWindow,Point,12:00:07.000,46.8
SimpleCountWindow,Point,12:00:08.000,45.4
SimpleCountWindow,Point,12:00:09.000,50</pre>
</td>
</tr>
</tbody>
</table>
<p><strong><a name="wa6">How do I measure the rate of arriving events every two seconds?</a></strong></p>
<pre class="brush: csharp;">var query = from window in inputStream.TumblingWindow(
    TimeSpan.FromSeconds(2),
    HoppingWindowOutputPolicy.ClipToWindowEnd)
select new
{
    Count = window.Count()
};</pre>
<p>[<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/101linq/6327.SensorDataMedium.txt" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-101linq/6327.SensorDataMedium.txt">Input</a>] Result:</p>
<table border="1">
<tbody>
<tr>
<td>
<pre>SimpleEventCount,Point,12:00:00.000,54
SimpleEventCount,Point,12:00:02.000,54
SimpleEventCount,Point,12:00:04.000,54
SimpleEventCount,Point,12:00:06.000,54
SimpleEventCount,Point,12:00:08.000,54
SimpleEventCount,Point,12:00:10.000,54
SimpleEventCount,Point,12:00:12.000,54
SimpleEventCount,Point,12:00:14.000,54
SimpleEventCount,Point,12:00:16.000,54</pre>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p><strong><a name="wa7">How can I calculate the average of each group of events in the last 10 seconds?&nbsp; </a></strong></p>
<p>For this example, we&rsquo;ll calculate the average of each sensor every 10 seconds.&nbsp; We do this by first grouping the events by the sensor ID, then performing the same aggregation operation from the average without grouping (with the addition of the <strong><em>group key </em></strong>&ndash; in this case, the sensor ID).</p>
<pre class="brush: csharp;">var query = from e in inputStream 
group e by e.SensorId into sensorGroups
from window in sensorGroups.TumblingWindow(
    TimeSpan.FromSeconds(10),
    HoppingWindowOutputPolicy.ClipToWindowEnd)
select new
{
    SensorId = sensorGroups.Key,
    Average = window.Avg(e =&gt; e.Value)
};</pre>
<p>[<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/101linq/6327.SensorDataMedium.txt" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-101linq/6327.SensorDataMedium.txt">Input</a>] Result:</p>
<table border="1">
<tbody>
<tr>
<td>
<pre>GroupedTumblingWindow,Point,12:00:00.000,42.1,1001
GroupedTumblingWindow,Point,12:00:00.000,34.6,1002
GroupedTumblingWindow,Point,12:00:00.000,39.7,1003
GroupedTumblingWindow,Point,12:00:00.000,50.9,1004
GroupedTumblingWindow,Point,12:00:00.000,30.7,1005
GroupedTumblingWindow,Point,12:00:00.000,38.3,1006
GroupedTumblingWindow,Point,12:00:00.000,36.8,1007
GroupedTumblingWindow,Point,12:00:00.000,41.7,1008
GroupedTumblingWindow,Point,12:00:00.000,34.4,1009
GroupedTumblingWindow,Point,12:00:10.000,46.375,1001
GroupedTumblingWindow,Point,12:00:10.000,40.2,1002
GroupedTumblingWindow,Point,12:00:10.000,36.1,1003
GroupedTumblingWindow,Point,12:00:10.000,37.3,1004
GroupedTumblingWindow,Point,12:00:10.000,31.8,1005
GroupedTumblingWindow,Point,12:00:10.000,41.4,1006
GroupedTumblingWindow,Point,12:00:10.000,40.3,1007
GroupedTumblingWindow,Point,12:00:10.000,43.5,1008
GroupedTumblingWindow,Point,12:00:10.000,43.3,1009</pre>
</td>
</tr>
</tbody>
</table>
<p><strong><a name="wa8">How can I calculate the average of each group of events in the last 20 seconds, every 10 seconds?&nbsp; </a></strong></p>
<pre sizset="8" sizcache="3" class="brush: csharp;"> var query = from e in inputStream
group e by e.SensorId into sensorGroups
from window in sensorGroups.HoppingWindow(
    TimeSpan.FromSeconds(20), TimeSpan.FromSeconds(10),
    HoppingWindowOutputPolicy.ClipToWindowEnd)
select new
{
    SensorId = sensorGroups.Key,
    Average = window.Avg(e =&gt; e.Value)
};</pre>
<p>[<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/101linq/6327.SensorDataMedium.txt" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-101linq/6327.SensorDataMedium.txt">Input</a>] Result:</p>
<table border="1">
<tbody>
<tr>
<td>
<pre>GroupedHoppingWindow,Point,11:59:50.000,42.1,1001
GroupedHoppingWindow,Point,11:59:50.000,34.6,1002
GroupedHoppingWindow,Point,11:59:50.000,39.7,1003
GroupedHoppingWindow,Point,11:59:50.000,50.9,1004
GroupedHoppingWindow,Point,11:59:50.000,30.7,1005
GroupedHoppingWindow,Point,11:59:50.000,38.3,1006
GroupedHoppingWindow,Point,11:59:50.000,36.8,1007
GroupedHoppingWindow,Point,11:59:50.000,41.7,1008
GroupedHoppingWindow,Point,11:59:50.000,34.4,1009
GroupedHoppingWindow,Point,12:00:00.000,44,1001
GroupedHoppingWindow,Point,12:00:00.000,37.0,1002
GroupedHoppingWindow,Point,12:00:00.000,38.1,1003
GroupedHoppingWindow,Point,12:00:00.000,44.8,1004
GroupedHoppingWindow,Point,12:00:00.000,31.2,1005
GroupedHoppingWindow,Point,12:00:00.000,39.7,1006
GroupedHoppingWindow,Point,12:00:00.000,38.4,1007
GroupedHoppingWindow,Point,12:00:00.000,42.5,1008
GroupedHoppingWindow,Point,12:00:00.000,38.4,1009
GroupedHoppingWindow,Point,12:00:10.000,46.3,1001
GroupedHoppingWindow,Point,12:00:10.000,40.2,1002
GroupedHoppingWindow,Point,12:00:10.000,36.1,1003
GroupedHoppingWindow,Point,12:00:10.000,37.3,1004
GroupedHoppingWindow,Point,12:00:10.000,31.8,1005
GroupedHoppingWindow,Point,12:00:10.000,41.4,1006
GroupedHoppingWindow,Point,12:00:10.000,40.3,1007
GroupedHoppingWindow,Point,12:00:10.000,43.5,1008
GroupedHoppingWindow,Point,12:00:10.000,43.3,1009</pre>
</td>
</tr>
</tbody>
</table>
<p><strong><a name="wa9">How can I calculate the average of each group of events in the past 10 seconds, every time a new event in that group arrives?</a></strong></p>
<pre class="brush: csharp;">var query = from e in inputStream
    .AlterEventDuration(e =&gt; TimeSpan.FromSeconds(10))
group e by e.SensorId into sensorGroups
from window in sensorGroups
    .SnapshotWindow(SnapshotWindowOutputPolicy.Clip)
select new
{
    SensorId = sensorGroups.Key,
    Average = window.Avg(e =&gt; e.Value)
};</pre>
<p>[<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/101linq/6327.SensorDataMedium.txt" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-101linq/6327.SensorDataMedium.txt">Input</a>] Result:</p>
<table border="1">
<tbody>
<tr>
<td>
<pre>&lt;snip&gt;</pre>
<pre>GroupedSlidingWindow,Point,12:00:17.017,39.3,1008
GroupedSlidingWindow,Point,12:00:17.018,39.4,1009
GroupedSlidingWindow,Point,12:00:17.019,43,1001
GroupedSlidingWindow,Point,12:00:17.020,43.1,1002
GroupedSlidingWindow,Point,12:00:17.021,37.8,1003
GroupedSlidingWindow,Point,12:00:17.022,41.8,1004
GroupedSlidingWindow,Point,12:00:17.023,33.7,1005
GroupedSlidingWindow,Point,12:00:17.024,39.2,1006
GroupedSlidingWindow,Point,12:00:17.025,40.3,1007
GroupedSlidingWindow,Point,12:00:17.026,38.9,1008
GroupedSlidingWindow,Point,12:00:17.027,40.8,1009
&lt;snip&gt;</pre>
</td>
</tr>
</tbody>
</table>
<p><strong><a name="wa10">How can I find the events with the largest value every 10 seconds?</a></strong></p>
<pre class="brush: csharp;">var query = (from window in inputStream.TumblingWindow(
    TimeSpan.FromSeconds(10),
    HoppingWindowOutputPolicy.ClipToWindowEnd)
from e in window
orderby e.Value descending
select e).Take(1);</pre>
<p>[<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/101linq/6327.SensorDataMedium.txt" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-101linq/6327.SensorDataMedium.txt">Input</a>] Result:</p>
<table border="1">
<tbody>
<tr>
<td>
<pre>TopK_TumblingDescending,Point,12:00:00.000,1006,80
TopK_TumblingDescending,Point,12:00:00.000,1007,80
TopK_TumblingDescending,Point,12:00:00.000,1009,80
TopK_TumblingDescending,Point,12:00:10.000,1007,81</pre>
</td>
</tr>
</tbody>
</table>
<p>Note that for the first group of events, the are three events with the same maximum value (80) in the same window of time.&nbsp; Thusly, all of the events with that maximum value are returned.</p>
<p><strong><a name="wa11">How can I find the events with the two smallest values in the last 10 seconds, every 5 seconds?</a></strong></p>
<pre class="brush: csharp;">var query = (from window in inputStream.HoppingWindow(
   TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(5),
   HoppingWindowOutputPolicy.ClipToWindowEnd)
from e in window
orderby e.Value ascending
select e).Take(2);</pre>
<p>[<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/101linq/6327.SensorDataMedium.txt" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-101linq/6327.SensorDataMedium.txt">Input</a>] Result:</p>
<table border="1">
<tbody>
<tr>
<td>
<pre>TopK_HoppingAscending,Point,11:59:55.000,1004,2
TopK_HoppingAscending,Point,11:59:55.000,1007,1
TopK_HoppingAscending,Point,11:59:55.000,1008,2
TopK_HoppingAscending,Point,12:00:00.000,1001,1
TopK_HoppingAscending,Point,12:00:00.000,1001,1
TopK_HoppingAscending,Point,12:00:00.000,1003,1
TopK_HoppingAscending,Point,12:00:00.000,1007,1
TopK_HoppingAscending,Point,12:00:05.000,1001,1
TopK_HoppingAscending,Point,12:00:05.000,1001,1
TopK_HoppingAscending,Point,12:00:05.000,1003,1
TopK_HoppingAscending,Point,12:00:10.000,1004,2
TopK_HoppingAscending,Point,12:00:10.000,1004,2
TopK_HoppingAscending,Point,12:00:10.000,1006,2
TopK_HoppingAscending,Point,12:00:10.000,1007,2
TopK_HoppingAscending,Point,12:00:15.000,1004,2
TopK_HoppingAscending,Point,12:00:15.000,1007,2</pre>
</td>
</tr>
</tbody>
</table>
<p>Note the same effect herein &ndash; multiple events having identical minimum values in the window.</p>
<p><strong><a name="wa12">How can I find the group of events with the highest average value in the last 10 seconds?</a></strong></p>
<p>This query is performed in two stages.&nbsp; In the first query we determine the average value of each sensor over the past 10 seconds (using a group by, a tumbling window and an Avg()).&nbsp; Then we take the output of that aggregate and perform a snapshot on top of that (against each set of events from the first query), sort it and take the top value.</p>
<pre class="brush: csharp;">var avg = from e in inputStream
    group e by e.SensorId into sensorGroups
    from window in sensorGroups.TumblingWindow(
        TimeSpan.FromSeconds(10),
        HoppingWindowOutputPolicy.ClipToWindowEnd)
    select new
    {
        SensorId = sensorGroups.Key,
        Average = window.Avg(e =&gt; e.Value)
    };

var query = (from win in avg
        .SnapshotWindow(SnapshotWindowOutputPolicy.Clip)
    from e in win
    orderby e.Average descending
    select e).Take(1);</pre>
<p>[<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/101linq/6327.SensorDataMedium.txt" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-101linq/6327.SensorDataMedium.txt">Input</a>] Results:</p>
<table border="1">
<tbody>
<tr>
<td>
<pre>TopK_GroupTumblingDescending,Point,12:00:00.000,50.9,1004
TopK_GroupTumblingDescending,Point,12:00:10.000,46.3,1001</pre>
</td>
</tr>
</tbody>
</table>
<p><strong><a name="wa13">How can I find the group of events with the highest maximum value in the last 10 seconds, every 5 seconds?</a></strong></p>
<pre class="brush: csharp;">var avg = from e in inputStream
    group e by e.SensorId into sensorGroups
    from window in sensorGroups.HoppingWindow(
        TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(5),
        HoppingWindowOutputPolicy.ClipToWindowEnd)
    select new
    {
        SensorId = sensorGroups.Key,
        Maximum = window.Max(e =&gt; e.Value),
        Minimum = window.Min(e =&gt; e.Value)
    };

var query = (from win in avg
        .SnapshotWindow(SnapshotWindowOutputPolicy.Clip)
    from e in win
    orderby e.Maximum descending
    select e).Take(1);</pre>
<p>[<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/101linq/6327.SensorDataMedium.txt" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-101linq/6327.SensorDataMedium.txt">Input</a>] Result:</p>
<table border="1">
<tbody>
<tr>
<td>
<pre>TopK_GroupHoppingDescending,Point,11:59:55.000,80,6,1006
TopK_GroupHoppingDescending,Point,11:59:55.000,80,1,1007
TopK_GroupHoppingDescending,Point,11:59:55.000,80,4,1009
TopK_GroupHoppingDescending,Point,12:00:00.000,80,6,1006
TopK_GroupHoppingDescending,Point,12:00:00.000,80,6,1006
TopK_GroupHoppingDescending,Point,12:00:00.000,80,1,1007
TopK_GroupHoppingDescending,Point,12:00:00.000,80,1,1007
TopK_GroupHoppingDescending,Point,12:00:00.000,80,2,1009
TopK_GroupHoppingDescending,Point,12:00:00.000,80,4,1009
TopK_GroupHoppingDescending,Point,12:00:05.000,80,2,1006
TopK_GroupHoppingDescending,Point,12:00:05.000,80,6,1006
TopK_GroupHoppingDescending,Point,12:00:05.000,80,1,1007
TopK_GroupHoppingDescending,Point,12:00:05.000,80,2,1009
TopK_GroupHoppingDescending,Point,12:00:10.000,81,2,1007
TopK_GroupHoppingDescending,Point,12:00:15.000,81,2,1007
TopK_GroupHoppingDescending,Point,12:00:15.000,81,2,1007
TopK_GroupHoppingDescending,Point,12:00:20.000,81,2,1007</pre>
</td>
</tr>
</tbody>
</table>
<p>Again, note the StreamInsight engine delivering the values corresponding to the top maximum value (80 or 81).</p>
<p><strong><a name="wa14">How can I detect if two events with the same ID value are received within a specific time frame, such as a 5 minute window?</a></strong></p>
<p>To implement this query, we use a sliding window to look at arriving events in a 5 minute window, grouped by their ID value.&nbsp; We then count the number of events in the window with that ID, and filter out groups that have less than 2 events.&nbsp; Or, to say it another say, we only want groups (sensors) that have more than 1 event, thus removing groups with only 1 event (there are no groups with zero :).</p>
<pre class="brush: csharp;">var eventCount = from e in inputStream.AlterEventDuration(e =&gt; TimeSpan.FromMinutes(5))
     group e by e.SensorId into sensorGroups
     from win in sensorGroups.SnapshotWindow(SnapshotWindowOutputPolicy.Clip)
     select new
     {
         SensorId = sensorGroups.Key,
         Count = win.Count()
     };

var query = from e in eventCount
where e.Count &gt;= 2
select e;</pre>
<p>[<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/08/98/101linq/6327.SensorDataMedium.txt" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-08-98-101linq/6327.SensorDataMedium.txt">Input</a>] Result:</p>
<table border="1">
<tbody>
<tr>
<td>
<pre>DetectMultipleInWindow,Point,12:05:16.206,4,1008
DetectMultipleInWindow,Point,12:05:16.207,4,1009
DetectMultipleInWindow,Point,12:05:16.208,3,1001
DetectMultipleInWindow,Point,12:05:16.209,3,1002
&lt;snip&gt;</pre>
</td>
</tr>
</tbody>
</table>
<pre></pre>
<pre></pre></!--></!--></!--></!-->]]></content:encoded>
    </item>
  </channel>
</rss>