﻿<?xml version="1.0" encoding="utf-8"?><rss version="2.0"><channel><title>Ayende @ Rahien</title><link>http://ayende.com/blog/</link><description>Ayende @ Rahien</description><copyright>Copyright (C) Ayende Rahien  2004 - 2012 (c) 2012</copyright><ttl>60</ttl><item><title>Gilad Shalit is back</title><description>&lt;p&gt;I don’t usually do posts about current events, but &lt;a href="http://www.ynetnews.com/articles/0,7340,L-4136451,00.html"&gt;this one is huge&lt;/a&gt;. &lt;/p&gt; &lt;p&gt;To celebrate the event, you can use the following coupon code: SLT-45K2D4692G to get 19.41% discount (Gilad was captive for 1,941 days) for all our profilers:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href="http://nhprof.com/"&gt;NHibernate Profiler&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="http://efprof.com/"&gt;Entity Framework Profiler&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="http://l2sprof.com/"&gt;Linq to SQL Profiler&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="http://llblgenprof.com/"&gt;LLBLGen Profiler&lt;/a&gt; &lt;/li&gt; &lt;li&gt;&lt;a href="http://hibernateprofiler.com/"&gt;Hibernate Profiler&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Hell, even our &lt;a href="http://nhprof.com/commercialsupport"&gt;commercial support for NHibernate&lt;/a&gt; is participating.&lt;/p&gt; &lt;p&gt;Please note that any political comment to this post that I don’t agree with will be deleted.&lt;/p&gt;</description><link>http://ayende.com/blog/130049/gilad-shalit-is-back?key=b8b09d35-b65b-4925-9046-a6315d3899aa</link><guid>http://ayende.com/blog/130049/gilad-shalit-is-back?key=b8b09d35-b65b-4925-9046-a6315d3899aa</guid><pubDate>Tue, 18 Oct 2011 10:00:00 GMT</pubDate></item><item><title>What is next for the profilers?</title><description>&lt;p&gt;We have been working on the profilers (&lt;a href="http://nhprof.com/"&gt;NHibernate Profiler&lt;/a&gt;, &lt;a href="http://efprof.com/"&gt;Entity Framework Profiler&lt;/a&gt;, &lt;a href="http://l2sprof.com/"&gt;Linq to SQL Profiler&lt;/a&gt;, &lt;a href="http://llblgenprof.com/"&gt;LLBLGen Profiler&lt;/a&gt; and &lt;a href="http://hibernateprofiler.com"&gt;Hibernate Profiler&lt;/a&gt;) for close to three years now. And we have been running always as 1.x, so we didn’t have a major release (although we have continual releases, we currently have close to 900 drops of the 1.x version).&lt;/p&gt; &lt;p&gt;The question now becomes, what is going to happen in the next version of the profiler?&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Production Profiling, the ability to setup your application so that you can connect to your production application and see what is going on &lt;em&gt;right now&lt;/em&gt;. &lt;/li&gt; &lt;li&gt;Error Analysis, the ability to provide you with additional insight and common solution to recurring problems.&lt;/li&gt; &lt;li&gt;Global Query Analysis, the ability to take all of your queries, look at their query plans and show your potential issues.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Those are the big ones, we have a few others, and a surprise in store &lt;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="http://ayende.com/blog/Images/Windows-Live-Writer/What-is-next-for-the-profilers_868C/wlEmoticon-smile_2.png"&gt;&lt;/p&gt; &lt;p&gt;What would you want to see in the next version of the profiler?&lt;/p&gt;</description><link>http://ayende.com/blog/11265/what-is-next-for-the-profilers?key=98ae56ef-3200-41b0-beec-1c206cbe1608</link><guid>http://ayende.com/blog/11265/what-is-next-for-the-profilers?key=98ae56ef-3200-41b0-beec-1c206cbe1608</guid><pubDate>Thu, 02 Jun 2011 09:00:00 GMT</pubDate></item><item><title>Uber Prof &amp;amp; NuGet</title><description>&lt;p&gt;Fitzchak has all the details in our &lt;a href="http://blogs.hibernatingrhinos.com/archive/2011/03/31/nuget-packages-and-an-example-use-of-the-profiler.aspx"&gt;company blog&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;img alt="NugetPackages" src="http://blogs.hibernatingrhinos.com/images/blogs_hibernatingrhinos_com/Windows-Live-Writer/33b8e30a3166_9ED0/NugetPackages_thumb_1.png" /&gt;&lt;/p&gt;</description><link>http://ayende.com/blog/4799/uber-prof-amp-nuget?key=e4deb5ce-de52-4c43-89ba-2c3f410d2801</link><guid>http://ayende.com/blog/4799/uber-prof-amp-nuget?key=e4deb5ce-de52-4c43-89ba-2c3f410d2801</guid><pubDate>Fri, 01 Apr 2011 11:00:00 GMT</pubDate></item><item><title>NHibernate Profiler update: Client Profile &amp;amp; NHibernate 3.x updates</title><description>&lt;p&gt;We just finished a pretty major change to how the &lt;a href="http://nhprof.com"&gt;NHibernate Profiler&lt;/a&gt; interacts with NHibernate. That change was mostly driven out of the desire to fully support running under the client profile and to allow us to support the new logging infrastructure in NHibernate 3.x.&lt;/p&gt;  &lt;p&gt;The good news, this is done &lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://ayende.com/Blog/images/ayende_com/Blog/Windows-Live-Writer/6f0d21354309_E22E/wlEmoticon-smile_2.png" /&gt;, you can now use NH Prof from the client profile, and you don’t need to do anything to make it work for NHibernate 3.x.&lt;/p&gt;  &lt;p&gt;The slightly bad news is that if you were relying on log4net conifguration to configure NH Prof, there is a breaking change that affects you. Basically, you need to update your configuration. You can find the full details on how to do this in the &lt;a href="http://nhprof.com/Learn/Usage/ProfileAppWithConfiguration"&gt;documentation&lt;/a&gt;.&lt;/p&gt;</description><link>http://ayende.com/blog/4780/nhibernate-profiler-update-client-profile-amp-nhibernate-3-x-updates?key=b9fed313-c182-4419-8eb4-398335fe7369</link><guid>http://ayende.com/blog/4780/nhibernate-profiler-update-client-profile-amp-nhibernate-3-x-updates?key=b9fed313-c182-4419-8eb4-398335fe7369</guid><pubDate>Sun, 13 Mar 2011 14:28:00 GMT</pubDate></item><item><title>New Profiler Feature: Avoid Writes from Multiple Sessions In The Same Request</title><description>&lt;p&gt;Because I keep getting asked, this feature is available for the following profilers:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://nhprof.com/"&gt;NHibernate Profiler&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://efprof.com/"&gt;Entity Framework Profiler&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://l2sprof.com/"&gt;Linq to SQL Profiler&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://llblgenprof.com/"&gt;LLBLGen Profiler&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://hibernateprofiler.com/"&gt;Hibernate Profiler&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;This new feature detects a very interesting bad practice, write to the database from multiple session in the same web request.&lt;/p&gt;  &lt;p&gt;For example, consider the following code:&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; SaveAccount(Account account)
{
    &lt;span class="kwrd"&gt;using&lt;/span&gt;(var session = sessionFactory.OpenSession())
    &lt;span class="kwrd"&gt;using&lt;/span&gt;(session.BeginTransaction())
    {
           session.SaveOrUpdate(account);
           session.Transaction.Commit();    
    }
}&lt;/pre&gt;

  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; Account GetAccount(&lt;span class="kwrd"&gt;int&lt;/span&gt; id)
{
    &lt;span class="kwrd"&gt;using&lt;/span&gt;(var session = sessionFactory.OpenSession())
    {
        &lt;span class="kwrd"&gt;return&lt;/span&gt; session.Get&amp;lt;Account&amp;gt;(id);
    }
}&lt;/pre&gt;
  &lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;&lt;/blockquote&gt;

&lt;p&gt;It is bad for several reasons, micro managing the session is just one of them, but the worst part is yet to come…&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; MakePayment(&lt;span class="kwrd"&gt;int&lt;/span&gt; fromAccount, &lt;span class="kwrd"&gt;int&lt;/span&gt; toAccount, &lt;span class="kwrd"&gt;decimal&lt;/span&gt; ammount)
{
    var from = Dao.GetAccount(fromAccount);
    var to = Dao.GetAccount(toAccount);
    from.Total -= amount;
    to.Total += amount;
    Dao.SaveAccount(from);
    Dao.SaveAccount(to);
}&lt;/pre&gt;
  &lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;&lt;/blockquote&gt;

&lt;p&gt;Do you see the error here? There are actually several, let me count them:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;We are using 4 different connections to the database in a single method.&lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;We don’t have transactional safety!!!!&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think about it, if the server crashed between the fifth and sixth lines of this method, where would we be? &lt;/p&gt;

&lt;p&gt;We would be in that wonderful land where money disappear into thin air and we stare at that lovely lawsuit folder and then jump from a high window to a stormy sea.&lt;/p&gt;

&lt;p&gt;Or, of course, you could use the profiler, which will tell you that you are doing something which should be avoided:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/Windows-Live-Writer/New-Alert-Multiple-Write-Sessions-In-The_C8D8/image_2.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/Windows-Live-Writer/New-Alert-Multiple-Write-Sessions-In-The_C8D8/image_thumb.png" width="775" height="110" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Isn’t that better than swimming with the sharks?&lt;/p&gt;</description><link>http://ayende.com/blog/4775/new-profiler-feature-avoid-writes-from-multiple-sessions-in-the-same-request?key=7f102633-ec3a-497f-b84f-8c191dab2292</link><guid>http://ayende.com/blog/4775/new-profiler-feature-avoid-writes-from-multiple-sessions-in-the-same-request?key=7f102633-ec3a-497f-b84f-8c191dab2292</guid><pubDate>Tue, 01 Mar 2011 12:26:00 GMT</pubDate></item><item><title>New Uber Prof Feature: Too Many Database Calls In The Same Request</title><description>&lt;p&gt;&lt;font size="3"&gt;Recently, we added a way to track alerts across all the sessions the request. This alert will detect whenever you are making too many database calls in the same request.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;But wait, don’t we already have that?&lt;/p&gt;  &lt;p&gt;Yes, we do, but that was limited to the scope of one session. there is a very large set of codebases where the usage of OR/Ms is… suboptimal (in other words, they could take the most advantage of the profiler abilities to detect issues and suggest solutions to them), but because of the way they are structured, they weren’t previously detected.&lt;/p&gt;  &lt;p&gt;&lt;font size="3"&gt;What is the difference between a session and a request? &lt;/font&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font size="3"&gt;Note: I am using NHibernate terms here, but naturally this feature is shared among all profiler:&lt;/font&gt;&lt;/p&gt;    &lt;ul&gt;     &lt;li&gt;&lt;a href="http://nhprof.com/"&gt;NHibernate Profiler&lt;/a&gt;&lt;/li&gt;      &lt;li&gt;&lt;a href="http://efprof.com/"&gt;Entity Framework Profiler&lt;/a&gt;&lt;/li&gt;      &lt;li&gt;&lt;a href="http://l2sprof.com/"&gt;Linq to SQL Profiler&lt;/a&gt;&lt;/li&gt;      &lt;li&gt;&lt;a href="http://llblgenprof.com/"&gt;LLBLGen Profiler&lt;/a&gt;&lt;/li&gt;      &lt;li&gt;&lt;a href="http://hibernateprofiler.com/"&gt;Hibernate Profiler&lt;/a&gt;&lt;/li&gt;   &lt;/ul&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;font size="3"&gt;A session is the NHibernate session (or the data/object context in linq to sql / entity framework), and the request is the HTTP request or the WCF operation. If you had code such as the following:&lt;/font&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; T GetEntity&amp;lt;T&amp;gt;(&lt;span class="kwrd"&gt;int&lt;/span&gt; id)
{
    &lt;span class="kwrd"&gt;using&lt;/span&gt; (var session = sessionFactory.OpenSession())
    {
         &lt;span class="kwrd"&gt;return&lt;/span&gt; session.Get&amp;lt;T&amp;gt;(id);
    }
}&lt;/pre&gt;
  &lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;&lt;/blockquote&gt;

&lt;p&gt;This code is bad, it micro manages the session, it uses too many connections to the database, it … well, you get the point. The problem is that code that uses this code:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; IEnumerable&amp;lt;Friends&amp;gt; GetFriends(&lt;span class="kwrd"&gt;int&lt;/span&gt;[] friends)
{
   var results = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;Friends&amp;gt;();
   &lt;span class="kwrd"&gt;foreach&lt;/span&gt;(var id &lt;span class="kwrd"&gt;in&lt;/span&gt; friends)
       results.Add(GetEnttiy&amp;lt;Friend&amp;gt;(id));

   &lt;span class="kwrd"&gt;return&lt;/span&gt; results;
}&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;p&gt;The code above would look like the following in the profiler:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/Windows-Live-Writer/New-Alert-Too-Many-Database-Calls-In-The_C8E2/Image1.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Image1" border="0" alt="Image1" src="http://ayende.com/Blog/images/ayende_com/Blog/Windows-Live-Writer/New-Alert-Too-Many-Database-Calls-In-The_C8E2/Image1_thumb.png" width="251" height="400" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, each call is in a separate session, and previously, we wouldn’t have been able to detect that you have too many calls (because each call is a separate session).&lt;/p&gt;

&lt;p&gt;Now, however, we will alert the user with a too many database calls in the same request alerts. &lt;/p&gt;

&lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/Windows-Live-Writer/New-Alert-Too-Many-Database-Calls-In-The_C8E2/Image2.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Image2" border="0" alt="Image2" src="http://ayende.com/Blog/images/ayende_com/Blog/Windows-Live-Writer/New-Alert-Too-Many-Database-Calls-In-The_C8E2/Image2_thumb.png" width="699" height="317" /&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://ayende.com/blog/4774/new-uber-prof-feature-too-many-database-calls-in-the-same-request?key=5fe23059-c0d9-4990-8c16-0372c0ee5bac</link><guid>http://ayende.com/blog/4774/new-uber-prof-feature-too-many-database-calls-in-the-same-request?key=5fe23059-c0d9-4990-8c16-0372c0ee5bac</guid><pubDate>Mon, 28 Feb 2011 12:15:00 GMT</pubDate></item><item><title>New Uber Prof Concept: Cross Session Alerts</title><description>&lt;p&gt;We have recently been doing some work on Uber Prof, mostly in the sense of a code review, and I wanted to demonstrate how easy it was to add a new feature. The problem is that we couldn’t really think of a nice feature to add that we didn’t already have. &lt;/p&gt;  &lt;p&gt;Then we started thinking about features that aren’t there and that there wasn’t anything in Uber Prof to enable, and we reached the conclusion that one limitation we have right now is the inability to analyze your application’s behavior beyond the session’s level. But there is actually a whole &lt;em&gt;set&lt;/em&gt; of bad practices that are there when you are using multiple sessions.&lt;/p&gt;  &lt;p&gt;That led to the creation of a new concept the Cross Session Alert, unlike the alerts we had so far, those alerts looks at the data stream with a much broader scope, and they can analyze and detect issues that we previously couldn’t detect.&lt;/p&gt;  &lt;p&gt;I am going to be posting extensively on some of the new features in just a bit, but in the meantime, why don’t you tell me what sort of features do you think this new concept is enabling.&lt;/p&gt;  &lt;p&gt;And just a reminder, my architecture is based around &lt;a href="http://ayende.com/Blog/archive/2009/03/06/application-structure-concepts-amp-features.aspx"&gt;Concepts &amp;amp; Features&lt;/a&gt;.&lt;/p&gt;</description><link>http://ayende.com/blog/4773/new-uber-prof-concept-cross-session-alerts?key=eeebdd89-c238-4266-b655-fc2be2a2ae50</link><guid>http://ayende.com/blog/4773/new-uber-prof-concept-cross-session-alerts?key=eeebdd89-c238-4266-b655-fc2be2a2ae50</guid><pubDate>Fri, 25 Feb 2011 10:05:00 GMT</pubDate></item><item><title>Uber Prof New Features: A better query plan</title><description>&lt;blockquote&gt;Originally posted at 1/7/2011&lt;/blockquote&gt;&lt;p&gt;Because I keep getting asked, this feature is available for the following profilers:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://nhprof.com"&gt;NHibernate Profiler&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://efprof.com"&gt;Entity Framework Profiler&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://l2sprof.com"&gt;Linq to SQL Profiler&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://llblgenprof.com"&gt;LLBLGen Profiler&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://hibernateprofiler.com"&gt;Hibernate Profiler&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;This feature is actually two separate ones. The first is the profiler detecting what is the most expensive part of the query plan and making it instantly visible. As you can see, in this fairly complex query, it is this select statement that is the hot spot.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/UberProfNewFeaturesAbetterqueryplan_CDD8/image_8.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/UberProfNewFeaturesAbetterqueryplan_CDD8/image_thumb_3.png" width="1132" height="666" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p /&gt;  &lt;p /&gt;  &lt;p /&gt;  &lt;p&gt;Another interesting feature that only crops up whenever we are dealing with complex query plans is that the query plan can get &lt;em&gt;big&lt;/em&gt;. And by that I mean &lt;em&gt;really&lt;/em&gt; big. Too big for a single screen.&lt;/p&gt;  &lt;p&gt;Therefore, we added zooming capabilities as well as the mini map that you see in the top right corner.&lt;/p&gt;</description><link>http://ayende.com/blog/4752/uber-prof-new-features-a-better-query-plan?key=7d9a03d2-2816-444d-a87c-5750ccf802f3</link><guid>http://ayende.com/blog/4752/uber-prof-new-features-a-better-query-plan?key=7d9a03d2-2816-444d-a87c-5750ccf802f3</guid><pubDate>Sat, 15 Jan 2011 10:00:00 GMT</pubDate></item><item><title>Uber Prof New Features: Go To Session from alert</title><description>&lt;blockquote&gt;Originally posted at 1/7/2011&lt;/blockquote&gt;&lt;p&gt;This is another oft requested feature that we just implemented. The new feature is available for the full suite of Uber Profilers:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://nhprof.com"&gt;NHibernate Profiler&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://efprof.com"&gt;Entity Framework Profiler&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://l2sprof.com"&gt;Linq to SQL Profiler&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://llblgenprof.com"&gt;LLBLGen Profiler&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://hibernateprofiler.com"&gt;Hibernate Profiler&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;You can see the new feature below:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/UberProfNewFeaturesGoToSessionfromalert_C9AD/image_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/UberProfNewFeaturesGoToSessionfromalert_C9AD/image_thumb.png" width="1094" height="388" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;I think it is cute, and was surprisingly easy to do.&lt;/p&gt;  &lt;p&gt;Uber Prof have recently passed the stage where it is mostly implemented using itself, so I just had to wire a few things together, and then I spent most of the time just making sure that things aligned correctly on the UI.&lt;/p&gt;</description><link>http://ayende.com/blog/4751/uber-prof-new-features-go-to-session-from-alert?key=b28db449-7214-454f-abbf-7eaf960a299a</link><guid>http://ayende.com/blog/4751/uber-prof-new-features-go-to-session-from-alert?key=b28db449-7214-454f-abbf-7eaf960a299a</guid><pubDate>Fri, 14 Jan 2011 10:00:00 GMT</pubDate></item><item><title>NH Prof New Feature: Alert on bad ‘like’ query</title><description>&lt;blockquote&gt;Originally posted at 12/3/2010&lt;/blockquote&gt;&lt;p&gt;One of the things that are coming to &lt;a href="http://nhprof.com"&gt;NH Prof&lt;/a&gt; is more smarts at the analysis part. We now intend to create a lot more alerts and guidance. One of the new features that is already there as part of this strategy is detecting bad ‘like’ queries.&lt;/p&gt;  &lt;p&gt;For example, let us take a look at this &lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/Windows-Live-Writer/4c0ce342b3e3_8AA7/image_2.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/Windows-Live-Writer/4c0ce342b3e3_8AA7/image_thumb.png" width="268" height="61" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This is generally not a good idea, because that sort of query cannot use an index, and requires the database to generate a table scan, which can be pretty slow.&lt;/p&gt;  &lt;p&gt;Here is how it looks like from the query perspective:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/Windows-Live-Writer/4c0ce342b3e3_8AA7/image_6.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/Windows-Live-Writer/4c0ce342b3e3_8AA7/image_thumb_2.png" width="329" height="111" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;And NH Prof (and all the other profilers) will now detect this and warn about this.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/Windows-Live-Writer/4c0ce342b3e3_8AA7/image_8.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/Windows-Live-Writer/4c0ce342b3e3_8AA7/image_thumb_3.png" width="561" height="77" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;In fact, it will even detect queries like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/Windows-Live-Writer/4c0ce342b3e3_8AA7/image_4.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/Windows-Live-Writer/4c0ce342b3e3_8AA7/image_thumb_1.png" width="457" height="151" /&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://ayende.com/blog/4717/nh-prof-new-feature-alert-on-bad-like-query?key=97890a55-caca-4d7b-a7b7-47dfb92e776a</link><guid>http://ayende.com/blog/4717/nh-prof-new-feature-alert-on-bad-like-query?key=97890a55-caca-4d7b-a7b7-47dfb92e776a</guid><pubDate>Thu, 09 Dec 2010 10:00:00 GMT</pubDate></item><item><title>Feature selection strategies for NH Prof</title><description>&lt;blockquote&gt;Originally posted at 12/3/2010&lt;/blockquote&gt;&lt;p&gt;I recently had a discussion on how I select features for NH Prof.  The simple answer is that I started with features that would appeal to me.  My dirty little secret is that the only reason NH Prof even exists is that I wanted it so much and no one else did it already.&lt;/p&gt;  &lt;p&gt;But while that lasted for a good while, I eventually got to the point where NH Prof does everything that &lt;em&gt;I&lt;/em&gt; need it to do. So, what next… ?&lt;/p&gt;  &lt;p&gt;Feature selection is a complex topic, and it is usually performed in the dark, because you have to guess at what people are using. A while ago I setup NH Prof so I can get usage reports (they are fully anonymous, and were covered on this blog previously). Those usage reports come in very handily when I need to understand how people are using NH Prof. Think about it like a users study, but without the cost, and without the artificial environment. &lt;/p&gt;  &lt;p&gt;Here are the (real) numbers for NH Prof:&lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="0" width="645"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td width="204"&gt;Action&lt;/td&gt;        &lt;td width="65"&gt;%&lt;/td&gt;        &lt;td width="374"&gt;What it means&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="204"&gt;Selection&lt;/td&gt;        &lt;td width="65"&gt;62.76%&lt;/td&gt;        &lt;td width="374"&gt;Selecting a statement&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="204"&gt;Session-Statements&lt;/td&gt;        &lt;td width="65"&gt;20.58%&lt;/td&gt;        &lt;td width="374"&gt;Looking at a particular session statements&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="204"&gt;Recent-Statements&lt;/td&gt;        &lt;td width="65"&gt;8.67%&lt;/td&gt;        &lt;td width="374"&gt;The recent statements (default view)&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="204"&gt;Unique-Queries&lt;/td&gt;        &lt;td width="65"&gt;2.73%&lt;/td&gt;        &lt;td width="374"&gt;The unique queries report&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="204"&gt;Listening-Toggle&lt;/td&gt;        &lt;td width="65"&gt;1.10%&lt;/td&gt;        &lt;td width="374"&gt;Stop / Start listening to connections&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="204"&gt;Session-Usage&lt;/td&gt;        &lt;td width="65"&gt;0.91%&lt;/td&gt;        &lt;td width="374"&gt;Showing the session usage tab for a session&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="204"&gt;Session-Entities&lt;/td&gt;        &lt;td width="65"&gt;0.54%&lt;/td&gt;        &lt;td width="374"&gt;Looking at the loaded entities in a session&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="204"&gt;Query-Execute&lt;/td&gt;        &lt;td width="65"&gt;0.50%&lt;/td&gt;        &lt;td width="374"&gt;Show the results of a query&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="204"&gt;Connections-Edit&lt;/td&gt;        &lt;td width="65"&gt;0.38%&lt;/td&gt;        &lt;td width="374"&gt;Editing a connection string&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="204"&gt;Queries-By-Method&lt;/td&gt;        &lt;td width="65"&gt;0.34%&lt;/td&gt;        &lt;td width="374"&gt;The queries by method report&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="204"&gt;Queries-By-Url&lt;/td&gt;        &lt;td width="65"&gt;0.27%&lt;/td&gt;        &lt;td width="374"&gt;The queries by URL report&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="204"&gt;Overall-Usage&lt;/td&gt;        &lt;td width="65"&gt;0.25%&lt;/td&gt;        &lt;td width="374"&gt;The overall usage report&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="204"&gt;Show-Settings&lt;/td&gt;        &lt;td width="65"&gt;0.23%&lt;/td&gt;        &lt;td width="374"&gt;Show settings&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="204"&gt;Aggregate-Sessions&lt;/td&gt;        &lt;td width="65"&gt;0.21%&lt;/td&gt;        &lt;td width="374"&gt;Selecting more than 1 session&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="204"&gt;Reports-Queries-Expensive&lt;/td&gt;        &lt;td width="65"&gt;0.16%&lt;/td&gt;        &lt;td width="374"&gt;The expensive queries report&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="204"&gt;Session-Remove&lt;/td&gt;        &lt;td width="65"&gt;0.13%&lt;/td&gt;        &lt;td width="374"&gt;Remove a session&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="204"&gt;Queries-By-Isolation-Level&lt;/td&gt;        &lt;td width="65"&gt;0.08%&lt;/td&gt;        &lt;td width="374"&gt;The queries by isolation level report&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="204"&gt;File-Load&lt;/td&gt;        &lt;td width="65"&gt;0.04%&lt;/td&gt;        &lt;td width="374"&gt;Load a saved session&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="204"&gt;File-Save&lt;/td&gt;        &lt;td width="65"&gt;0.03%&lt;/td&gt;        &lt;td width="374"&gt;Save a session&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="204"&gt;Html-Export&lt;/td&gt;        &lt;td width="65"&gt;0.02%&lt;/td&gt;        &lt;td width="374"&gt;Exporting to HTML&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="204"&gt;Sessions-Diff&lt;/td&gt;        &lt;td width="65"&gt;0.01%&lt;/td&gt;        &lt;td width="374"&gt;Diffing two sessions&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="204"&gt;Sort-By-ShortSql&lt;/td&gt;        &lt;td width="65"&gt;0.01%&lt;/td&gt;        &lt;td width="374"&gt;Sort by SQL&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="204"&gt;Session-Rename&lt;/td&gt;        &lt;td width="65"&gt;0.01%&lt;/td&gt;        &lt;td width="374"&gt;Rename a session&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="204"&gt;Sort-By-Duration&lt;/td&gt;        &lt;td width="65"&gt;0.01%&lt;/td&gt;        &lt;td width="374"&gt;Sort by duration&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="204"&gt;Sort-By-RowCount&lt;/td&gt;        &lt;td width="65"&gt;&amp;gt; 0.00%&lt;/td&gt;        &lt;td width="374"&gt;Sort by row count&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="204"&gt;GoToSession&lt;/td&gt;        &lt;td width="65"&gt;&amp;gt; 0.00%&lt;/td&gt;        &lt;td width="374"&gt;Go from report to statement’s session&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="204"&gt;Sort-By-AvgDuration&lt;/td&gt;        &lt;td width="65"&gt;&amp;gt; 0.00%&lt;/td&gt;        &lt;td width="374"&gt;Sort by duration (in reports)&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="204"&gt;Production-Connect&lt;/td&gt;        &lt;td width="65"&gt;&amp;gt; 0.00%&lt;/td&gt;        &lt;td width="374"&gt;(Not publically available) Connect to production server&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="204"&gt;Sort-By-QueryCount&lt;/td&gt;        &lt;td width="65"&gt;&amp;gt; 0.00%&lt;/td&gt;        &lt;td width="374"&gt;Sort by query count (in reports)&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="204"&gt;Sort-By-Alerts&lt;/td&gt;        &lt;td width="65"&gt;&amp;gt; 0.00%&lt;/td&gt;        &lt;td width="374"&gt;Sort by alerts (for statements)&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="204"&gt;Sort-By-Count&lt;/td&gt;        &lt;td width="65"&gt;&amp;gt; 0.00%&lt;/td&gt;        &lt;td width="374"&gt;Sort by row count &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;There is nothing really earth shattering here, by far, people are using NH Prof as a tool to show them the SQL. Note how most of the other features are used much more rarely. This doesn’t mean that they are not valuable, but it does represent that a feature that isn’t immediately available on the “show me the SQL” usage path is going to be used very rarely.&lt;/p&gt;  &lt;p&gt;There is another aspect for feature selection, will this feature increase my software sales? &lt;/p&gt;  &lt;p&gt;Some features are Must Have, your users won’t buy the product without them. Some features are Nice To Have, but have no impact on the sale/no sale. Some features are very effective in driving sales. &lt;/p&gt;  &lt;p&gt;In general, there is a balancing act between how complex a feature is, how often people will use it and how useful would it be in marketing.&lt;/p&gt;  &lt;p&gt;I learned quickly that having better analysis (alerts) is a good competitive advantage, which is why I optimized the hell out of this development process. In contrast to that, things like reports are much less interesting, because once you got the Must Have ones, adding more doesn’t seem to be an effective way of going about things. &lt;/p&gt;  &lt;p&gt;And then, of course, there are the features whose absence annoys me…&lt;/p&gt;</description><link>http://ayende.com/blog/4715/feature-selection-strategies-for-nh-prof?key=08879568-8981-4843-8c59-53580b2ae00e</link><guid>http://ayende.com/blog/4715/feature-selection-strategies-for-nh-prof?key=08879568-8981-4843-8c59-53580b2ae00e</guid><pubDate>Tue, 07 Dec 2010 10:00:00 GMT</pubDate></item><item><title>The most amazing demo ever</title><description>&lt;p&gt;I was giving a talk yesterday at the &lt;a href="http://melbourne.ozalt.net/"&gt;Melbourne ALT.Net group&lt;/a&gt;, the topic of which was How Ayende’s Build Software. This isn’t the first time that I give this talk, and I thought that talking in the abstracts is only useful so much.&lt;/p&gt;  &lt;p&gt;So I decided to demonstrate, live, how I get stuff done as quickly as I am. One of the most influential stories that I ever read was The Man Who Was Too Lazy to Fail - &lt;i&gt;Robert A. Heinlein. &lt;/i&gt;He does a much better job in explain the reasoning, but essentially, it comes down to finding anything that you do more than once, and removing all friction from it.&lt;/p&gt;  &lt;p&gt;In the talk, I decided to demonstrate, live, how this is done. I asked people to give me an idea about a new feature for NH Prof. After some back and forth, we settled on warning when you are issuing a query using a like that will force the database to use a table scan.  I then proceed to implement the scenario showing what I wanted:&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; EndsWith : INHibernateScenario
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Execute(ISessionFactory factory)
    {
        &lt;span class="kwrd"&gt;using&lt;/span&gt;(var s = factory.OpenSession())
        {
            s.CreateCriteria&amp;lt;Blog&amp;gt;()
                .Add(Restrictions.Like(&lt;span class="str"&gt;"Title"&lt;/span&gt;, &lt;span class="str"&gt;"%ayende"&lt;/span&gt;))
                .List();
        }
    }
}&lt;/pre&gt;
  &lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;&lt;/blockquote&gt;

&lt;p&gt;Implemented the feature itself, and tried it out live. This showed off some aspects about the actual development, the ability to execute just the right piece of the code that I want by offering the ability to execute individual scenarios easily.&lt;/p&gt;

&lt;p&gt;We even did some debugging because it didn’t work the first time. Then I wrote the test for it:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; WillDetectQueriesUsingEndsWith : IntegrationTestBase
{
    [Fact]
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; WillIssueWarning()
    {
        ExecuteScenarioInDifferentAppDomain&amp;lt;EndsWith&amp;gt;();

        var statementModel = model.RecentStatements.Statements.First();

        Assert.True(
            statementModel.Alerts.Any(x=&amp;gt;x.HelpTopic == AlertInformation.EndsWithWillForceTableScan.HelpTopic)
            );
    }
    
}&lt;/pre&gt;
  &lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;&lt;/blockquote&gt;

&lt;p&gt;So far, so good, I have been doing stuff like that for a while now, live.&lt;/p&gt;

&lt;p&gt;But it is the next step that I think shocked most people, because I then committed the changes, and let the CI process takes care of things.  By the time that I showed the people in the room that the new build is now publically available, it has &lt;em&gt;already been download&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Now, just to give you some idea, that &lt;em&gt;wasn’t the point of this talk&lt;/em&gt;. I did a whole talk on different topic, and the whole process from “I need an idea” to “users are the newly deployed feature” took something in the order of 15 minutes, and that includes debugging to fix a problem.&lt;/p&gt;</description><link>http://ayende.com/blog/4710/the-most-amazing-demo-ever?key=89ee73f4-b37a-4b7b-b7d2-30ced11b58d0</link><guid>http://ayende.com/blog/4710/the-most-amazing-demo-ever?key=89ee73f4-b37a-4b7b-b7d2-30ced11b58d0</guid><pubDate>Wed, 01 Dec 2010 18:17:00 GMT</pubDate></item><item><title>What is Uber Prof’s competitive advantage?</title><description>&lt;blockquote&gt;Originally posted at 11/25/2010&lt;/blockquote&gt;&lt;p&gt;In a &lt;a href="http://ayende.com/Blog/archive/2010/11/24/your-design-should-be-focused-on-your-competitive-advantage.aspx"&gt;recent post&lt;/a&gt;, I discussed the notion of competitive advantage and how you should play around them. In this post, I am going to focus on Uber Prof. Just to clarify, when I am talking about Uber Prof, I am talking about &lt;a href="http://nhprof.com/"&gt;NHibernate Profiler&lt;/a&gt;, &lt;a href="http://efprof.com/"&gt;Entity Framework Profiler&lt;/a&gt;, &lt;a href="http://l2sprof.com/"&gt;Linq to SQL Profiler&lt;/a&gt;, &lt;a href="http://hibernateprofiler.com/"&gt;Hibernate Profiler&lt;/a&gt; and &lt;a href="http://llblgenprof.com/"&gt;LLBLGen Profiler&lt;/a&gt;. Uber Prof is just a handle for me to use to talk about each of those.&lt;/p&gt;  &lt;p&gt;So, what is the major competitive advantage that I see in the Uber Prof line of products?&lt;/p&gt;  &lt;p&gt;Put very simply, they focus very heavily on the developer’s point of view. &lt;/p&gt;  &lt;p&gt;Other profilers will give you the SQL that is being executed, but Uber Prof will show you the SQL and:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Format that SQL in a way that make it easy to read.&lt;/li&gt;    &lt;li&gt;Group the SQL statements into sessions. Which let the developer look at what is going on in the natural boundary.&lt;/li&gt;    &lt;li&gt;Associate each query with the exact line of code that executed it.&lt;/li&gt;    &lt;li&gt;Provide the developer with guidance about improving their code.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;There are other stuff, of course, but those are the core features that make Uber Prof into what it is.&lt;/p&gt;</description><link>http://ayende.com/blog/4705/what-is-uber-profs-competitive-advantage?key=6dca10eb-7243-4817-8756-300adfc29ee8</link><guid>http://ayende.com/blog/4705/what-is-uber-profs-competitive-advantage?key=6dca10eb-7243-4817-8756-300adfc29ee8</guid><pubDate>Sat, 27 Nov 2010 10:00:00 GMT</pubDate></item><item><title>Profiler new features: Data binding alerts</title><description>&lt;p&gt;The following features apply to &lt;a href="http://nhprof.com/"&gt;NHProf&lt;/a&gt;, &lt;a href="http://efprof.com/"&gt;EFProf&lt;/a&gt;, &lt;a href="http://l2sprof.com/"&gt;L2SProf&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;In general, it is strong discouraged to data bind directly to an IQueryable. Mostly, that is because data binding may actually iterate over the IQueryable several times, resulting in multiple queries being generated from something that can be done purely in memory. Worse, it is actually pretty common for data binding to result in lazy loading, and lazy loading from data binding almost always result in SELECT N+1. The profiler can now detect and warn you about such mistakes preemptively. More than that, the profiler can also now detect queries that are being generated from the views in an ASP.Net MVC application, another bad practice that I don’t like.&lt;/p&gt;  &lt;p&gt;You can find more information about each warnings here:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://efprof.com/learn/alerts/DataBindingQueries"&gt;Data Binding &amp;amp; Queries Shouldn’t Mix&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://l2sprof.com/learn/alerts/QueriesFromViews"&gt;Don’t Query From The View&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;WPF detection:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/ProfilernewfeaturesDatabindingalerts_918F/image_2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/ProfilernewfeaturesDatabindingalerts_918F/image_thumb.png" width="448" height="120" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p /&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/ProfilernewfeaturesDatabindingalerts_918F/image_4.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/ProfilernewfeaturesDatabindingalerts_918F/image_thumb_1.png" width="751" height="205" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;WinForms detections:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/ProfilernewfeaturesDatabindingalerts_918F/image_8.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/ProfilernewfeaturesDatabindingalerts_918F/image_thumb_3.png" width="563" height="151" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/ProfilernewfeaturesDatabindingalerts_918F/image_6.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/ProfilernewfeaturesDatabindingalerts_918F/image_thumb_2.png" width="733" height="197" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Web applications:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/ProfilernewfeaturesDatabindingalerts_918F/image_10.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/ProfilernewfeaturesDatabindingalerts_918F/image_thumb_4.png" width="581" height="189" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/ProfilernewfeaturesDatabindingalerts_918F/image_12.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/ProfilernewfeaturesDatabindingalerts_918F/image_thumb_5.png" width="743" height="210" /&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://ayende.com/blog/4642/profiler-new-features-data-binding-alerts?key=d2ea3054-7db3-4e3f-b221-1d71b53d7aef</link><guid>http://ayende.com/blog/4642/profiler-new-features-data-binding-alerts?key=d2ea3054-7db3-4e3f-b221-1d71b53d7aef</guid><pubDate>Mon, 27 Sep 2010 10:00:00 GMT</pubDate></item><item><title>Profiler new features, Sept Edition</title><description>&lt;p&gt;The following features apply to &lt;a href="http://nhprof.com"&gt;NHProf&lt;/a&gt;, &lt;a href="http://efprof.com"&gt;EFProf&lt;/a&gt;, &lt;a href="http://hibernateprofiler.com"&gt;HProf&lt;/a&gt;, &lt;a href="http://l2sprof.com"&gt;L2SProf&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The first feature is something that was frequently requested, but we kept deferring. Not because it was hard, but because it was tedious and we had cooler features to implement: Sorting.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/ProfilernewfeaturesSeptEdition_8A71/image_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/ProfilernewfeaturesSeptEdition_8A71/image_thumb.png" width="681" height="135" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Yep. Plain old sorting for all the grids in the application.&lt;/p&gt;  &lt;p&gt;Not an exciting feature, I’ll admit, but an important one.&lt;/p&gt;  &lt;p&gt;The feature that gets &lt;em&gt;me&lt;/em&gt; exciting is the Go To Session. Let us take the Expensive Queries report as a great example for this feature:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/ProfilernewfeaturesSeptEdition_8A71/image_6.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/ProfilernewfeaturesSeptEdition_8A71/image_thumb_2.png" width="609" height="136" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;As you can see, we have a very expensive query. Let us ignore the &lt;em&gt;reason&lt;/em&gt; it is expensive, and assume that we aren’t sure about that.&lt;/p&gt;  &lt;p&gt;The problem with the reports feature in the profiler is that while it exposes a lot of information (expensive queries, most common queries, etc), it also lose the context of where this query is running. That is why you can, in any of the reports, right click on a statement and go directly to the session where it originated from:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/ProfilernewfeaturesSeptEdition_8A71/image_8.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/ProfilernewfeaturesSeptEdition_8A71/image_thumb_3.png" width="538" height="122" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/ProfilernewfeaturesSeptEdition_8A71/image_10.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/ProfilernewfeaturesSeptEdition_8A71/image_thumb_4.png" width="578" height="149" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;We bring the context back to the intelligence that we provide.&lt;/p&gt;  &lt;p&gt;What happen if we have a statement that appear in several sessions?&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/ProfilernewfeaturesSeptEdition_8A71/image_12.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/ProfilernewfeaturesSeptEdition_8A71/image_thumb_5.png" width="480" height="219" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p /&gt;  &lt;p&gt;You can select each session that this statement appears in, getting back the context of the statement and finding out a lot more about it.&lt;/p&gt;  &lt;p&gt;I am very happy about this feature, because I think that it closes a circle with regards to the reports. The reports allows you to pull out a lot of data across you entire application, and the Go To Session feature allows you to connect the interesting pieces of the data back to originating session, giving you where and why this statement was issued.&lt;/p&gt;</description><link>http://ayende.com/blog/4632/profiler-new-features-sept-edition?key=ea32c80b-9b96-4fd8-8d41-6c8131c017fa</link><guid>http://ayende.com/blog/4632/profiler-new-features-sept-edition?key=ea32c80b-9b96-4fd8-8d41-6c8131c017fa</guid><pubDate>Fri, 17 Sep 2010 11:00:00 GMT</pubDate></item><item><title>Estimates sucks, especially when I pay for them</title><description>&lt;p&gt;I recently got an estimate for a feature that I wanted to add to &lt;a href="http://nhprof.com"&gt;NH Prof&lt;/a&gt;. It was for two separate features, actually, but they were closely related. &lt;/p&gt;  &lt;p&gt;That estimate was for 32 hours. &lt;/p&gt;  &lt;p&gt;And it caused me a great deal of indigestion. The problem was, quite simply, that even granting that there is the usual padding of estimates (which I expect), that timing estimate was off, &lt;em&gt;way&lt;/em&gt; off. I knew what would be required for this feature, and it shouldn’t be anywhere &lt;em&gt;near&lt;/em&gt; complicated enough to require 4 days of full time work. In fact, I estimated that it would take me a maximum of 6 hours and a probable of 3 hours to get it done.&lt;/p&gt;  &lt;p&gt;Now, to be fair, I &lt;em&gt;know&lt;/em&gt; the codebase (well, actually that isn’t true, a lot of the code for NH Prof was written by &lt;a href="http://devlicio.us/blogs/rob_eisenberg/"&gt;Rob&lt;/a&gt; &amp;amp; &lt;a href="http://devlicious.com/blogs/christopher_bennage/"&gt;Christopher&lt;/a&gt;, and after a few days of working with them, I stopped looking at the code, there wasn’t any need to do so). And I am well aware that most people consider me to be an above average developer. &lt;/p&gt;  &lt;p&gt;I wouldn’t have batted an eye for an estimate of 8 – 14 hours, probably. Part of the reason that I have other people working on the code base is that even though I can do certain things faster, I can only do so many things, after all.&lt;/p&gt;  &lt;p&gt;But a time estimate that was 5 – 10 times as large as what I estimated was too annoying. I decided that &lt;em&gt;this&lt;/em&gt; feature I am going to do on my own. And I decided that I wanted to do this on the clock.&lt;/p&gt;  &lt;p&gt;The result is here:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/EstimatessucksespeciallywhenIpayforthem_117BA/image_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/EstimatessucksespeciallywhenIpayforthem_117BA/image_thumb.png" width="471" height="193" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;This is actually total time over three separate sittings, but the timing is close enough to what I though it would be.&lt;/p&gt;  &lt;p&gt;This includes &lt;em&gt;everything&lt;/em&gt;, implementing the feature, unit testing it, wiring it up in the UI, etc.&lt;/p&gt;  &lt;p&gt;The only thing remaining is to add the UI works for the other profilers (&lt;a href="http://efprof.com"&gt;Entity Framework&lt;/a&gt;, &lt;a href="http://l2sprof.com"&gt;Linq to SQL&lt;/a&gt;, &lt;a href="http://hibernateprofiler.com"&gt;Hibernate&lt;/a&gt; and the upcoming LLBLGen Profiler) . Doing this now…&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/EstimatessucksespeciallywhenIpayforthem_117BA/image_4.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/EstimatessucksespeciallywhenIpayforthem_117BA/image_thumb_1.png" width="438" height="191" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;And we are done.&lt;/p&gt;  &lt;p&gt;I have more features that I want to implement, but in general, if I pushed those changes out, they would be a new release that customers can use immediately.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Nitpicker corner:&lt;/b&gt; No, I am not being ripped off. And no, the people making the estimates aren't incompetent. To be perfectly honest, looking at the work that they did do and the time marked against it, they are good, and they deliver in a reasonable time frame. What I think is going on is that their estimates are &lt;i&gt;highly&lt;/i&gt; conservative, because they don't want to get into a bind with "oh, we run into a problem with XYZ and overrun the time for the feature by 150%".&lt;/p&gt;
&lt;p&gt;That also lead to a different problem, when you pay by the hour, you really want to have estimates that are more or less reasonably tied to your payments. But estimating with hours has too much granularity to be really effective (a single bug can easily consume hours, totally throwing off estimation, and it doesn't even have to be a complex one.)&lt;/p&gt;</description><link>http://ayende.com/blog/4627/estimates-sucks-especially-when-i-pay-for-them?key=c6294703-532a-4dee-b64c-ebef996a595f</link><guid>http://ayende.com/blog/4627/estimates-sucks-especially-when-i-pay-for-them?key=c6294703-532a-4dee-b64c-ebef996a595f</guid><pubDate>Sun, 12 Sep 2010 10:00:00 GMT</pubDate></item><item><title>The Profiler New Features: Starring &amp; Renaming</title><description>&lt;p&gt;An interesting thing happened recently, when I started to build the profiler, a lot of the features were what I call Core Features. Those were the things that without which, we wouldn’t &lt;em&gt;have&lt;/em&gt; a product. Things like detecting SQL, merging it into sessions, providing reports, etc. What I find myself doing recently with the profiler is not so much building Core Features, but building UX features. In other words, now that we have this in place, let us see how we can make better use of this. &lt;/p&gt;  &lt;p&gt;Case in point, the new features that were just released in build 713. They aren’t big, but they are there to improve how people are commonly using the products.&lt;/p&gt;  &lt;p&gt;Renaming a session:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/TheProfilerNewFeaturesStarringRenaming_A482/image_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/TheProfilerNewFeaturesStarringRenaming_A482/image_thumb.png" width="357" height="237" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;This is primarily useful if you are in a long profiling session and you want to mark a specific session with some notation:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/TheProfilerNewFeaturesStarringRenaming_A482/image_4.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/TheProfilerNewFeaturesStarringRenaming_A482/image_thumb_1.png" width="460" height="172" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p /&gt;  &lt;p&gt;Small feature, and individually not very useful. But you might have noticed that the sessions are marked with stars around them. They weren’t there is previous builds, so what are they?&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/TheProfilerNewFeaturesStarringRenaming_A482/image_6.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/TheProfilerNewFeaturesStarringRenaming_A482/image_thumb_2.png" width="369" height="174" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;They are a way to tell the profiler that you really like those sessions :-)&lt;/p&gt;  &lt;p&gt;More to the point, such sessions will not be removed when you clear the current state. That lets you keep around the previous state of the application as a base line while you work to improve it. Beside, it makes it much easier to locate them visually.&lt;/p&gt;  &lt;p&gt;And finally, as a quicker way to do that, you can just ask the profiler to clear all but the selected features.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/TheProfilerNewFeaturesStarringRenaming_A482/image_8.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/TheProfilerNewFeaturesStarringRenaming_A482/image_thumb_3.png" width="396" height="241" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Not big features, but nice ones, I think.&lt;/p&gt;</description><link>http://ayende.com/blog/4608/the-profiler-new-features-starring-renaming?key=18646a6f-4599-4c3a-8765-575af7ce061b</link><guid>http://ayende.com/blog/4608/the-profiler-new-features-starring-renaming?key=18646a6f-4599-4c3a-8765-575af7ce061b</guid><pubDate>Thu, 26 Aug 2010 08:13:00 GMT</pubDate></item><item><title>NH Prof &amp; usage data</title><description>&lt;p&gt;There seems to be some suspicion about the &lt;a href="http://ayende.com/Blog/archive/2010/08/17/profiler-usage-analysis.aspx"&gt;usage data&lt;/a&gt; from NH Prof that I published recently.&lt;/p&gt;  &lt;p&gt;I would like to apologize for responding late to the comments, I know that there are some people who believe that I have installed a 3G chip directly to my head, but I actually was busy in the real world and didn’t look at my email until recently. The blog runs on auto pilot just so I’ll be able to do that, but sometimes it does give the wrong impression.&lt;/p&gt;  &lt;p&gt;So, what &lt;em&gt;does&lt;/em&gt; NH Prof “phone home” about?&lt;/p&gt;  &lt;p&gt;Well, the data is actually divided into two distinct pieces. Most of the data (numbers, usages, geographic location, etc) actually comes from looking at the server logs for the update check. &lt;/p&gt;  &lt;p&gt;Another piece of data that the profiler reports is feature usage. There are about 20 – 30 individual features that are being tracked for usage. What does it means, tracking a feature?&lt;/p&gt;  &lt;p&gt;Well, here are three examples that shows what gets reported:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/NHProfusagedata_10739/image_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/NHProfusagedata_10739/image_thumb.png" width="673" height="54" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/NHProfusagedata_10739/image_4.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/NHProfusagedata_10739/image_thumb_1.png" width="398" height="68" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/NHProfusagedata_10739/image_8.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/NHProfusagedata_10739/image_thumb_3.png" width="525" height="77" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;There is no way to correlate this data to an individual user, nor is there a way to track the behavior of a single user. &lt;/p&gt;  &lt;p&gt;I use this data mainly in order to see what features are being used most often (therefore deserving the most attention, optimizations, etc).&lt;/p&gt;  &lt;p&gt;Those are mentioned in the &lt;a href="http://nhprof.com/Learn/Usage/FireWall"&gt;product documentation&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;To summarize:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;I am not stealing your connection strings.&lt;/li&gt;    &lt;li&gt;I don’t gather any personally identifying data (and I am at somewhat at a loss to understand what I would &lt;em&gt;do&lt;/em&gt; with it even if I did).&lt;/li&gt;    &lt;li&gt;There is never any data about what you are profiling being sent anywhere.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I hope this clear things out.&lt;/p&gt;</description><link>http://ayende.com/blog/4597/nh-prof-usage-data?key=89f084ea-16ba-4b5f-89d7-265d92ec548e</link><guid>http://ayende.com/blog/4597/nh-prof-usage-data?key=89f084ea-16ba-4b5f-89d7-265d92ec548e</guid><pubDate>Thu, 19 Aug 2010 15:25:00 GMT</pubDate></item><item><title>NHProf new feature: Expensive queries report</title><description>&lt;p&gt;It has been a while since we had a new major feature for the profiler, but here it is:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/NHProfnewfeatureExpensivequeriesreport_AAEA/image_4.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/NHProfnewfeatureExpensivequeriesreport_AAEA/image_thumb_1.png" width="683" height="189" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p /&gt;  &lt;p&gt;The expensive queries report will look at all your queries and surface the most expensive ones across all the sessions. This can give you a good indication on where you need to optimize things.&lt;/p&gt;  &lt;p&gt;Naturally, this feature is available across all the profiler profiles (&lt;a href="http://nhprof.com"&gt;NHibernate Profiler&lt;/a&gt;, &lt;a href="http://efprof.com"&gt;Entity Framework Profiler&lt;/a&gt;, &lt;a href="http://l2sprof.com"&gt;Linq to SQL Profiler&lt;/a&gt; and &lt;a href="http://hibernateprofiler.com"&gt;Hibernate Profiler&lt;/a&gt;).&lt;/p&gt;</description><link>http://ayende.com/blog/4554/nhprof-new-feature-expensive-queries-report?key=c9025f2c-f0f8-4915-99a3-2be02e107b0e</link><guid>http://ayende.com/blog/4554/nhprof-new-feature-expensive-queries-report?key=c9025f2c-f0f8-4915-99a3-2be02e107b0e</guid><pubDate>Fri, 16 Jul 2010 09:09:51 GMT</pubDate></item><item><title>Profiler subscriptions are now open for all profilers</title><description>&lt;p&gt;After trying it out on &lt;a href="http://nhprof.com"&gt;NH Prof&lt;/a&gt;, profiler subscriptions are now opened for all the profilers.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://l2sprof.com"&gt;Linq To SQL Profiler&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://efprof.com"&gt;Entity Framework Profiler&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://hibernateprofiler.com"&gt;Hibernate Profiler&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;A profiler subscription allows you to pay a small monthly free (~16$) and get the full profiler capabilities along with the assurance of no upgrade cost when the next major version comes out.&lt;/p&gt;  &lt;p&gt;In addition to the monthly subscription, I got requests for a yearly subscription. I am not sure that I quite follow the logic, but I am not going to make it harder for people to give me money, so that is available as well for all profilers.&lt;/p&gt;</description><link>http://ayende.com/blog/4473/profiler-subscriptions-are-now-open-for-all-profilers?key=bc3ec794-f15d-4433-8746-d4a856399261</link><guid>http://ayende.com/blog/4473/profiler-subscriptions-are-now-open-for-all-profilers?key=bc3ec794-f15d-4433-8746-d4a856399261</guid><pubDate>Mon, 26 Apr 2010 12:54:00 GMT</pubDate></item></channel></rss>
