<?xml version="1.0" encoding="UTF-8"?> <rss
version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
><channel><title>The Inquisitive Coder - Davy Brion&#039;s Blog &#187; Performance</title> <atom:link href="http://davybrion.com/blog/category/performance/feed/" rel="self" type="application/rss+xml" /><link>http://davybrion.com/blog</link> <description>inquisitive: adjective. given to inquiry, research, or asking questions; eager for knowledge; intellectually curious</description> <lastBuildDate>Sun, 29 Jan 2012 10:48:12 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3.1</generator> <item><title>(Ab)Using Conventions To Enforce Good Practices</title><link>http://davybrion.com/blog/2012/01/abusing-conventions-to-enforce-good-practices/</link> <comments>http://davybrion.com/blog/2012/01/abusing-conventions-to-enforce-good-practices/#comments</comments> <pubDate>Thu, 26 Jan 2012 19:15:29 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[NHibernate]]></category> <category><![CDATA[Performance]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=3886</guid> <description><![CDATA[I always tell people to explicitly specify the lengths of their string properties in their NHibernate mappings for performance reasons. If you don't specify them, the ADO.NET parameter lengths of those strings will always be set to the length of the actual string value that's been assigned to the parameter. This is a problem for [...]]]></description> <content:encoded><![CDATA[<p>I always tell people to explicitly specify the lengths of their string properties in their NHibernate mappings for performance reasons. If you don't specify them, the ADO.NET parameter lengths of those strings will always be set to the length of the actual string value that's been assigned to the parameter. This is a problem for SQL Server, because it can't cache those statements as efficiently as it would if the parameter lengths were always the same for a given statement. Simply put, if you don't specify the lengths, SQL Server's statement cache gets polluted with a bunch of statements that are often the same, but they're considered to be different simply because of the lengths of those string parameters. And this can really hurt the performance of your application.</p><p>Of course, not everyone remembers to set those lengths, so I thought it'd be great if I could force people to do this. With a little creative use of Fluent NHibernate's conventions, it's quite easy to enforce this:</p><div><pre class="brush: csharp; title: ; notranslate">
public class StringsMustHaveLengthConvention: IPropertyConvention, IPropertyConventionAcceptance
{
    public void Apply(IPropertyInstance instance)
    {
        var msg = string.Format(&quot;The string property '{0}' of type '{1}' does not have a length value specified, &quot; +
            &quot;which is required for performance reasons. Add something like this to your mapping override:\r\n&quot; + 
            &quot;\tmapping.Map(e =&gt; e.{0}).Length(50); // with an appropriate length for this property&quot;,
            instance.Property.Name, instance.EntityType.Name);

        throw new MappingException(msg);
    }

    public void Accept(IAcceptanceCriteria&lt;IPropertyInspector&gt; criteria)
    {
        criteria.Expect(x =&gt; x.Type == typeof(string)).Expect(x =&gt; x.Length == 0);
    }
}
</pre></div><p>With that convention in place, you won't even be able to run your code until you've specified the string lengths <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2012%2F01%2Fabusing-conventions-to-enforce-good-practices%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2012/01/abusing-conventions-to-enforce-good-practices/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2012/01/abusing-conventions-to-enforce-good-practices/"  data-text="(Ab)Using Conventions To Enforce Good Practices" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2012/01/abusing-conventions-to-enforce-good-practices/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2012/01/abusing-conventions-to-enforce-good-practices/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2012/01/abusing-conventions-to-enforce-good-practices/feed/</wfw:commentRss> <slash:comments>15</slash:comments> </item> <item><title>Displaying Feed Items On A Web Page: My Solution</title><link>http://davybrion.com/blog/2011/12/displaying-feed-items-on-a-web-page-my-solution/</link> <comments>http://davybrion.com/blog/2011/12/displaying-feed-items-on-a-web-page-my-solution/#comments</comments> <pubDate>Tue, 20 Dec 2011 07:00:55 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[express.js]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[node.js]]></category> <category><![CDATA[Performance]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=3830</guid> <description><![CDATA[A couple of days ago I asked you how you'd implement showing links from an RSS feed on a web page (in this case: my new company web site). These are my requirements for this: It needs to be fast The fewer requests that are impacted by retrieving the feed data, the better If I [...]]]></description> <content:encoded><![CDATA[<p>A couple of days ago I <a
href="http://davybrion.com/blog/2011/12/challenge-displaying-feed-items-on-a-web-page/">asked you</a> how you'd implement showing links from an RSS feed on a web page (in this case: my new company web site). These are my requirements for this:</p><ul><li>It needs to be <strong>fast</strong></li><li>The fewer requests that are impacted by retrieving the feed data, the better</li><li>If I publish a post, the links on the company website should contain the new link within 30 minutes</li><li>The simpler the solution, the better</li></ul><p>I came up with a very simple solution, which satisfies these requirements better than any other solution I could think of, or heard of from other people. It is extremely fast, doesn't delay any requests, and doesn't require me to deploy anything but the company website. I'm building the site with <a
href="http://expressjs.com/">Express</a> on <a
href="http://nodejs.org/">Node.js</a>, which means I can take full advantage of the asynchronous nature of Node.js to implement this.</p><p>Let's go over the code... in the script that starts the express server, I have the following code:</p><div><pre class="brush: jscript; title: ; notranslate">
var express = require('express'),
    app = module.exports = express.createServer(),
    NodePie = require('nodepie'),
    request = require('request'),
    recentFeedItems = null;

app.dynamicHelpers({
    getRecentFeedItems: function() {
        return recentFeedItems;
    }
});

// ... some extra configuration of Express that isn't relevant to this post

var processFeed = function(callback) {
    request('http://feeds.feedburner.com/davybrion', function(err, response, body) {
        if (!err &amp;&amp; response.statusCode == 200) {
            var feed = new NodePie(body);
            feed.init();
            recentFeedItems = feed.getItems(0, 5);
            if (callback) callback();
        };
    }); 
};

setInterval(processFeed, 1800000); // process feed items every 30 minutes

processFeed(function() {
    app.listen(3000);
    console.log('Express started on port 3000');    
});
</pre></div><p>I'll discuss the code in just a moment, but first I want to show the view code that renders the links:</p><div><pre class="brush: xml; title: ; notranslate">
&lt;ul&gt;
&lt;% getRecentFeedItems.forEach(function(item) { %&gt;
    &lt;li&gt;&lt;time class=&quot;date&quot;&gt;&lt;%= item.getDate().getDate() + '/' + (item.getDate().getMonth() + 1) %&gt;&lt;/time&gt;&lt;a href=&quot;&lt;%= item.getPermalink() %&gt;&quot;&gt;&lt;%= item.getTitle() %&gt;&lt;/a&gt;&lt;/li&gt;
&lt;% }); %&gt;
&lt;/ul&gt;
</pre></div><p>And that's all. This is the solution in its entirety!</p><p>If you're new to Node, this code probably requires some explanation. Let's start with this part:</p><div><pre class="brush: jscript; title: ; notranslate">
app.dynamicHelpers({
    getRecentFeedItems: function() {
        return recentFeedItems;
    }
});
</pre></div><p>Here I'm adding a dynamic helper to the Express application. It basically means that my views have access to the getRecentFeedItems function, which returns the value of the recentFeedItems variable. It's important to know that the getRecentFeedItems function creates a closure on the recentFeedItems variable created above it. That means that if the value of the recentFeedItems variable changes at any point in time, the getRecentFeedItems function will return that new value.</p><div><pre class="brush: jscript; title: ; notranslate">
var processFeed = function(callback) {
    request('http://feeds.feedburner.com/davybrion', function(err, response, body) {
        if (!err &amp;&amp; response.statusCode == 200) {
            var feed = new NodePie(body);
            feed.init();
            recentFeedItems = feed.getItems(0, 5);
            if (callback) callback();
        };
    }); 
};
</pre></div><p>This just creates a function that we can use later on. It retrieves the feed asynchronously, and when the result is retrieved, we parse the feed using the NodePie library and we get the 5 most recent items which we store in the recentFeedItems variable. Again, this creates a closure on the recentFeedItems variable which means that every time we assign a value to this variable, any subsequent call to the getRecentFeedItems function will return the value we just assigned to it because both functions point to the same memory thanks to the magic of closures. Finally, if a callback is provided as a parameter, the callback will be invoked.</p><div><pre class="brush: jscript; title: ; notranslate">
setInterval(processFeed, 1800000); // process feed items every 30 minutes

processFeed(function() {
    app.listen(3000);
    console.log('Express started on port 3000');    
});
</pre></div><p>The call to setInterval makes sure that the processFeed function is called every 30 minutes. After that, we call the processFeed function manually, and we pass in a callback where we start the Express server. This guarantees that the feed items will be in memory before the server starts processing requests.</p><p>What makes this solution so great is that we take full advantage of some of Node's benefits. Whenever we retrieve the RSS feed, Node.JS will retrieve that data asynchronously. As soon as it has fired the request to get the RSS feed, it just goes to the next event in its eventloop so no request is kept waiting while we wait for the data to be downloaded. Until the data from the RSS feed is returned, each request will just use the items that are stored in the recentFeedItems variable. Once the data has been returned, our callback is executed which overwrites the value of the recentFeedItems variable. We don't need to do any locking here because the Node.JS eventloop is single-threaded: while our callback is running, no other code that has access to the recentFeedItems variable can be executed anyway. And the actual parsing of the RSS feed is done by NodePie, which uses <a
href="http://expat.sourceforge.net/">expat</a> behind the scenes, which is supposedly the fastest C XML parser available.</p><p>Looking back on my initial requirements, I think this solution matches very well.</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2011%2F12%2Fdisplaying-feed-items-on-a-web-page-my-solution%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2011/12/displaying-feed-items-on-a-web-page-my-solution/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2011/12/displaying-feed-items-on-a-web-page-my-solution/"  data-text="Displaying Feed Items On A Web Page: My Solution" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2011/12/displaying-feed-items-on-a-web-page-my-solution/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2011/12/displaying-feed-items-on-a-web-page-my-solution/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2011/12/displaying-feed-items-on-a-web-page-my-solution/feed/</wfw:commentRss> <slash:comments>7</slash:comments> </item> <item><title>Challenge: Displaying Feed Items On A Web Page</title><link>http://davybrion.com/blog/2011/12/challenge-displaying-feed-items-on-a-web-page/</link> <comments>http://davybrion.com/blog/2011/12/challenge-displaying-feed-items-on-a-web-page/#comments</comments> <pubDate>Sat, 17 Dec 2011 15:17:41 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Performance]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=3822</guid> <description><![CDATA[I'm finally getting around to implementing the website for my company, and there's one small part of it that's quite interesting from an implementation point of view. The website will have a footer on each page which displays links to my 5 most recent blog posts: Of course, I don't want to update those links [...]]]></description> <content:encoded><![CDATA[<p>I'm finally getting around to implementing the website for my company, and there's one small part of it that's quite interesting from an implementation point of view. The website will have a footer on each page which displays links to my 5 most recent blog posts:</p><p><a
href="http://davybrion.com/blog/wp-content/uploads/2011/12/feed_items.png" rel="prettyPhoto[3822]"><img
src="http://davybrion.com/blog/wp-content/uploads/2011/12/feed_items.png" alt="" title="feed_items" width="683" height="402" class="aligncenter size-full wp-image-3823" /></a></p><p>Of course, I don't want to update those links manually whenever I publish a new post, so they need to be retrieved from my blog's RSS feed, which is published by Feedburner. I was hoping to be able to retrieve only the metadata from the posts (date, title and URL is all I need) because my feed always contains the last 20 posts and its total size is usually above 100KB. I haven't found a way to do that, so getting the information I need has to be retrieved through the full feed. Sure, 100KB isn't much but keep in mind that you need to retrieve it and parse it and that I absolutely want to minimize the time each request takes and that I'd rather not see any visual delays on the page either.</p><p>I'm interested in hearing how you would implement this. You have total freedom to pick the technologies you'd like to use and no limits on how you'd use them. My only requirements are these:</p><ul><li>It needs to be <strong>fast</strong></li><li>The fewer requests that are impacted by retrieving the feed data, the better</li><li>If I publish a post, the links on the company website should contain the new link within 30 minutes</li><li>The simpler the solution, the better</li></ul><p>My solution can be found <a
href="http://davybrion.com/blog/2011/12/displaying-feed-items-on-a-web-page-my-solution/">here</a>.</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2011%2F12%2Fchallenge-displaying-feed-items-on-a-web-page%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2011/12/challenge-displaying-feed-items-on-a-web-page/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2011/12/challenge-displaying-feed-items-on-a-web-page/"  data-text="Challenge: Displaying Feed Items On A Web Page" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2011/12/challenge-displaying-feed-items-on-a-web-page/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2011/12/challenge-displaying-feed-items-on-a-web-page/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2011/12/challenge-displaying-feed-items-on-a-web-page/feed/</wfw:commentRss> <slash:comments>16</slash:comments> </item> <item><title>Repeated Failed Log-Ins: What&#8217;s Your Strategy?</title><link>http://davybrion.com/blog/2011/09/repeated-failed-log-ins-whats-your-strategy/</link> <comments>http://davybrion.com/blog/2011/09/repeated-failed-log-ins-whats-your-strategy/#comments</comments> <pubDate>Sat, 10 Sep 2011 17:38:45 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[ASP.NET MVC]]></category> <category><![CDATA[express.js]]></category> <category><![CDATA[node.js]]></category> <category><![CDATA[Patterns]]></category> <category><![CDATA[Performance]]></category> <category><![CDATA[security]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=3705</guid> <description><![CDATA[I've only been using the server that's hosting this blog for a week or two, so I'm still keeping a close eye on it. I check usage graphs (cpu, disk I/O and network) a couple of times a day to verify whether things are still running smoothly. This morning, I saw a noticeable increase in [...]]]></description> <content:encoded><![CDATA[<p>I've only been using the server that's hosting this blog for a week or two, so I'm still keeping a close eye on it. I check usage graphs (cpu, disk I/O and network) a couple of times a day to verify whether things are still running smoothly. This morning, I saw a noticeable increase in CPU usage and network activity that lasted for about 11 hours. I logged into the machine, checked some logs and found out that someone had conducted an 11 hour lasting brute-force SSH attack. It doesn't make much sense to try that on my server since my SSH daemon doesn't allow password authentication, and indeed there was no successful login during the attack so no harm done, right?</p><p>Even if such an attack is not successful, it does consume resources on the targeted server(s). And wasteful, unnecessary resource usage has always been a bit of a pet peeve of mine so I wanted to prevent this from happening again. For this particular scenario, it's pretty easy. I installed DenyHosts which routinely checks for repeated (configured at 5) failed log-in attempts, and adds the offending IP addresses to /etc/hosts.deny so every other attempted SSH connection from those IP addresses will be denied immediately. Each offending IP address will be purged from /etc/hosts.deny after 1 week. Then I added a firewall rule that prevents you from connecting through SSH more than 5 times in 60 seconds. If you go over 5 connections, it just starts dropping packets, and by the time the drop behavior for your IP address expires, you'll have been added to /etc/hosts.deny already. As I said, pretty easy in this scenario because there are great tools I can rely on.</p><p>But what would you do if you had to implement a strategy to deal with this yourself? The most interesting approach I've heard of is to add an incremental delay on each failed authentication attempt. If the user fails the authentication check, delay the response with 1 second. If the user fails the second time, delay the response with 2 seconds. Third failure means a delay of 3 seconds, and so on. This pretty much makes a brute-force or dictionary attack impossible. The key is though, that you can't block any of your request-handling threads because then you open yourself up to an easy DoS attack.</p><p>Implementing this for a web application built on Node.js and Express.js is incredibly easy (there's an ASP.NET MVC example later in this post btw). I took the <a
href="https://github.com/visionmedia/express/blob/master/examples/auth/app.js">authorization example</a> of Express.js and made just a few minor changes. First of all, I added the delayAuthenticationResponse function:</p><div><pre class="brush: jscript; title: ; notranslate">
function delayAuthenticationResponse(session, callback) {
  if (!session.attempts) {
    session.attempts = 1; 
  } else {
    session.attempts++;
  }

  setTimeout(callback, session.attempts * 1000);
}
</pre></div><p>This is the most important part of the implementation. Every time we get here, we increment the number of attempts for this user by one and store the number in the user's session. Side note: this is one of the few things you'd actually want to use a session for: <strong>session-related data</strong>. Then we schedule the callback to be executed after the number of attempts * 1000 milliseconds have passed. The important part to remember here is that Node's event loop is not blocked by this, so our ability to handle other requests is <em>not impaired in any way</em>. The only one who suffers here is the attacker. Note that in a real world implementation, you'd probably only want to start increasing the delay after 5 attempts or so, in order to not piss off users who're just having problems remembering their password.</p><p>Then I changed the authenticate function so that it receives a session as the first parameter, and uses our delayAuthenticationResponse function whenever something goes wrong:</p><div><pre class="brush: jscript; title: ; notranslate">
function authenticate(session, name, pass, callback) {
  var user = users[name];

  if (!user) {
    return delayAuthenticationResponse(session, function() {
      callback(new Error('cannot find user'));
    });
  }

  if (user.pass == hash(pass, user.salt)) {
    delete session.attempts;
    return callback(null, user);
  }

  delayAuthenticationResponse(session, function() {
    callback(new Error('invalid password'));
  });
}
</pre></div><p>After that, it's just a matter of changing the function that is assigned to the login route:</p><div><pre class="brush: jscript; title: ; notranslate">
app.post('/login', function(req, res){
  authenticate(req.session, req.body.username, req.body.password, function(err, user){
    if (user) {
      req.session.regenerate(function(){
        req.session.user = user;
        res.redirect('back');
      });
    } else {
      req.session.error = 'Authentication failed, please check your '
        + ' username and password.'
        + ' (use &quot;tj&quot; and &quot;foobar&quot;)';
      res.redirect('back');
    }
  });
});
</pre></div><p>And there we go. This effectively makes it impossible to brute-force your way into this web application, and I'm sure you can agree it was rather easy to do so. Of course, this is only because Node.js is inherently non-blocking. In an environment where non-blocking is the exception rather than the rule, you have to keep a few more things into account when trying to implement this strategy.</p><p>For instance, ASP.NET MVC is a typical blocking web framework. There's a certain number of threads that are waiting to handle requests, and once they receive a request, they process that request in its entirety. That means that if your code has to wait on something, the request handling thread is blocked and can't handle any other requests. So obviously, if you'd like to implement this strategy for dealing with repeated failed log-ins, you really want to avoid doing something like this:</p><div><pre class="brush: csharp; title: ; notranslate">
        [HttpPost]
        public ActionResult LogOn(LogOnModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                if (CredentialsAreValid(model.UserName, model.Password))
                {
                    FormsService.SignIn(model.UserName, model.RememberMe);
                    if (Url.IsLocalUrl(returnUrl))
                    {
                        return Redirect(returnUrl);
                    }
                    
                    return RedirectToAction(&quot;Index&quot;, &quot;Home&quot;);
                }

                Session[&quot;attempts&quot;] = Session[&quot;attempts&quot;] == null ? 1 : (int)Session[&quot;attempts&quot;] + 1;
                Thread.Sleep((int)Session[&quot;attempts&quot;] * 1000);
                ModelState.AddModelError(&quot;&quot;, &quot;The user name or password provided is incorrect.&quot;);
            }

            return View(model);
        }
</pre></div><p>(note: this is a slightly modified LogOn method from the default AccountController when selecting 'internet application' in the MVC project wizard)</p><p>While this looks like it does the same as the Node/Express example, it certainly doesn't. The experience for the attacker is the same, because each failed attempt causes the response time to be increased with an extra second. But on your server, the thread handling the request is blocking the whole time and is thus incapable of handling extra requests while you're making the attacker wait.</p><p>Luckily, you can use ASP.NET MVC's asynchronous controllers to provide an asynchronous implementation of an action without blocking the request handling thread:</p><div><pre class="brush: csharp; title: ; notranslate">
        [HttpPost]
        public void LogOnAsync(LogOnModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                if (CredentialsAreValid(model.UserName, model.Password))
                {
                    FormsService.SignIn(model.UserName, model.RememberMe);
                    AsyncManager.Parameters[&quot;returnUrl&quot;] = returnUrl;
                }
                else
                {
                    Session[&quot;attempts&quot;] = Session[&quot;attempts&quot;] == null ? 1 : (int)Session[&quot;attempts&quot;] + 1;
                    var timeout = (int)Session[&quot;attempts&quot;] * 1000;
                    AsyncManager.OutstandingOperations.Increment();

                    var timer = new System.Timers.Timer(timeout) { AutoReset = false };
                    timer.Elapsed += (sender, e) =&gt;
                    {
                        ModelState.AddModelError(&quot;&quot;, &quot;The user name or password provided is incorrect.&quot;);
                        AsyncManager.Parameters[&quot;model&quot;] = model;
                        timer.Dispose();
                        AsyncManager.OutstandingOperations.Decrement();
                    };
                    timer.Start();
                }
            }
        }

        public ActionResult LogOnCompleted(LogOnModel model, string returnUrl)
        {
            if (!string.IsNullOrEmpty(returnUrl) &amp;&amp; Url.IsLocalUrl(returnUrl))
            {
                return Redirect(returnUrl);
            }

            if (model == null)
            {
                return RedirectToAction(&quot;Index&quot;, &quot;Home&quot;);
            }

            return View(model);
        }
</pre></div><p>Your controller has to inherit from AsyncController instead of Controller to make this work. Of course, it's much more complicated and requires more ceremony compared to the Node/Express approach, but then again, ASP.NET MVC isn't optimized for this kind of usage whereas Node/Express definitely is.</p><p>Either way, no matter what web framework you use, if you can add an incremental delay to the response of each failed log-in attempt without blocking a request-handling-thread, you've added a very effective and low-cost protection against brute-force and dictionary attacks.</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2011%2F09%2Frepeated-failed-log-ins-whats-your-strategy%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2011/09/repeated-failed-log-ins-whats-your-strategy/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2011/09/repeated-failed-log-ins-whats-your-strategy/"  data-text="Repeated Failed Log-Ins: What&#8217;s Your Strategy?" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2011/09/repeated-failed-log-ins-whats-your-strategy/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2011/09/repeated-failed-log-ins-whats-your-strategy/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2011/09/repeated-failed-log-ins-whats-your-strategy/feed/</wfw:commentRss> <slash:comments>11</slash:comments> </item> <item><title>Virtual Method Performance Penalty, Revisited</title><link>http://davybrion.com/blog/2010/12/virtual-method-performance-penalty-revisited/</link> <comments>http://davybrion.com/blog/2010/12/virtual-method-performance-penalty-revisited/#comments</comments> <pubDate>Fri, 17 Dec 2010 15:13:05 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[C#]]></category> <category><![CDATA[Performance]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=2955</guid> <description><![CDATA[I wrote a post about a year ago which discussed a test of the performance difference between calling virtual methods and non-virtual methods. This morning, someone added the following comment to that post: if you have 100 subclasses of class A, and they all override a method a, it will take a lot longer for [...]]]></description> <content:encoded><![CDATA[<p>I wrote a <a
href="http://davybrion.com/blog/2010/01/virtual-method-performance-penalty">post</a> about a year ago which discussed a test of the performance difference between calling virtual methods and non-virtual methods. This morning, someone added the following <a
href="http://davybrion.com/blog/2010/01/virtual-method-performance-penalty/#comment-83122">comment</a> to that post:</p><blockquote>if you have 100 subclasses of class A, and they all override a method a, it will take a lot longer for it to figure out which version of a to call. Think of it as a switch statement with one case label verses a switch statement with 100 case labels. Since you’re just testing it with one method it’s not surprising that the cost is negligible.</blockquote><p>My Bullshit-detector started beeping while reading that, so i just had to see if the number of subclasses indeed had an impact.  I didn't go all the way up to 100 subclasses, but i went with 15.  If there is indeed a performance penalty that grows with the number of subclasses in play, then surely i'd have to see <em>some difference</em> when using 15 subclasses over just 1, right?</p><p>In the original test, i had the following 2 classes:</p><div><pre class="brush: csharp; title: ; notranslate">
    public class MyClass
    {
        public long someLong;

        public void IncreaseLong()
        {
            someLong++;
        }

        public virtual void VirtualIncreaseLong()
        {
            someLong++;
        }
    }

    public class MyDerivedClass : MyClass
    {
        public override void VirtualIncreaseLong()
        {
            someLong += 2;
        }
    }
</pre></div><p>Now, i wasn't quite sure whether the commenter meant having a bunch of classes that inherited directly from MyClass, or having a set of inheriting classes in a deep inheritance tree.  Just to be sure, i tested both cases.</p><p>In the first case, i have classes like MyDerivedClass1, MyDerivedClass2, ... , MyDerivedClass15 that all inherit directly from MyClass.  In the second case, MyDerivedClass1 inherits from MyClass, MyDerivedClass2 inherits from MyDerivedClass1, ... , and MyDerivedClass15 inherits from MyDerivedClass14.</p><p>The code of the test is still largely the same as it was in the previous post, with just some minor modifications to make sure that more of the code to be executed has been JIT'ed prior to the actual test-run:</p><div><pre class="brush: csharp; title: ; notranslate">
    class Program
    {
        const int iterations = 1000000000;

        static void Main(string[] args)
        {
            var myObject = new MyClass();
            var myDerivedObject = new MyDerivedClass15();

            // we do this so there's no first-time performance cost while timing
            EnsureThatEverythingHasBeenJitted(myObject);
            EnsureThatEverythingHasBeenJitted(myDerivedObject);

            TestNormalIncreaseMethod(myObject, iterations);
            TestVirtualIncreaseMethod(myObject, iterations);

            TestNormalIncreaseMethod(myDerivedObject, iterations);
            TestVirtualIncreaseMethod(myDerivedObject, iterations);

            Console.ReadLine();
        }

        static void EnsureThatEverythingHasBeenJitted(MyClass theObject)
        {
            theObject.IncreaseLong();
            theObject.VirtualIncreaseLong();
            TestNormalIncreaseMethod(theObject, 1, false);
            TestVirtualIncreaseMethod(theObject, 1, false);
        }

        static void TestNormalIncreaseMethod(MyClass theObject, int numberOfTimes, bool printToConsole = true)
        {
            if (printToConsole) Console.WriteLine(string.Format(&quot;calling the IncreaseLong method of type {0} {1} times&quot;, theObject.GetType().Name, numberOfTimes));
            
            var stopwatch = Stopwatch.StartNew();
            for (var i = 0; i &lt; numberOfTimes; i++)
            {
                theObject.IncreaseLong();
            }
            stopwatch.Stop();

            if (printToConsole) Console.WriteLine(&quot;Elapsed milliseconds: &quot; + stopwatch.ElapsedMilliseconds);
        }

        static void TestVirtualIncreaseMethod(MyClass theObject, int numberOfTimes, bool printToConsole = true)
        {
            if (printToConsole) Console.WriteLine(string.Format(&quot;calling the VirtualIncreaseLong method of type {0} {1} times&quot;, theObject.GetType().Name, numberOfTimes));

            var stopwatch = Stopwatch.StartNew();
            for (var i = 0; i &lt; numberOfTimes; i++)
            {
                theObject.VirtualIncreaseLong();
            }
            stopwatch.Stop();

            if (printToConsole) Console.WriteLine(&quot;Elapsed milliseconds: &quot; + stopwatch.ElapsedMilliseconds);
        }
    }
</pre></div><p>In the first test (multiple direct subclasses of MyClass) i got the following result:</p><p><a
href="http://davybrion.com/blog/wp-content/uploads/2010/12/fifteen_subclasses.png" rel="prettyPhoto[2955]"><img
src="http://davybrion.com/blog/wp-content/uploads/2010/12/fifteen_subclasses.png" alt="fifteen subclasses" title="fifteen_subclasses" width="642" height="171" class="aligncenter size-full wp-image-2956" /></a></p><p>(note: for this test, i used MyDerivedClass1 instead of MyDerivedClass15 as in the listed code)</p><p>In the second test (inheritance tree) i got the following result:</p><p><a
href="http://davybrion.com/blog/wp-content/uploads/2010/12/fifteen_nested_subclasses.png" rel="prettyPhoto[2955]"><img
src="http://davybrion.com/blog/wp-content/uploads/2010/12/fifteen_nested_subclasses.png" alt="fifteen nested subclasses" title="fifteen_nested_subclasses" width="651" height="173" class="aligncenter size-full wp-image-2957" /></a></p><p>As you can once again see, the difference is completely negligible. So here's what i propose: until someone actually shows a case where a clear-cut performance penalty is shown that is even slightly relevant to real-world usage, we should just drop the whole "virtual methods are expensive!"-thing.</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2010%2F12%2Fvirtual-method-performance-penalty-revisited%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2010/12/virtual-method-performance-penalty-revisited/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2010/12/virtual-method-performance-penalty-revisited/"  data-text="Virtual Method Performance Penalty, Revisited" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2010/12/virtual-method-performance-penalty-revisited/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2010/12/virtual-method-performance-penalty-revisited/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2010/12/virtual-method-performance-penalty-revisited/feed/</wfw:commentRss> <slash:comments>18</slash:comments> </item> <item><title>Performance Of NHibernate With Ruby Objects Compared To Traditional C# Objects</title><link>http://davybrion.com/blog/2010/10/performance-of-nhibernate-with-ruby-objects-compared-to-traditional-c-objects/</link> <comments>http://davybrion.com/blog/2010/10/performance-of-nhibernate-with-ruby-objects-compared-to-traditional-c-objects/#comments</comments> <pubDate>Tue, 19 Oct 2010 14:22:38 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[IronRuby]]></category> <category><![CDATA[NHibernate]]></category> <category><![CDATA[Performance]]></category> <category><![CDATA[Ruby]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=2817</guid> <description><![CDATA[I recently showed how you can use NHibernate to persist and query Ruby objects through IronRuby. We've continued the experiment (though we've already done some big optimizations in the code based on the first results of these tests) and we recently had to decide whether or not the performance difference between using NHibernate with regular [...]]]></description> <content:encoded><![CDATA[<p>I recently showed how you can <a
href="http://davybrion.com/blog/2010/09/using-nhibernate-to-persist-and-query-ruby-objects/">use NHibernate to persist and query Ruby objects</a> through IronRuby. We've continued the experiment (though we've already done some big optimizations in the code based on the first results of these tests) and we recently had to decide whether or not the performance difference between using NHibernate with regular static C# code and using it with dynamic Ruby objects was acceptable.  So we ran a set of tests, and compared all of the numbers.  Note that we don't claim that these benchmarks are scientifically correct in any way, but we do think they give us a good idea on what we can reasonably expect.  I want to share the results with you, and would appreciate any feedback you guys have on this... particularly on whether or not we missed something obvious in our tests or whether or not we should trust these numbers. After all, we're not professional benchmarkers so our approach might very well just suck <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>We have a scenario which consists of 15 'actions'.  For these actions, we use some tables from the Chinook database, basically just Artist/Album/Track/Genre/MediaType.  The actions are the following:</p><ol><li>Retrieve single track without joins, and access each non-reference property</li><li>Retrieve single track with joins, and access all properties, including references</li><li>Retrieve single track without joins, and access all properties, including references (triggers lazy-loading)</li><li>Create and persist object graph: one artist with two albums with 13 tracks each</li><li>Retrieve created artist from nr 4, add a new album with another 13 tracks, change the title of the first album from nr 4, and remove the second album from nr 4 including its tracks</li><li>Retrieve created artist from nr 4 and delete its entire graph</li><li>Create a single track</li><li>Retrieve single track from step 7 and update it</li><li>Retrieve single track from step 7 and update the name of one of its referenced properties</li><li>Retrieve single track from step 7 and change one of the reference properties so it references a different instance</li><li>Delete the track from step 7</li><li>Retrieve 100 tracks and access each non-reference property</li><li>Retrieve 200 tracks and access each non-reference property</li><li>Retrieve 100 tracks without joins and access all properties, including references (triggers lazy-loading)</li><li>Retrieve 100 tracks with joins and access all properties, including references</li></ol><p>Note: when i say we access reference properties to trigger lazy loading, i mean that we access a non-id property of the referenced property to make sure it indeed hits the database.</p><p>The scenario is ran 500 times with regular C# objects, and 500 times with Ruby objects.  We keep track of the average time of each action in the scenario, as well as the total duration of the scenario.  Also, keep in mind that we ran these tests on a local database.</p><p>The following graph shows the average duration of each action in milliseconds on the Y axis, and the number of the action on the X axis:</p><p><a
href="http://davybrion.com/blog/wp-content/uploads/2010/10/average_duration_of_each_action_in_millis.png" rel="prettyPhoto[2817]"><img
src="http://davybrion.com/blog/wp-content/uploads/2010/10/average_duration_of_each_action_in_millis.png" alt="" title="average_duration_of_each_action_in_millis" width="600" height="406" class="aligncenter size-medium wp-image-2818" /></a></p><p>(you can click on the graph to watch it in its full size)</p><p>Before i'll discuss these results, i'd also like to show the following graph which shows the average difference in milliseconds between the static and the dynamic execution of each action:</p><p><a
href="http://davybrion.com/blog/wp-content/uploads/2010/10/average_difference_in_millis_for_each_action.png" rel="prettyPhoto[2817]"><img
src="http://davybrion.com/blog/wp-content/uploads/2010/10/average_difference_in_millis_for_each_action.png" alt="" title="average_difference_in_millis_for_each_action" width="600" height="418" class="aligncenter size-medium wp-image-2821" /></a></p><p>Two actions immediately stand out: the last two which both deal with fetching a set of items and accessing all of their properties.  They're both about 6ms slower than their static counterparts, which is a performance penalty of 71% for action 14, and 87% for action 15.  That deals with a part of code that we can't really optimize any more.  Well, it probably is possible but we've already done a lot of work on that, and this is the best we can come up with so far.</p><p>Now, those 2 actions are things we avoid as much as possible in real code anyway, so maybe they aren't that big of an issue.  The other 2 actions where there is a noticable difference (though it actually means an increase in average execution time of 1.1ms using a local database) is the creation and persistance of an object graph (step 4), and the retrieval/modification/persistence of that same graph (step 5).  Most other actions don't have a noticeable difference, and in some cases the dynamic version is actually faster than the static one, no doubt because NHibernate has in some cases less work to do when using the Map EntityMode (which we rely on for the dynamic stuff) compared to the Poco EntityMode.</p><p>We also wanted to see whether the performance difference would get worse when spreading the workload evenly over a set of threads, or even a 'pool' of IronRuby engines.  I was pretty happy to see that it didn't really lead to a noticeable difference.</p><p>The following graph shows the average duration of the entire scenario in a couple of different situations:</p><p><a
href="http://davybrion.com/blog/wp-content/uploads/2010/10/average_scenario_duration.png" rel="prettyPhoto[2817]"><img
src="http://davybrion.com/blog/wp-content/uploads/2010/10/average_scenario_duration.png" alt="" title="average_scenario_duration" width="462" height="363" class="aligncenter size-full wp-image-2822" /></a></p><p>I do have to mention that the numbers shown in this graph aren't averages, but the result from running the scenario once in each situation.  We did however ran the scenarios in each situation more than once, and while we didn't list the averages, the numbers are representative of each testrun... we didn't see any really noticeable differences over multiple runs.  The percentage difference for each situation is shown in this graph:</p><p><a
href="http://davybrion.com/blog/wp-content/uploads/2010/10/average_scenario_duration_difference.png" rel="prettyPhoto[2817]"><img
src="http://davybrion.com/blog/wp-content/uploads/2010/10/average_scenario_duration_difference.png" alt="" title="average_scenario_duration_difference" width="395" height="365" class="aligncenter size-full wp-image-2825" /></a></p><p>As you can see, the performance penalty of the entire scenario in each situation varies between 15% and 26%.</p><p>Now, considering the fact that we prefer to avoid loading 'large' sets of data through NHibernate into entities (we prefer to use projections instead for that) we wanted to see what the difference would be for the entire duration of the scenario in each situation, without the final 4 actions.  Basically, just the typical CRUD scenarios:</p><p><a
href="http://davybrion.com/blog/wp-content/uploads/2010/10/average_scenario_duration_without_last_4_actions.png" rel="prettyPhoto[2817]"><img
src="http://davybrion.com/blog/wp-content/uploads/2010/10/average_scenario_duration_without_last_4_actions.png" alt="" title="average_scenario_duration_without_last_4_actions" width="468" height="365" class="aligncenter size-full wp-image-2826" /></a></p><p><a
href="http://davybrion.com/blog/wp-content/uploads/2010/10/average_scenario_duration_difference_without_last_4_actions.png" rel="prettyPhoto[2817]"><img
src="http://davybrion.com/blog/wp-content/uploads/2010/10/average_scenario_duration_difference_without_last_4_actions.png" alt="" title="average_scenario_duration_difference_without_last_4_actions" width="405" height="368" class="aligncenter size-full wp-image-2827" /></a></p><p>Now the difference varies between 6% and 15%.</p><p>Now, suppose that we have a compelling reason to actually go ahead with using this approach (we do actually, but i'm not gonna get into that here), do you think we can trust these numbers? Is there anything else we're missing? Are we complete idiots for testing the performance difference like this?  Do you have any feedback whatsoever? Then please leave a comment <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2010%2F10%2Fperformance-of-nhibernate-with-ruby-objects-compared-to-traditional-c-objects%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2010/10/performance-of-nhibernate-with-ruby-objects-compared-to-traditional-c-objects/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2010/10/performance-of-nhibernate-with-ruby-objects-compared-to-traditional-c-objects/"  data-text="Performance Of NHibernate With Ruby Objects Compared To Traditional C# Objects" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2010/10/performance-of-nhibernate-with-ruby-objects-compared-to-traditional-c-objects/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2010/10/performance-of-nhibernate-with-ruby-objects-compared-to-traditional-c-objects/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2010/10/performance-of-nhibernate-with-ruby-objects-compared-to-traditional-c-objects/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Think Twice Before You Map Entities To DTOs</title><link>http://davybrion.com/blog/2010/09/think-twice-before-you-map-entities-to-dtos/</link> <comments>http://davybrion.com/blog/2010/09/think-twice-before-you-map-entities-to-dtos/#comments</comments> <pubDate>Wed, 01 Sep 2010 11:58:32 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[NHibernate]]></category> <category><![CDATA[Performance]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=2607</guid> <description><![CDATA[One thing that i see a lot, and that i have largely started to avoid, is that people fetch entities with NHibernate, only to transform them to DTO's so you can send them back to the client so they can be displayed in a a grid or some kind of list or whatever. This is [...]]]></description> <content:encoded><![CDATA[<p>One thing that i see a lot, and that i have largely started to avoid, is that people fetch entities with NHibernate, only to transform them to DTO's so you can send them back to the client so they can be displayed in a a grid or some kind of list or whatever.  This is usually pretty easy to do, especially if you already have a DTO mapper or are using something like Automapper.  But this comes with a bit of overhead (both performance and memory) that you can often avoid quite easily.</p><p>Suppose i have a screen where i need to display entries based on the following DTO class:</p><div><pre class="brush: csharp; title: ; notranslate">
    public class AuthorizationDto
    {
        public long Id { get; set; }
        public Guid ApplicationId { get; set; }
        public string ApplicationName { get; set; }
        public Guid? UserGroupId { get; set; }
        public string UserGroupName { get; set; }
        public Guid? UserId { get; set; }
        public string Username { get; set; }
        public Guid PermissionId { get; set; }
        public string PermissionName { get; set; }
        public string PermissionDescription { get; set; }
    }
</pre></div><p>This DTO basically contains data from 4 entities: Application, UserGroup, User and Permission.  I could easily do something like this with NHibernate:</p><div><pre class="brush: csharp; title: ; notranslate">
            var items = Session.CreateCriteria&lt;Authorization&gt;()
                .CreateAlias(&quot;Application&quot;, &quot;a&quot;, JoinType.InnerJoin)
                .CreateAlias(&quot;User&quot;, &quot;u&quot;, JoinType.LeftOuterJoin)
                .CreateAlias(&quot;UserGroup&quot;, &quot;g&quot;, JoinType.LeftOuterJoin)
                .CreateAlias(&quot;Permission&quot;, &quot;p&quot;, JoinType.InnerJoin)
                .Future&lt;Authorization&gt;();

            var dtos = new AuthorizationDtoMapper().ToDtos(items);
</pre></div><p>As you can see, that's very easy to do.  Unfortunately, this code really does a lot of stuff that you might not realize.  For starters, it retrieves all of the Authorization instances with its related Application, User, UserGroup and Permission instances.  It also fetches those entities in their entirety, which means it's retrieving all of their properties while i only need their Id and Name properties really.  And finally, NHibernate will set up all of the things that enable its magic for all of these entity instances.  That takes a few more CPU cycles and uses more memory than you truly need for the scenario of fetching entities merely to return DTO's.  This extra cost obviously becomes worse depending on the size of the resultset that you're fetching.</p><p>A better way to do this, is to simply let NHibernate fetch only the data (columns) that you need, and to let it populate the DTO's itself.  You can easily do this using projections and the AliasToBeanResultTransformer class.  The code would look like this:</p><div><pre class="brush: csharp; title: ; notranslate">
            var dtos = Session.CreateCriteria&lt;Authorization&gt;()
                .CreateAlias(&quot;Application&quot;, &quot;a&quot;, JoinType.InnerJoin)
                .CreateAlias(&quot;User&quot;, &quot;u&quot;, JoinType.LeftOuterJoin)
                .CreateAlias(&quot;UserGroup&quot;, &quot;g&quot;, JoinType.LeftOuterJoin)
                .CreateAlias(&quot;Permission&quot;, &quot;p&quot;, JoinType.InnerJoin)
                .SetProjection(Projections.ProjectionList()
                    .Add(Projections.Id(), &quot;Id&quot;)
                    .Add(Projections.Property(&quot;a.Id&quot;), &quot;ApplicationId&quot;)
                    .Add(Projections.Property(&quot;a.Name&quot;), &quot;ApplicationName&quot;)
                    .Add(Projections.Property(&quot;u.Id&quot;), &quot;UserId&quot;)
                    .Add(Projections.Property(&quot;u.UserName&quot;), &quot;Username&quot;)
                    .Add(Projections.Property(&quot;g.Id&quot;), &quot;UserGroupId&quot;)
                    .Add(Projections.Property(&quot;g.Name&quot;), &quot;UserGroupName&quot;)
                    .Add(Projections.Property(&quot;p.Id&quot;), &quot;PermissionId&quot;)
                    .Add(Projections.Property(&quot;p.Name&quot;), &quot;PermissionName&quot;)
                    .Add(Projections.Property(&quot;p.Description&quot;), &quot;PermissionDescription&quot;))
                .SetResultTransformer(new AliasToBeanResultTransformer(typeof(AuthorizationDto)))
                .Future&lt;AuthorizationDto&gt;();
</pre></div><p>Granted, you need to write a bit more code.  But that code will do far less than the first version.</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2010%2F09%2Fthink-twice-before-you-map-entities-to-dtos%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2010/09/think-twice-before-you-map-entities-to-dtos/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2010/09/think-twice-before-you-map-entities-to-dtos/"  data-text="Think Twice Before You Map Entities To DTOs" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2010/09/think-twice-before-you-map-entities-to-dtos/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2010/09/think-twice-before-you-map-entities-to-dtos/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2010/09/think-twice-before-you-map-entities-to-dtos/feed/</wfw:commentRss> <slash:comments>20</slash:comments> </item> <item><title>Why You Shouldn&#8217;t Expose Your Entities Through Your Services</title><link>http://davybrion.com/blog/2010/05/why-you-shouldnt-expose-your-entities-through-your-services/</link> <comments>http://davybrion.com/blog/2010/05/why-you-shouldnt-expose-your-entities-through-your-services/#comments</comments> <pubDate>Mon, 17 May 2010 15:18:43 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Architecture]]></category> <category><![CDATA[Code Quality]]></category> <category><![CDATA[Opinions]]></category> <category><![CDATA[Performance]]></category> <category><![CDATA[WCF]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=2318</guid> <description><![CDATA[I sometimes still get questions from people who want to expose their entities through their WCF Services.&#160; Regardless of whether these are entities that are populated through NHibernate or any other ORM, this is just not a good thing to do.&#160; Many people prefer to accept and return entities through their services because they believe [...]]]></description> <content:encoded><![CDATA[<p>I sometimes still get questions from people who want to expose their entities through their WCF Services.&#160; Regardless of whether these are entities that are populated through NHibernate or any other ORM, this is just not a good thing to do.&#160; Many people prefer to accept and return entities through their services because they believe this is an easier programming model.&#160; They believe that it takes less work than mapping to DTO’s and that as a whole, this solution is much more manageable.&#160; Rest assured that this is a fallacy.&#160; Any perceived benefit that you’ll get from exposing entities outside of your service layer will only last a <em>very short time</em> and will quickly be dwarfed by added complexity, increased maintenance overhead and a performance overhead which must not be ignored.&#160;</p><p>In this post, i’d like to take the chance to explain the downsides to exposing entities through services.&#160; Though i’ll probably miss quite a few of the downsides (feel free to add to the list through comments), the ones i will mention are IMO important enough to take note of.</p><p><strong>Exposing entities to clients means your clients are very tightly coupled to your service(s)</strong></p><p>Entities are a part of your domain.&#160; These entities in your domain can change for various reasons.&#160; Sometimes because functional changes are required, but quite often also for optimizations (whether they are for performance reasons or to improve the clarity and maintainability of your domain).&#160; Functional changes <em>can </em>impact your clients, though that is not necessarily the case.&#160; Optimizations hardly ever have an impact on your clients (other than possibly improved response times from your service calls obviously).&#160; If your service layer accepts and returns domain entities, each possible change is highly likely to have an impact on your clients.&#160; And this impact is not cheap.&#160; In the best case scenario, it means updating your service contracts, regenerating your service proxies and redeploying your clients.&#160; In the worst case scenario, it means making actual changes to the code of your clients.&#160; And for what? Because of changes that shouldn’t have impacted your clients in the first place?</p><p>Ideally, your clients are as dumb as they can be.&#160; They should know as little as possible about the actual <em>implementation</em> of the domain because that implementation is simply not relevant to them.&#160; They should present users with data and give them the option to modify that data, to trigger actions and to perform certain tasks.&#160; They should focus squarely on those tasks and pretty much everything else is typically better suited to be done behind your service layer.&#160; If you build your clients with no real knowledge of the actual domain model, but of DTO’s and possible actions to be performed then you can reduce the level of coupling between your clients and your services substantially.</p><p>Many of the people who prefer to expose entities often claim that going for the DTO approach introduces too much extra work and too many extra, seemingly unnecessary classes.&#160; For starters, they don’t want to write code that maps entities to DTO’s.&#160; First of all, the amount of code that this requires is in reality <em>very small</em>, not to mention <em>very easy</em>.&#160; Secondly, you can just as well use a library such as AutoMapper to take that pain away from you.&#160; And contrary to what you might think, there is a big performance gain to be had from returning DTO’s over entities, but i’ll get to that in the next section.</p><h5></h5><h5></h5><p><strong>Entities are hardly ever the most optimal representation of data</strong></p><p>I think we can safely say that most applications need to show data in the following 3 ways:</p><ul><li>In a grid view, either as a total listing of all instances of a certain type of data or the result of a search query or some kind of filtering action</li><li>In dropdown controls or anything else that lets users select pieces of data</li><li>In edit screens where a piece of data needs to be displayed in its entirety, perhaps even to be modified by the user</li></ul><p>There are undoubtedly more ways in which data can be presented to the user but i think it’s safe to say that most business applications will certainly rely on the following 3 ways quite heavily.</p><p>In the case of a grid view, you’re frequently showing data that is related to more than one entity.&#160; You’ll often need to include the name or the description of some associated entities.&#160; So what exactly is it that you want to do in this situation?&#160; Do you want to return a list of the main entities of the grid view, which all have their required association properties filled in so you can display the columns that you need in the grid view?&#160; Do you actually need all of the properties of these entities (for both the main entities and the associated entities)?&#160; Odds are high that you’re going to be returning a lot more data to the client than you actually need.&#160; And that is what is realistically going to hurt the performance of your system.&#160; Any piece of unnecessary data that you transmit to your clients has a cost associated with it.&#160; The unnecessary data is retrieved from the database.&#160; The entities are then serialized at the service end.&#160; Then they are transmitted to the client.&#160; Then they are deserialized by your client.&#160; All of this is pretty costly, so the more unnecessary data that is included in this operation, the more your performance and the responsiveness of your client (not to mention your database and your server) is impacted negatively.</p><p>In the case of dropdown controls or anything else that lets users select pieces of data, you typically only need very few of the properties of that piece of data.&#160; In many cases, the primary key and a name or a description are sufficient.&#160; Do you really need to transmit the entire entity every time for usages like this? Again, keep in mind that all of that extra data that will never be used by your client needs to be retrieved, serialized, transmitted and deserialized again.&#160; Surely, this is an awful waste, no?&#160;</p><p>And then there’s the case where a piece of data needs to be displayed in its entirety.&#160; In these cases, you will almost always need all of the properties of the entity that is displayed, but you’ll most often also need to show other data (things that can be selected, or linked to the main entity).&#160; This other data will in most cases fall into the previous category where you’ll only need very little information about the actual entity.&#160; If you’re smart, you’ve chosen the DTO approach to retrieve this data for the data that can be selected, and in that case, you already have all of the infrastructural code in place to project entities or data into DTO’s.&#160; So you might as well reuse it for the main entity as well since you already have the capability to do this.</p><p>Always keep in mind that your entities will frequently either contain <em>more data than needed</em>, or <em>less data than needed</em>.&#160; As such, it just doesn’t make much sense to expose entities to your clients since they are hardly ever optimal for client-side usage.&#160; If you really want to think about performance, stop worrying about the supposed cost of mapping to DTO’s (which is truly negligible) and start focusing on <em>what</em> your actually <em>sending</em> to and from your service because this is far more costly than any kind of DTO-mapping really is.</p><p><strong>Must your data really come from entities?</strong></p><p>If you are displaying data to your user, does that data really need to come from your domain model?&#160; Does it really need to be retrieved by populating a collection of entities to then return them to the client?&#160; Again, keep the <em>form</em> of the data in mind when thinking about this.&#160; In many cases, as i mentioned above, an entity is not the most optimal form of the data that your client needs.&#160; So why even retrieve it through entities? Sure, asking your ORM to retrieve a set of entities based on a set of criteria is often the easiest thing to do, but if the easiest path were the best path, the overall quality of software projects wouldn’t be in the sad state that it’s in today.&#160; If the form of the required data is not identical to the structure of an entity, it’s often far more optimal to simply populate a DTO <em>directly from the data.</em>&#160; With NHibernate, you can easily do this by adding a list of projections to your query and then using a ResultTransformer to populate the DTO’s based on the direct output of the query.&#160; In this case, no entity instance ever needs to be created when you’re just retrieving data, and no extra mapping between the entity and the DTO’s needs to be performed.&#160; Your data access code simply retrieves the resulting data from a query, and puts that data directly in your DTO’s.&#160; There’s no reason why usage of an ORM should prevent you from doing this.&#160;&#160; Once again, this approach will offer far more performance benefits than avoiding DTO mapping at all costs ever can.</p><p><strong>What about the behavior of your entities?</strong></p><p>Do your entities have any behavior in them?&#160; If not, they are already more of a DTO than a true entity.&#160; In fact, if your entities have no behavior at all, you could even wonder why you’re using an ORM in the first place.&#160; Now, behavior can mean many things.&#160; It could mean lazy loading of associations.&#160; It could mean actual business logic.&#160; Obviously, lazy-loading doesn’t (and shouldn’t!) work client-side, but what about your business logic? Do you have business logic that <em>can </em>be executed client-side? Or is it business logic that should only be executed behind the service layer? If so, how do you make the distinction between this to prevent client-side usage from these entities? Whatever you do, you’re pretty much opening up a can of worms that really is better avoided in the first place.</p><p><strong>How are you going to deal with technical issues?</strong></p><p>Accepting and returning entities from services introduces a host of technical issues that can be quite substantial.&#160; Serialization and deserialization specifically are issues that you need to be worried about.&#160; If you’re using an ORM which does lazy-loading of associations, this will certainly cause serialization issues that you need to work around.&#160; You can either disable lazy loading, or you can make sure that your entities are always fully initialized (as in: always have their associations fully loaded) before they are sent back to the client.&#160; Disabling lazy-loading <em>will </em>cause performance problems in your service layer, either in places where you don’t expect them to be or in places that you haven’t thought of before it’s too late.&#160; Fully loading your entities and their associates before returning them is another performance nightmare waiting to happen so that’s really not an ideal solution either.&#160; You can try to hook into the serialization process or even the lazy-loading features of your ORM but whatever you do in that case will be a hack that <em>will</em> cause issues sooner or later.&#160; And again, all of these problems can very easily be avoided with a solution which, i hope you realize by now, offers plenty more benefits than any solution where you accept/return entities in your service.</p><p><strong>Conclusion</strong></p><p>Every single downside to exposing entities through services are issues that i have myself encountered in past projects, either ones i’ve worked on myself, or ones that i’ve seen other people work on.&#160; If that’s not enough for you, then maybe you’ll find it interesting to know that some of the brightest and most respected people (like Udi Dahan and Ayende for instance) in the .NET community also actively recommend against exposing entities through services because of the same downsides that i mentioned, though they could probably give you even more downsides that i forgot to cover in this post.&#160; These downsides are not figments of anyone’s imagination.&#160; They are very real, and you really, really ought to think twice before dismissing this advice.&#160;</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2010%2F05%2Fwhy-you-shouldnt-expose-your-entities-through-your-services%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2010/05/why-you-shouldnt-expose-your-entities-through-your-services/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2010/05/why-you-shouldnt-expose-your-entities-through-your-services/"  data-text="Why You Shouldn&rsquo;t Expose Your Entities Through Your Services" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2010/05/why-you-shouldnt-expose-your-entities-through-your-services/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2010/05/why-you-shouldnt-expose-your-entities-through-your-services/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2010/05/why-you-shouldnt-expose-your-entities-through-your-services/feed/</wfw:commentRss> <slash:comments>26</slash:comments> </item> <item><title>Using Copy-On-Write In Multithreaded Code To Reduce Locking Overhead</title><link>http://davybrion.com/blog/2010/03/using-copy-on-write-in-multithreaded-code-to-reduce-locking-overhead/</link> <comments>http://davybrion.com/blog/2010/03/using-copy-on-write-in-multithreaded-code-to-reduce-locking-overhead/#comments</comments> <pubDate>Mon, 08 Mar 2010 15:36:35 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Multithreading]]></category> <category><![CDATA[Performance]]></category><guid
isPermaLink="false">http://davybrion.com/blog/2010/03/using-copy-on-write-in-multithreaded-code-to-reduce-locking-overhead/</guid> <description><![CDATA[I recently posted some code that i asked you to review.&#160; When i posted it, the code had never even executed (that’s right, not even through a test) and i only thought it would do what i needed it to do.&#160; I consider the actual implementation non-obvious (at least for those who don’t know the [...]]]></description> <content:encoded><![CDATA[<p>I recently <a
href="http://davybrion.com/blog/2010/02/wanna-review-my-code/" target="_blank">posted some code</a> that i asked you to review.&#160; When i posted it, the code had never even executed (that’s right, not even through a test) and i only <em>thought</em> it would do what i needed it to do.&#160; I consider the actual implementation non-obvious (at least for those who don’t know the copy-on-write approach to avoid traditional locking) so i just wanted to hear some reactions to the code from people who didn’t knew the context.&#160; I promised to do a follow-up post to discuss the code in its entirety so here it is.</p><p>First, i’ll show the whole class again:</p><div
style="font-family: consolas; background: white; color: black; font-size: 10pt"><p
style="margin: 0px">&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">class</span> <span
style="color: #2b91af">TenantSessionFactoryManager</span> : <span
style="color: #2b91af">ITenantSessionFactoryManager</span></p><p
style="margin: 0px">&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">private</span> <span
style="color: blue">readonly</span> <span
style="color: #2b91af">ITenantContext</span> tenantContext;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">private</span> <span
style="color: blue">readonly</span> <span
style="color: #2b91af">ITenantInfoHolder</span> tenantInfoHolder;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">private</span> <span
style="color: blue">readonly</span> <span
style="color: blue">string</span> mappingAssemblyName;</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">private</span> <span
style="color: blue">readonly</span> <span
style="color: blue">object</span> writeLock = <span
style="color: blue">new</span> <span
style="color: blue">object</span>();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">private</span> <span
style="color: #2b91af">Dictionary</span>&lt;<span
style="color: #2b91af">Guid</span>, <span
style="color: #2b91af">ISessionFactory</span>&gt; sessionFactories;</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> TenantSessionFactoryManager(<span
style="color: #2b91af">ITenantContext</span> tenantContext, <span
style="color: #2b91af">ITenantInfoHolder</span> tenantInfoHolder, <span
style="color: blue">string</span> mappingAssemblyName)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">this</span>.tenantContext = tenantContext;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">this</span>.tenantInfoHolder = tenantInfoHolder;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">this</span>.mappingAssemblyName = mappingAssemblyName;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; sessionFactories = <span
style="color: blue">new</span> <span
style="color: #2b91af">Dictionary</span>&lt;<span
style="color: #2b91af">Guid</span>, <span
style="color: #2b91af">ISessionFactory</span>&gt;();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: #2b91af">ISession</span> CreateSessionForCurrentTenant()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">var</span> tenantId = tenantContext.CurrentTenantId;</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">if</span> (!sessionFactories.ContainsKey(tenantId))</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; CreateSessionFactoryForCurrentTenant();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">return</span> sessionFactories[tenantId].OpenSession();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">private</span> <span
style="color: blue">void</span> CreateSessionFactoryForCurrentTenant()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">lock</span> (writeLock)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">var</span> tenantId = tenantContext.CurrentTenantId;</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">if</span> (!sessionFactories.ContainsKey(tenantId))</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">var</span> connectionString = tenantInfoHolder.GetDatabaseConnectionString(tenantId);</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">var</span> sessionFactory = <span
style="color: blue">new</span> <span
style="color: #2b91af">Configuration</span>()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; .Configure()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; .AddProperties(<span
style="color: blue">new</span> <span
style="color: #2b91af">Dictionary</span>&lt;<span
style="color: blue">string</span>, <span
style="color: blue">string</span>&gt;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; { <span
style="color: #a31515">&quot;connection.connection_string&quot;</span>, connectionString },</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; { <span
style="color: #a31515">&quot;cache.region_prefix&quot;</span>, <span
style="color: #a31515">&quot;Tenant_&quot;</span> + tenantId }</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; })</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; .AddAssembly(mappingAssemblyName)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; .BuildSessionFactory();</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">var</span> newDictionary = <span
style="color: blue">new</span> <span
style="color: #2b91af">Dictionary</span>&lt;<span
style="color: #2b91af">Guid</span>, <span
style="color: #2b91af">ISessionFactory</span>&gt;(sessionFactories);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; newDictionary[tenantId] = sessionFactory;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; sessionFactories = newDictionary;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">void</span> RemoveSessionFactoryForTenant(<span
style="color: #2b91af">Guid</span> tenantId)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">if</span> (!sessionFactories.ContainsKey(tenantId))</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">return</span>;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">lock</span> (writeLock)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">if</span> (!sessionFactories.ContainsKey(tenantId))</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">return</span>;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">var</span> sessionFactory = sessionFactories[tenantId];</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">var</span> newDictionary = <span
style="color: blue">new</span> <span
style="color: #2b91af">Dictionary</span>&lt;<span
style="color: #2b91af">Guid</span>, <span
style="color: #2b91af">ISessionFactory</span>&gt;(sessionFactories);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; newDictionary.Remove(tenantId);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; sessionFactories = newDictionary;</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; sessionFactory.Dispose();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160; }</p></div><p>&#160;</p><p>Basically, the purpose of this class is to hold a set of ISessionFactory instances, each of which belongs to a particular tenant in a multi-tenant application.&#160; Tenants can be added on the fly (without restarting the application) and when an ISessionFactory doesn’t exist yet for a particular tenant, it must be created when the first request for an ISession for that tenant comes in.&#160; Obviously, access to the sessionFactories dictionary must be thread-safe since multiple threads will be reading from the dictionary as well as occasionally writing to it.</p><p>I considered 3 options to make sure access to the dictionary would be thread-safe:</p><ol><li>Traditional locking (through the lock statement or the Monitor class)</li><li>Using the <a
href="http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx" target="_blank">ReadWriterLockSlim</a> class</li><li>Using the copy-on-write pattern</li></ol><p>Traditional locking was quickly scratched from the list because that would require me to lock for every read of the dictionary as well as every write.&#160; Now, pretty much every single request requires an NHibernate session which means that pretty much every single request results in a lookup in the sessionFactories dictionary.&#160; If i need to lock for every read, this significantly hurts overall throughput of the system.&#160;</p><p>The ReadWriterLockSlim might be a good solution here… after all, the short description of this class in MSDN says this:</p><blockquote><p>Represents a lock that is used to manage access to a resource, allowing multiple threads for reading or exclusive access for writing.</p></blockquote><p>Sounds like what i need, right?&#160; But the thing is, i’ve never used the ReadWriterLockSlim class before and it hasn’t really gained my trust yet.&#160; I know that’s a terrible excuse for not using it, but here me out.&#160; While the ReadWriterLockSlim likely reduces locking overhead over traditional locking substantially, there still has to be <em>some</em> overhead for read operations, even if it is small.&#160; In most situations, that small overhead wouldn’t bother me but in this case, that little overhead would be added to pretty much <em>every single request</em> in the system.&#160; Now, writing to a dictionary implies that a new tenant has been added to the system.&#160; In the context of this system, that’s not even gonna happen on a daily basis.&#160; Hell, once a week is probably a best-case estimation and even that is highly optimistic.&#160; So i really don’t want any kind of overhead on read operations when the write operation is only going to happen very occasionally.</p><p>That leaves the copy-on-write pattern.&#160; I’ve used it <a
href="http://davybrion.com/blog/2009/02/challenge-do-you-truly-understand-this-code/" target="_blank">before</a> with success (though at the time, i didn’t know it was a known pattern) so this approach has already gained my trust.&#160; It basically implies that we don’t do <em>any</em> locking on the read operations, but whenever a write operation occurs we copy the original set of objects, perform the write on the newly copied set and then set the reference of the original set to the newly created and modified instance.&#160; During this whole time, every <em>single</em> read is safe.&#160; Successive reads within the same logical operation however aren’t, so the following code would not be thread-safe:</p><div
style="font-family: consolas; background: white; color: black; font-size: 10pt"><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">if</span> (sessionFactories.ContainsKey(tenantId))</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">return</span> sessionFactories[tenantId].OpenSession();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p></div><p>&#160;</p><p>Because there’s no locking on the reads, the code within the if-block could fail because the sessionFactories reference could be pointing to a new dictionary which no longer contains the element for that key.&#160;</p><p>Of course, if you have frequent writes, the overhead of copying the set of objects every time you need to add/remove one might be bigger than you want, so this isn’t a pattern that you should use whenever you need to protect access to a shared resource. For this situation however, i think it’s ideal… though i’d obviously like to hear about better solutions <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>Now, let’s take a closer look at the pieces of code that perform the write operations.&#160; First, adding a new ISessionFactory to the dictionary:</p><div
style="font-family: consolas; background: white; color: black; font-size: 10pt"><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">private</span> <span
style="color: blue">void</span> CreateSessionFactoryForCurrentTenant()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">lock</span> (writeLock)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">var</span> tenantId = tenantContext.CurrentTenantId;</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">if</span> (!sessionFactories.ContainsKey(tenantId))</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">var</span> connectionString = tenantInfoHolder.GetDatabaseConnectionString(tenantId);</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">var</span> sessionFactory = <span
style="color: blue">new</span> <span
style="color: #2b91af">Configuration</span>()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; .Configure()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; .AddProperties(<span
style="color: blue">new</span> <span
style="color: #2b91af">Dictionary</span>&lt;<span
style="color: blue">string</span>, <span
style="color: blue">string</span>&gt;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; { <span
style="color: #a31515">&quot;connection.connection_string&quot;</span>, connectionString },</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; { <span
style="color: #a31515">&quot;cache.region_prefix&quot;</span>, <span
style="color: #a31515">&quot;Tenant_&quot;</span> + tenantId }</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; })</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; .AddAssembly(mappingAssemblyName)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; .BuildSessionFactory();</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">var</span> newDictionary = <span
style="color: blue">new</span> <span
style="color: #2b91af">Dictionary</span>&lt;<span
style="color: #2b91af">Guid</span>, <span
style="color: #2b91af">ISessionFactory</span>&gt;(sessionFactories);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; newDictionary[tenantId] = sessionFactory;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; sessionFactories = newDictionary;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p></div><p>&#160;</p><p>As you can see, the entire operation is put between a lock on the writeLock object instance.&#160; The downside of this is that creating an ISessionFactory instance is an expensive operation, which means the lock will be held for a long time (could easily be one or more <em>seconds</em>).&#160; Then again, i don’t anticipate this happening frequently so it’s not that big of an issue… especially since reads aren’t being blocked by this anyway.&#160; This approach also prevents the creation of 2 ISessionFactory instances for the same tenant.&#160; Well, unless i missed a bug here :p</p><p>Now, once the ISessionFactory instance is created, we create a new Dictionary based on the contents of the old one and then we add the new ISessionFactory instance to it.&#160; After that, we replace the sessionFactories references with the new dictionary and from that point on, every read will use the new dictionary instance.&#160; During this entire operation, no read operation was impacted negatively.&#160;</p><p>Now lets take a look at the other write operation, removing an ISessionFactory instance from the dictionary:</p><div
style="font-family: consolas; background: white; color: black; font-size: 10pt"><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">void</span> RemoveSessionFactoryForTenant(<span
style="color: #2b91af">Guid</span> tenantId)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">if</span> (!sessionFactories.ContainsKey(tenantId))</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">return</span>;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">lock</span> (writeLock)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">if</span> (!sessionFactories.ContainsKey(tenantId))</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">return</span>;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">var</span> sessionFactory = sessionFactories[tenantId];</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">var</span> newDictionary = <span
style="color: blue">new</span> <span
style="color: #2b91af">Dictionary</span>&lt;<span
style="color: #2b91af">Guid</span>, <span
style="color: #2b91af">ISessionFactory</span>&gt;(sessionFactories);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; newDictionary.Remove(tenantId);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; sessionFactories = newDictionary;</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; sessionFactory.Dispose();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p></div><p>&#160;</p><p>The first if-check, which happens outside of the lock is a bug that i missed but that was pointed out in the comments of the original post.&#160; If CreateSessionFactoryForCurrentTenant and RemoveSessionFactoryForTenant would execute concurrently for the same tenant, it’s possible that the ISessionFactory instance of that tenant is never removed from the dictionary (and also never disposed of…) since the check happens outside of the lock and could be executed before the ISessionFactory of the tenant was added to the dictionary.&#160; In that case, the ISessionFactory instance would stay in the dictionary as long as the application stays up.&#160; This is definitely a race condition that you want to avoid in every other situation though in this case, the odds that we’re simultaneously adding and removing the same tenant are slim to none.&#160; Nevertheless, i don’t want to be accused of promoting race conditions so we’ll make the change anyway <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><div
style="font-family: consolas; background: white; color: black; font-size: 10pt"><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">void</span> RemoveSessionFactoryForTenant(<span
style="color: #2b91af">Guid</span> tenantId)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">lock</span> (writeLock)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">if</span> (!sessionFactories.ContainsKey(tenantId))</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">return</span>;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">var</span> sessionFactory = sessionFactories[tenantId];</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">var</span> newDictionary = <span
style="color: blue">new</span> <span
style="color: #2b91af">Dictionary</span>&lt;<span
style="color: #2b91af">Guid</span>, <span
style="color: #2b91af">ISessionFactory</span>&gt;(sessionFactories);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; newDictionary.Remove(tenantId);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; sessionFactories = newDictionary;</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; sessionFactory.Dispose();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p></div><p>&#160;</p><p>Now, as you can see we once again create a new dictionary based on the previous one, then remove the ISessionFactory instance for the current tenant and then we overwrite the sessionFactories instance once again.</p><p>Finally, there’s the read operation that i specifically didn’t want suffering from locking overhead:</p><div
style="font-family: consolas; background: white; color: black; font-size: 10pt"><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: #2b91af">ISession</span> CreateSessionForCurrentTenant()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">var</span> tenantId = tenantContext.CurrentTenantId;</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">if</span> (!sessionFactories.ContainsKey(tenantId))</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; CreateSessionFactoryForCurrentTenant();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">return</span> sessionFactories[tenantId].OpenSession();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p></div><p>&#160;</p><p>The only time this code will block is when a new ISessionFactory for the current tenant needs to be created.&#160; Luckily, that only happens once for each tenant.&#160; As i mentioned earlier in the post, using this pattern doesn’t guarantee that successive reads within the same logical operation are thread safe, so there is a bug in here.&#160; If a tenant already has an ISessionFactory instance, it’s possible that the RemoveSessionFactoryForTenant method has been executed between the if-check and accessing the ISessionFactory based on the tenantId.&#160; In that particular scenario, the ISessionFactory instance is no longer in the dictionary which will cause this code to throw an exception.</p><p>That’s a bug that i don’t feel like fixing though… Once a tenant has been removed, they are no longer a paying customer.&#160; If they are no longer paying for the software, there is no reason whatsoever why i should care about any possible exceptions they could get while running the software <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>Seriously though, if the RemoveSessionFactoryForTenant method is called, users of that tenant won’t even have access to the system anymore so it’s really a non-issue.</p><p>Anyways, i think i’ve covered the implementation in more detail than you probably cared for.&#160; So, any thoughts? Are there still issues that i haven’t thought of? Is there another approach that you would use for this specific scenario?</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2010%2F03%2Fusing-copy-on-write-in-multithreaded-code-to-reduce-locking-overhead%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2010/03/using-copy-on-write-in-multithreaded-code-to-reduce-locking-overhead/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2010/03/using-copy-on-write-in-multithreaded-code-to-reduce-locking-overhead/"  data-text="Using Copy-On-Write In Multithreaded Code To Reduce Locking Overhead" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2010/03/using-copy-on-write-in-multithreaded-code-to-reduce-locking-overhead/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2010/03/using-copy-on-write-in-multithreaded-code-to-reduce-locking-overhead/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2010/03/using-copy-on-write-in-multithreaded-code-to-reduce-locking-overhead/feed/</wfw:commentRss> <slash:comments>5</slash:comments> </item> <item><title>Virtual Method Performance Penalty</title><link>http://davybrion.com/blog/2010/01/virtual-method-performance-penalty/</link> <comments>http://davybrion.com/blog/2010/01/virtual-method-performance-penalty/#comments</comments> <pubDate>Sun, 10 Jan 2010 16:14:51 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[C#]]></category> <category><![CDATA[Performance]]></category><guid
isPermaLink="false">http://davybrion.com/blog/2010/01/virtual-method-performance-penalty/</guid> <description><![CDATA[You often hear/read that one of the reasons why C# methods aren’t virtual by default is because of performance.&#160; Calling a virtual method is more expensive than calling a regular instance method, because the CLR has to determine the correct override to call at runtime, instead of being able to simply call the instance method [...]]]></description> <content:encoded><![CDATA[<p>You often hear/read that one of the reasons why C# methods aren’t virtual by default is because of performance.&#160; Calling a virtual method is more expensive than calling a regular instance method, because the CLR has to determine the correct override to call at runtime, instead of being able to simply call the instance method directly.&#160; Another reason why virtual methods are more expensive to call is because they can never be inlined.</p><p>Is it really that much more expensive though? I ran a little experiment and i’d like to share the results with you.</p><p>Suppose you have the following 2 classes:</p><div
style="font-family: consolas; background: white; color: black; font-size: 10pt"><p
style="margin: 0px">&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">class</span> <span
style="color: #2b91af">MyClass</span></p><p
style="margin: 0px">&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">protected</span> <span
style="color: blue">long</span> someLong;</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">void</span> IncreaseLong()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; someLong++;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">virtual</span> <span
style="color: blue">void</span> VirtualIncreaseLong()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; someLong++;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">class</span> <span
style="color: #2b91af">MyDerivedClass</span> : <span
style="color: #2b91af">MyClass</span></p><p
style="margin: 0px">&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">override</span> <span
style="color: blue">void</span> VirtualIncreaseLong()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; someLong += 2;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160; }</p></div><p>&#160;</p><p>As you can see, there is no difference between the IncreaseLong and VirtualIncreaseLong methods, except that the latter is virtual and the former is a regular instance method.&#160; According to many people, calling VirtualIncreaseLong instead of IncreaseLong will be more expensive.&#160; I also have a derived class which overrides the VirtualIncreaseLong method with a slightly different implementation.</p><p>If we call these methods a bunch of times (like 1000000000 times), we should notice quite a difference according to many people.</p><p>I wrote the following test code which calls these methods a bunch of times, times it, and outputs the results.</p><div
style="font-family: consolas; background: white; color: black; font-size: 10pt"><p
style="margin: 0px">&#160;&#160;&#160; <span
style="color: blue">class</span> <span
style="color: #2b91af">Program</span></p><p
style="margin: 0px">&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">const</span> <span
style="color: blue">int</span> numberOfTimes = 1000000000;</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">static</span> <span
style="color: blue">void</span> Main(<span
style="color: blue">string</span>[] args)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">var</span> myObject = <span
style="color: blue">new</span> <span
style="color: #2b91af">MyClass</span>();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">var</span> myDerivedObject = <span
style="color: blue">new</span> <span
style="color: #2b91af">MyDerivedClass</span>();</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: green">// we do this so there's no first-time performance cost while timing</span></p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; EnsureThatEverythingHasBeenJitted(myObject);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; EnsureThatEverythingHasBeenJitted(myDerivedObject);</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; TestNormalIncreaseMethod(myObject);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; TestVirtualIncreaseMethod(myObject);</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; TestNormalIncreaseMethod(myDerivedObject);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; TestVirtualIncreaseMethod(myDerivedObject);</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: #2b91af">Console</span>.ReadLine();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">static</span> <span
style="color: blue">void</span> EnsureThatEverythingHasBeenJitted(<span
style="color: #2b91af">MyClass</span> theObject)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; theObject.IncreaseLong();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; theObject.VirtualIncreaseLong();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">static</span> <span
style="color: blue">void</span> TestNormalIncreaseMethod(<span
style="color: #2b91af">MyClass</span> theObject)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: #2b91af">Console</span>.WriteLine(<span
style="color: blue">string</span>.Format(<span
style="color: #a31515">&quot;calling the IncreaseLong method of type {0} {1} times&quot;</span>, theObject.GetType().Name, numberOfTimes));</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">var</span> stopwatch = <span
style="color: #2b91af">Stopwatch</span>.StartNew();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">for</span> (<span
style="color: blue">var</span> i = 0; i &lt; numberOfTimes; i++)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; theObject.IncreaseLong();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; stopwatch.Stop();</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: #2b91af">Console</span>.WriteLine(<span
style="color: #a31515">&quot;Elapsed milliseconds: &quot;</span> + stopwatch.ElapsedMilliseconds);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">static</span> <span
style="color: blue">void</span> TestVirtualIncreaseMethod(<span
style="color: #2b91af">MyClass</span> theObject)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: #2b91af">Console</span>.WriteLine(<span
style="color: blue">string</span>.Format(<span
style="color: #a31515">&quot;calling the VirtualIncreaseLong method of type {0} {1} times&quot;</span>, theObject.GetType().Name, numberOfTimes));</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">var</span> stopwatch = <span
style="color: #2b91af">Stopwatch</span>.StartNew();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">for</span> (<span
style="color: blue">var</span> i = 0; i &lt; numberOfTimes; i++)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; theObject.VirtualIncreaseLong();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; stopwatch.Stop();</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: #2b91af">Console</span>.WriteLine(<span
style="color: #a31515">&quot;Elapsed milliseconds: &quot;</span> + stopwatch.ElapsedMilliseconds);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160; }</p></div><p>&#160;</p><p>The output of running this code might surprise you.&#160; On my machine, i got the following results when the code was compiled in debug mode:</p><p><a
href="http://davybrion.com/blog/wp-content/uploads/2010/01/manual_compile_debug.png" rel="prettyPhoto[2169]"><img
style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="manual_compile_debug" border="0" alt="manual_compile_debug" src="http://davybrion.com/blog/wp-content/uploads/2010/01/manual_compile_debug_thumb.png" width="753" height="161" /></a></p><p>The difference between calling the regular instance method and the virtual method is quite small.&#160; I’d even say it’s negligible.</p><p>When compiling in release mode, i got the following output:</p><p><a
href="http://davybrion.com/blog/wp-content/uploads/2010/01/manual_compile_optimized.png" rel="prettyPhoto[2169]"><img
style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="manual_compile_optimized" border="0" alt="manual_compile_optimized" src="http://davybrion.com/blog/wp-content/uploads/2010/01/manual_compile_optimized_thumb.png" width="757" height="171" /></a></p><p>I ran the test a bunch of times, and there was no consistent observable performance penalty when calling the virtual methods.&#160; In fact, the virtual methods often performed faster than the regular instance methods and in most cases were equally fast.&#160; I’m not claiming that virtual methods are faster than regular instance methods, but if there really was an extra <em>real-world </em>performance cost associated with virtual methods, it surely should be observable with this test code, no?</p><p>Obviously, this test isn’t scientific in any way.&#160; But still, i think it does show that the so called performance cost associated with virtual methods is highly overrated.&#160; There definitely will be cases where virtual methods are more expensive than regular instance methods, but i’m willing to bet that those cases are rare and that the vast majority of .NET developers will never be negatively impacted by it.&#160;</p><p>Side note: have you ever noticed that most people who recommend to avoid virtual methods due to their performance cost never put the same emphasis on avoiding the cost of say, frequent remote operations?&#160; Which is odd, since i wouldn’t be surprised if that would be the most common reason for performance problems with .NET applications.&#160; Then again, that’s what you get when the biggest company pushing a platform advocates meaningless performance improvements while at the same time pushing bad architectural decisions/guidelines on the world because the resulting code is supposedly easier to write, use and maintain.</p><p>You can download the example code <a
href="http://davybrion.com/VirtualMethodsPerformance.zip" target="_blank">here</a> so you can run the test yourself.&#160;</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2010%2F01%2Fvirtual-method-performance-penalty%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2010/01/virtual-method-performance-penalty/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2010/01/virtual-method-performance-penalty/"  data-text="Virtual Method Performance Penalty" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2010/01/virtual-method-performance-penalty/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2010/01/virtual-method-performance-penalty/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2010/01/virtual-method-performance-penalty/feed/</wfw:commentRss> <slash:comments>20</slash:comments> </item> <item><title>Monitoring Production Performance</title><link>http://davybrion.com/blog/2009/09/monitoring-production-performance/</link> <comments>http://davybrion.com/blog/2009/09/monitoring-production-performance/#comments</comments> <pubDate>Mon, 07 Sep 2009 19:48:54 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Performance]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=1624</guid> <description><![CDATA[It's always interesting to know how well your applications perform in production. To get a better view on this, i recently added a bit of performance related logging to the RequestProcessor class of my Request/Response service layer. I have the following 2 loggers set up: And here's a simplified version of the Process method: The [...]]]></description> <content:encoded><![CDATA[<p>It's always interesting to know how well your applications perform in production.  To get a better view on this, i recently added a bit of performance related logging to the RequestProcessor class of my <a
href="http://davybrion.com/blog/2008/07/the-request-response-service-layer/">Request/Response service layer</a>.  I have the following 2 loggers set up:</p><div><pre class="brush: csharp; title: ; notranslate">
        private readonly ILog logger = LogManager.GetLogger(typeof(RequestProcessor));
        private readonly ILog performanceLogger = LogManager.GetLogger(&quot;PERFORMANCE&quot;);
</pre></div><p>And here's a simplified version of the Process method:</p><div><pre class="brush: csharp; title: ; notranslate">
        public Response[] Process(params Request[] requests)
        {
            if (requests == null) return null;
 
            var responses = new List&lt;Response&gt;(requests.Length);
 
            var batchStopwatch = Stopwatch.StartNew();
 
            foreach (var request in requests)
            {
                try
                {
                    using (var handler = (IRequestHandler)IoC.Container.Resolve(GetHandlerTypeFor(request)))
                    {
                        var requestStopwatch = Stopwatch.StartNew();
 
                        try
                        {
                            // NOTE: the real code has a lot more stuff in this block for dealing with
                            // failed requests etc...
                            responses.Add(GetResponseFromHandler(request, handler));
                        }
                        finally
                        {
                            requestStopwatch.Stop();
 
                            if (requestStopwatch.ElapsedMilliseconds &gt; 100)
                            {
                                performanceLogger.Warn(string.Format(&quot;Performance warning: {0}ms for {1}&quot;,
                                    requestStopwatch.ElapsedMilliseconds, handler.GetType().Name));
                            }
 
                            IoC.Container.Release(handler);
                        }
                    }
                }
                catch (Exception e)
                {
                    // NOTE: every single thrown exception in the service layer (and everything below it)
                    // is caught here and logged only once
                    logger.Error(e);          
                    throw;
                }
            }
 
            batchStopwatch.Stop();
 
            if (batchStopwatch.ElapsedMilliseconds &gt; 200)
            {
                var builder = new StringBuilder();
 
                foreach (var request in requests)
                {
                    builder.Append(request.GetType().Name + &quot;, &quot;);
                }
                builder.Remove(builder.Length - 2, 2);
 
                performanceLogger.Warn(string.Format(&quot;Performance warning: {0}ms for the following batch: {1}&quot;,
                    batchStopwatch.ElapsedMilliseconds, builder));
            }
 
            return responses.ToArray();
        }
</pre></div><p>The part that is simplified is simply the part that deals with getting the actual responses for each request, including how to deal with failed requests and how to handle subsequent requests in the batch.  It's not relevant to this post and it only clutters the code more so i left that out.  But anyways, the interesting part here is the performance logging.  Ok, the code itself isn't interesting but what you get out of it is pretty nice.  Each single request that takes more than 100 milliseconds is logged.  Also, each batch of requests that takes more than 200 milliseconds is logged.  Both of these 'events' are logged to the performance logger which, in our case, is set up to use a different logfile than the typical error log.</p><p>Which gives us some interesting looking data, like this:</p><p>WARN 2009-09-05 08:58:45 - Performance warning: 122ms for GetOpportunityCardHandler <br/> WARN 2009-09-05 09:00:45 - Performance warning: 159ms for GetCompanyCardHandler <br/> WARN 2009-09-05 09:01:23 - Performance warning: 187ms for GetOpportunityCardHandler <br/> WARN 2009-09-05 09:01:32 - Performance warning: 155ms for GetCompanyCardHandler <br/> WARN 2009-09-05 09:01:41 - Performance warning: 189ms for GetOpportunityCardHandler <br/> WARN 2009-09-05 09:01:41 - Performance warning: 336ms for the following batch: GetSalesTaskCardRequest, GetContactCardRequest, GetOpportunityCardRequest, GetCompanyCardRequest <br/></p><p>336ms for a single batch of requests is rather slow, and if we see this output regularly in the logfile, we definitely know that these specific request handlers really need to be optimized because we can be pretty sure that is too slow in the real production environment.</p><p>It's also useful to identify single request handlers who could use some optimization:</p><p>WARN 2009-09-04 02:55:40 - Performance warning: 108ms for PersistIssueHandler <br/> WARN 2009-09-04 05:54:50 - Performance warning: 148ms for PersistTimesheetEntryHandler <br/></p><p>We've already deployed this for an internal version of one of our applications, which helped us identify some parts that we really needed to optimize before our next external deployment (for our customers).  Even better, when we deploy for our customers, each log entry will also contain the name of the tenant (customer) for which the performance warning was generated.  Which will only make it easier for us to identify real hotspots, based on real usage from our customers, and try to optimize them as soon as possible, preferably before customers start complaining about specific parts.</p><p>I'm sure some of you are already doing something similar, but i'm also pretty sure that most of you aren't doing this yet.  I'd definitely recommend doing something like this, because it definitely makes it easier to fix <em>real</em> performance issues instead of the theoretical ones <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F09%2Fmonitoring-production-performance%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2009/09/monitoring-production-performance/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2009/09/monitoring-production-performance/"  data-text="Monitoring Production Performance" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2009/09/monitoring-production-performance/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2009/09/monitoring-production-performance/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2009/09/monitoring-production-performance/feed/</wfw:commentRss> <slash:comments>7</slash:comments> </item> <item><title>Reducing ViewState Size</title><link>http://davybrion.com/blog/2009/09/reducing-viewstate-size/</link> <comments>http://davybrion.com/blog/2009/09/reducing-viewstate-size/#comments</comments> <pubDate>Tue, 01 Sep 2009 12:56:53 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[ASP.NET]]></category> <category><![CDATA[Performance]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=1593</guid> <description><![CDATA[I dislike ViewState as much as the next guy, but when you're working with ASP.NET WebForms, you just can't avoid it. In some cases, the size of the ViewState can become so big that it significantly increases the load time of pages due to the extra bandwidth consumption. The correct solution would obviously be to [...]]]></description> <content:encoded><![CDATA[<p>I dislike ViewState as much as the next guy, but when you're working with ASP.NET WebForms, you just can't avoid it.  In some cases, the size of the ViewState can become so big that it significantly increases the load time of pages due to the extra bandwidth consumption.  The correct solution would obviously be to reduce the size of the ViewState in those pages as much as you can, but it's not always feasible to do so.  So we wanted a more general 'solution', and i found <a
href="http://aspadvice.com/blogs/mamanzes_blog/archive/2006/08/27/Save-some-space_2C00_-compress-that-ViewState.aspx">this post</a> which discusses compressing the ViewState before you send it to the client and decompressing it when the client sends it back.  We used pretty much the same approach, but with some differences.</p><p>First of all, ViewState is persisted in the resulting HTML page through an IStateFormatter object.  We'll provide our own CompressedStateFormatter which implements the IStateFormatter interface, and uses the standard IStateFormatter that ASP.NET uses:</p><div><pre class="brush: csharp; title: ; notranslate">
    public class CompressedStateFormatter : IStateFormatter
    {
        private readonly IStateFormatter actualFormatter;
 
        public CompressedStateFormatter(IStateFormatter actualFormatter)
        {
            this.actualFormatter = actualFormatter;
        }
 
        public string Serialize(object state)
        {
            string decompressedState = actualFormatter.Serialize(state);
 
            using (MemoryStream memoryStream = new MemoryStream())
            {
                using (Stream zipStream = new GZipStream(memoryStream, CompressionMode.Compress))
                using (StreamWriter writer = new StreamWriter(zipStream))
                {
                    writer.Write(decompressedState);
                }
 
                return Convert.ToBase64String(memoryStream.ToArray());
            }
        }
 
        public object Deserialize(string serializedState)
        {
            byte[] data = Convert.FromBase64String(serializedState);
 
            using (MemoryStream memoryStream = new MemoryStream(data))
            using (Stream zippedStream = new GZipStream(memoryStream, CompressionMode.Decompress))
            using (StreamReader reader = new StreamReader(zippedStream))
            {
                return actualFormatter.Deserialize(reader.ReadToEnd());
            }
        }
    }
</pre></div><p>The idea is very simple: when the Serialize method is called, we first call the real formatter's Serialize method, compress its return value and then return the Base64-encoded string of the compressed serialized state.  And in the Deserialize method, we do the exact opposite: we first decompress the Base64-encoded string and then we use the real formatter to deserialize the actual ViewState.</p><p>In Mamanze's example, he checks to see if the compressed version is actually smaller than the decompressed version and if so, uses the decompressed version instead of the compressed one.  And when decompressing he first checks to see if it's a compressed or decompressed version and obviously only decompresses in case of a compressed version.  The only page where i found the compressed version of the ViewState to be larger than the decompressed version was in our log in page, so i just got rid of that piece of the code.</p><p>Now we still have to plug this into ASP.NET's behavior somehow... first we add a pagestate.browser file to the App_Browsers folder of your web application (if it doesn't exist, just create it) with the following content:</p><div><pre class="brush: xml; title: ; notranslate">
&lt;browsers&gt;
  &lt;browser refID=&quot;Default&quot;&gt;
    &lt;controlAdapters&gt;
      &lt;adapter controlType=&quot;System.Web.UI.Page&quot; adapterType=&quot;Our.Application.CompressedPageStateAdapter&quot; /&gt;
    &lt;/controlAdapters&gt;
  &lt;/browser&gt;
&lt;/browsers&gt;
</pre></div><p>The CompressedPageStateAdapter looks like this:</p><div><pre class="brush: csharp; title: ; notranslate">
    public class CompressedPageStateAdapter : PageAdapter
    {
        public override PageStatePersister GetStatePersister()
        {
            return new CompressedHiddenFieldPageStatePersister(Page);
        }
    }
</pre></div><p>And the CompressedHiddenFieldPageStatePersister class looks like this:</p><div><pre class="brush: csharp; title: ; notranslate">
    public class CompressedHiddenFieldPageStatePersister : HiddenFieldPageStatePersister
    {
        public CompressedHiddenFieldPageStatePersister(Page page) : base(page)
        {
            FieldInfo field = typeof(PageStatePersister).GetField(&quot;_stateFormatter&quot;, BindingFlags.NonPublic | BindingFlags.Instance);
            // retrieving this property instantiates the default IStateFormatter
            var defaultFormatter = base.StateFormatter;
            var formatter = new CompressedStateFormatter(defaultFormatter);
            field.SetValue(this, formatter);
        }
    }
</pre></div><p>The HiddenFieldPageStatePersister is the class that ASP.NET WebForms will use by default to store your ViewState into a hidden field in the resulting HTML.  By default, the HiddenFieldPageStatePersister uses the default IStateFormatter type that ASP.NET uses, which only uses Base64 encoding but no compression.  Unfortunately, there is no clean way to instruct ASP.NET to use a different implementation for IStateFormatter, so we need to use a bit of reflection to overwrite the value of HiddenFieldPageStatePersister's _stateFormatter field.  Luckily, this also enables us to first get the value of the StateFormatter property so we can pass this reference (which is the 'real' formatter) to our CompressedStateFormatter.</p><p>And that is all there is to it... all of your pages will now use this CompressedHiddenFieldPageStatePersister so you get the benefit of ViewState compression in each of your pages.  You can also do this selectively if you want, by not using the pagestate.browser file and overriding the PageStatePersister property of your ASPX page:</p><div><pre class="brush: csharp; title: ; notranslate">
        private CompressedHiddenFieldPageStatePersister persister;
 
        protected override PageStatePersister PageStatePersister
        {
            get
            {
                if (persister == null)
                {
                    persister = new CompressedHiddenFieldPageStatePersister(this);
                }
 
                return persister;
            }
        }
</pre></div><p>This way, only the pages that contain this code will use the CompressedHiddenFieldPageStatePersister.</p><p>Instead of inheriting from HiddenFieldPageStatePersister, you could also inherit from SessionPageStatePersister.  SessionPageStatePersister will store your ViewState in the HttpSessionState, and will only include a little bit of ViewState in your HTML page instead of everything.  But you do need to be aware of the fact that using the CompressedStateFormatter when inheriting from SessionPageStatePersister will only result in compressing the little bit of ViewState that is included in the HTML, and <strong>not</strong> the ViewState that is stored in the HttpSessionState.</p><p>In case you're wondering: why should i use this instead of using typical HTTP compression on the IIS level?  I believe it has a couple of advantages to HTTP compression.  First of all, AFAIK, HTTP compression does not have any benefit on postbacks.  And since ViewState is always posted back to the server, this can make a pretty big difference.  Also, with this approach, the client will not have to decompress the entire ViewState (which isn't used client-side anyway) and the browser doesn't have to waste time on it in general.</p><p>I haven't used this in production yet, but i will very soon... unless someone knows of a good reason why i shouldn't <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F09%2Freducing-viewstate-size%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2009/09/reducing-viewstate-size/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2009/09/reducing-viewstate-size/"  data-text="Reducing ViewState Size" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2009/09/reducing-viewstate-size/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2009/09/reducing-viewstate-size/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2009/09/reducing-viewstate-size/feed/</wfw:commentRss> <slash:comments>14</slash:comments> </item> <item><title>Of Course NHibernate Is Slow When You Use It Incorrectly</title><link>http://davybrion.com/blog/2009/08/of-course-nhibernate-is-slow-when-you-use-it-incorrectly/</link> <comments>http://davybrion.com/blog/2009/08/of-course-nhibernate-is-slow-when-you-use-it-incorrectly/#comments</comments> <pubDate>Wed, 19 Aug 2009 20:48:36 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[NHibernate]]></category> <category><![CDATA[Performance]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=1511</guid> <description><![CDATA[Just saw the following post where the performance of NHibernate and Entity Framework is compared for a couple of different operations. Spoiler alert: NHibernate loses. As it typically does in these kinds of 'benchmarks' or 'comparisons' that seem to pop up frequently lately. For some reason, a lot of people seem to think that opening [...]]]></description> <content:encoded><![CDATA[<p>Just saw the following <a
href="http://gregdoesit.com/2009/08/nhibernate-vs-entity-framework-a-performance-test/">post</a> where the performance of NHibernate and Entity Framework is compared for a couple of different operations.  Spoiler alert: NHibernate loses.  As it typically does in these kinds of 'benchmarks' or 'comparisons' that seem to pop up frequently lately.</p><p>For some reason, a lot of people seem to think that opening an NHibernate session and performing thousands of operations is a valid use case.  It's not.  Far from it actually.  And with all of the features that NHibernate offers, it can't possibly perform well in such a scenario.  See, an NHibernate session is a <a
href="http://martinfowler.com/eaaCatalog/unitOfWork.html">unit of work</a>.  A unit of work is a business transaction which is typically short and small, but it should never be something huge.  Your DBA probably won't appreciate huge database transactions on the database either.</p><p>Whenever you load an object through NHibernate, it will be tracked by the session that loaded it.  That means that the NHibernate session keeps a reference to it, and performs a series of checks on it periodically, depending on what you're doing and some configuration settings such as the FlushMode.  For instance, suppose you've loaded a hundred different entities in one session.  If the FlushMode is set to automatic, it means that NHibernate will perform a dirty check for each entity associated with the session before each query is executed.  The more entity instances you've loaded, the longer this takes (obviously).  If you take this to an extreme level, like loading thousands of entities like most of these 'benchmarks' do, performance will naturally be horrible.</p><p>Each entity instance is also stored in the first level (or session level) cache.  That means that whenever you retrieve a row from the database, NHibernate will check if an instance of that row already exists in the first level cache.  Again, the more instances you've loaded, the larger the overhead of this will be.   There are also a lot of possible extension points where you can plug in custom logic.  Again, there is a very minor cost that comes with this extensibility and as you can expect, that minor cost can add up to something much more noticable once you start dealing with an unreasonably large number of instances in your session.</p><p>Always keep in mind that an ORM (and this goes for every ORM) is most suitable for <a
href="http://en.wikipedia.org/wiki/OLTP">OLTP</a>.  Using an ORM for batch processing jobs or large data processing operations in general is simply put a bad idea.  And they will never perform as well as other solutions in these scenarios.  So please don't bother even benchmarking ORM performance in non OLTP usage because it quite simply doesn't make sense to do so, and the results will be completely untrustworthy anyway.</p><p>An ORM can offer you nice performance gains in OLTP scenarios simply by trying to minimize database connectivity, minimizing the number of database operations, and relatively sane caching usage.  Unfortunately, these are aspects that are never tested in these 'benchmarks' or 'comparisons'.</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F08%2Fof-course-nhibernate-is-slow-when-you-use-it-incorrectly%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2009/08/of-course-nhibernate-is-slow-when-you-use-it-incorrectly/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2009/08/of-course-nhibernate-is-slow-when-you-use-it-incorrectly/"  data-text="Of Course NHibernate Is Slow When You Use It Incorrectly" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2009/08/of-course-nhibernate-is-slow-when-you-use-it-incorrectly/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2009/08/of-course-nhibernate-is-slow-when-you-use-it-incorrectly/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2009/08/of-course-nhibernate-is-slow-when-you-use-it-incorrectly/feed/</wfw:commentRss> <slash:comments>16</slash:comments> </item> <item><title>Avoid Using NHibernate With NUnit 2.4.6</title><link>http://davybrion.com/blog/2009/06/avoid-using-nhibernate-with-nunit-2-4-6/</link> <comments>http://davybrion.com/blog/2009/06/avoid-using-nhibernate-with-nunit-2-4-6/#comments</comments> <pubDate>Wed, 24 Jun 2009 17:35:42 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[NHibernate]]></category> <category><![CDATA[Performance]]></category> <category><![CDATA[testing]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=1432</guid> <description><![CDATA[We just spent about 2 hours trying to find out why our NHibernate tests were about 10x slower on our build server than they were on our local machines. I had noticed lately that the build for one of our projects was taking longer and longer but i hadn't really timed the difference. This project [...]]]></description> <content:encoded><![CDATA[<p>We just spent about 2 hours trying to find out why our NHibernate tests were about 10x slower on our build server than they were on our local machines.  I had noticed lately that the build for one of our projects was taking longer and longer but i hadn't really timed the difference.  This project has about 1200 tests that use NHibernate and they run in about 45-60 seconds on my local machine.  It turns out they took around 15 <strong>minutes</strong> on the buildserver when running them through TeamCity.</p><p>I logged into the buildserver and ran the tests manually using nunit's console runner (with an NUnit-2.4.7 build that i happened to have installed somewhere on the machine) and they only took about 45 seconds.  After a lot of guesswork and screwing around, it turned out that we never modified our base build script (why yes, i do believe in build script inheritance) to use a newer version of NUnit.  We set up the buildserver about 1 year ago, and at that time, the latest stable NUnit version that TeamCity supported was NUnit 2.4.6.  Our base build script was still referring to NUnit 2.4.6, which apparently <a
href="http://blogs.lessthandot.com/index.php/DesktopDev/MSTech/nhibernate-nunit-2-4-6-and-log4net">sets log4net to use debug level logging</a>.  Now, NHibernate logs a huge amount of information at the debug level, so this turned out to slow down all of our builds that had NHibernate tests.</p><p>We changed the the 2.4.6 version in our script to 2.4.7 and the build time of this particular project decreased from around 50 minutes to about 35 minutes.  Yes, that's still a lot but this is a huge project with a lot of legacy tests and the entire build process is pretty complex.  Other projects went from build times from around 7 minutes to about 2 minutes.</p><p>That's a pretty nice improvement for simply changing a "6" to a "7" <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F06%2Favoid-using-nhibernate-with-nunit-2-4-6%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2009/06/avoid-using-nhibernate-with-nunit-2-4-6/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2009/06/avoid-using-nhibernate-with-nunit-2-4-6/"  data-text="Avoid Using NHibernate With NUnit 2.4.6" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2009/06/avoid-using-nhibernate-with-nunit-2-4-6/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2009/06/avoid-using-nhibernate-with-nunit-2-4-6/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2009/06/avoid-using-nhibernate-with-nunit-2-4-6/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Keep An Eye On Those Indexes</title><link>http://davybrion.com/blog/2009/05/keep-an-eye-on-those-indexes/</link> <comments>http://davybrion.com/blog/2009/05/keep-an-eye-on-those-indexes/#comments</comments> <pubDate>Thu, 21 May 2009 12:14:57 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Performance]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=1387</guid> <description><![CDATA[We have a multi-tenant application, where each tenant has its own database. We recently were informed about a particular performance problem that one tenant (which we'll refer to as Tenant A) was experiencing in every screen where data of a certain type needed to be shown. None of the other tenants experienced this problem though. [...]]]></description> <content:encoded><![CDATA[<p>We have a multi-tenant application, where each tenant has its own database. We recently were informed about a particular performance problem that one tenant (which we'll refer to as Tenant A) was experiencing in every screen where data of a certain type needed to be shown.  None of the other tenants experienced this problem though.</p><p>We tracked down the query that was causing the bad performance and ran it on the database of Tenant B.  Tenant B actually had a lot more data in the main table that was used in the query and the query executed immediately whereas it took about 25 seconds to complete for Tenant A.   So the query runs fast on another database that actually has more data... at this point i was convinced that it had to be related to indexes.</p><p>Turns out that someone recently ran an import process to import a bunch of data in Tenant A's database. I know very little about databases, but one thing i've seen time and time again (with both Oracle and SQL Server) is that you really need to make sure that your indexes are in good shape after any process that performs a lot of inserts (or removals).   A couple of years ago, i had a very intensive nightly import process for a particular project that used an Oracle database.  As time went on, the application's queries became painfully (unacceptably even) slow.  I managed to restore the performance of those queries by simply instructing Oracle to recalculate all of the statistics of the indexes of tables that were affected heavily during the nightly import.</p><p>With that in mind, we simply rebuilt the indexes for Tenant A's database, and the same query that took 25 seconds completed almost instantly from then on.  Now, we did had a weekly job running on that database server to keep the indexes in a healthy shape but that job didn't really do a good umm... job of it, apparently.</p><p>Lessons learned: make sure that you:</p><ul><li>Have a proper maintenance job set up which keeps your indexes healthy and schedule it to run regularly</li><li>Run that job manually if you need to perform a manual import process</li><li>Execute that job in an automated fashion whenever an intensive automated import process has completed</li></ul><p>Oh, and consult with your DBA's or at least people who know what they're doing when it comes to your particular database on how to keep those indexes healthy.  In this case, we rebuilt them.  In other cases it's sufficient to recalculate the statistics... i'm not sure which way is the best but you should at least keep an eye on this possible problem <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F05%2Fkeep-an-eye-on-those-indexes%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2009/05/keep-an-eye-on-those-indexes/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2009/05/keep-an-eye-on-those-indexes/"  data-text="Keep An Eye On Those Indexes" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2009/05/keep-an-eye-on-those-indexes/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2009/05/keep-an-eye-on-those-indexes/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2009/05/keep-an-eye-on-those-indexes/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Using The Guid.Comb Identifier Strategy</title><link>http://davybrion.com/blog/2009/05/using-the-guidcomb-identifier-strategy/</link> <comments>http://davybrion.com/blog/2009/05/using-the-guidcomb-identifier-strategy/#comments</comments> <pubDate>Thu, 21 May 2009 12:00:31 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[NHibernate]]></category> <category><![CDATA[Performance]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=1238</guid> <description><![CDATA[As you may have read by now, it's a good idea to avoid identity-style identifier strategies with ORM's. One of the better alternatives that i kinda like is the guid.comb strategy. Using regular guids as a primary key value leads to fragmented indexes (due to the randomness of the guid's value) which leads to bad [...]]]></description> <content:encoded><![CDATA[<p>As you may have read by now, it's a good idea to <a
href="http://ayende.com/Blog/archive/2009/03/20/nhibernate-avoid-identity-generator-when-possible.aspx">avoid identity-style identifier strategies</a> with ORM's.  One of the better alternatives that i kinda like is the guid.comb strategy.  Using regular guids as a primary key value leads to fragmented indexes (due to the randomness of the guid's value) which leads to bad performance.  This is a problem that the guid.comb strategy can solve quite easily for you.</p><p>If you want to learn how the guid.comb strategy really works, be sure to check out <a
href="http://www.informit.com/articles/article.aspx?p=25862">Jimmy Nilsson's article on it</a>. Basically, this strategy generates sequential guids which solves the fragmented index issue.  You can generate these sequential guids in your database, but the downside of that is that your ORM would still need to insert each record seperately and fetch the generated primary key value each time.  NHibernate includes the guid.comb strategy which will generate the sequential guids before actually inserting the records in your database.</p><p>This obviously has some great benefits:</p><ul><li>you don't have to hit the database immediately whenever a record needs to be inserted</li><li>you don't need to retrieve a generated primary key value when a record was inserted</li><li>you can batch your insert statements</li></ul><p>Let's see how we can use this with NHibernate.  First of all, you need to map the identifier of your entity like this:</p><div><pre class="brush: xml; title: ; notranslate">
    &lt;id name=&quot;Id&quot; column=&quot;Id&quot; type=&quot;guid&quot; &gt;
      &lt;generator class=&quot;guid.comb&quot; /&gt;
    &lt;/id&gt;
</pre></div><p>And that's actually all you have to do.  You don't have to assign the primary key values or anything like that.  You don't need to worry about them at all.</p><p>Take a look at the following test:</p><div><pre class="brush: csharp; title: ; notranslate">
        [Test]
        public void InsertsAreOnlyExecutedAtTransactionCommit()
        {
            var insertCountBefore = sessionFactory.Statistics.EntityInsertCount;
 
            using (var session = sessionFactory.OpenSession())
            using (var transaction = session.BeginTransaction())
            {
                for (int i = 0; i &lt; 50; i++)
                {
                    var category = new ProductCategory(string.Format(&quot;category {0}&quot;, i + 1));
                    // at this point, the entity doesn't have an ID value yet
                    Assert.AreEqual(Guid.Empty, category.Id);
                    session.Save(category);
                    // now the entity has an ID value, but we still haven't hit the database yet
                    Assert.AreNotEqual(Guid.Empty, category.Id);
                }
 
                // just verifying that we haven't hit the database yet to insert the new categories
                Assert.AreEqual(insertCountBefore, sessionFactory.Statistics.EntityInsertCount);
                transaction.Commit();
                // only now have the recors been inserted
                Assert.AreEqual(insertCountBefore + 50, sessionFactory.Statistics.EntityInsertCount);
            }
        }
</pre></div><p>Interesting, no? The entities have an ID value after they have been 'saved' by NHibernate.  But they haven't actually been saved to the database yet though.  NHibernate always tries to wait as long as possible to hit the database, and in this case it only needs to hit the database when the transaction is committed.  If you've enabled <a
href="http://davybrion.com/blog/2008/10/batching-nhibernates-dm-statements/">batching of DML statements</a>, you could severly reduce the number of times you need to hit the database in this scenario.</p><p>And in case you're wondering, the generated guids look like this:</p><p>81cdb935-d371-4285-9dcb-9bdb0122f25f<br/> a44baf99-58e9-4ad7-9a59-9bdb0122f25f<br/> a88300c2-6d64-4ae3-a55b-9bdb0122f25f<br/> 032c7884-da2f-4568-b505-9bdb0122f25f<br/> ....<br/> 70d7713c-b38d-4341-953d-9bdb0122f25f<br/></p><p>Notice the last part of the guids... this is what prevents the index fragmentation.</p><p>Obviously, this particular test is not a realistic scenario but i'm sure you understand how much of an improvement this identifier strategy could provide throughout an entire application.  The only downside (IMO) is that guid's aren't really human readable so if that is important to you, you should probably look into other identifier strategies.  The HiLo strategy would be particularly interesting in that case, but we'll cover that in a later post <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F05%2Fusing-the-guidcomb-identifier-strategy%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2009/05/using-the-guidcomb-identifier-strategy/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2009/05/using-the-guidcomb-identifier-strategy/"  data-text="Using The Guid.Comb Identifier Strategy" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2009/05/using-the-guidcomb-identifier-strategy/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2009/05/using-the-guidcomb-identifier-strategy/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2009/05/using-the-guidcomb-identifier-strategy/feed/</wfw:commentRss> <slash:comments>11</slash:comments> </item> <item><title>Put Performance Concerns Into Perspective</title><link>http://davybrion.com/blog/2009/04/put-performance-concerns-into-perspective/</link> <comments>http://davybrion.com/blog/2009/04/put-performance-concerns-into-perspective/#comments</comments> <pubDate>Sat, 18 Apr 2009 14:58:03 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Performance]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=1318</guid> <description><![CDATA[There is a reported performance issue with NHibernate that i wanted to look into. The reported issue was related to retrieving objects through a generically typed List or through an IList reference. The following code simulates the issue: &#160;&#160;&#160; class MyClass {} &#160; &#160;&#160;&#160; class Program &#160;&#160;&#160; { &#160;&#160;&#160; &#160;&#160;&#160; static void Main(string[] args) &#160;&#160;&#160; [...]]]></description> <content:encoded><![CDATA[<p>There is a reported <a
href="http://nhjira.koah.net/browse/NH-1079">performance issue</a> with NHibernate that i wanted to look into.  The reported issue was related to retrieving objects through a generically typed List or through an IList reference.</p><p>The following code simulates the issue:</p><p><code><style type="text/css">.cf{font-family:Consolas;font-size:9pt;color:black;background:white}.cl{margin:0px}.cb1{color:blue}.cb2{color:#2b91af}.cb3{color:#a31515}</style></p><div
class="cf"><p
class="cl">&nbsp;&nbsp;&nbsp; <span
class="cb1">class</span> <span
class="cb2">MyClass</span> {}</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; <span
class="cb1">class</span> <span
class="cb2">Program</span></p><p
class="cl">&nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">static</span> <span
class="cb1">void</span> Main(<span
class="cb1">string</span>[] args)</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb2">List</span>&lt;<span
class="cb2">MyClass</span>&gt; list = <span
class="cb1">new</span> <span
class="cb2">List</span>&lt;<span
class="cb2">MyClass</span>&gt;();</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb2">Stopwatch</span> stopwatch = <span
class="cb2">Stopwatch</span>.StartNew();</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">for</span> (<span
class="cb1">int</span> i = 0; i &lt; 100000; i++)</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; list.Add(<span
class="cb1">new</span> <span
class="cb2">MyClass</span>());</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; stopwatch.Stop();</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb2">Console</span>.WriteLine(<span
class="cb3">&quot;Elapsed ms: &quot;</span> + stopwatch.ElapsedMilliseconds);</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb2">IList</span> iList = <span
class="cb1">new</span> <span
class="cb2">List</span>&lt;<span
class="cb2">MyClass</span>&gt;();</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; stopwatch = <span
class="cb2">Stopwatch</span>.StartNew();</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">for</span> (<span
class="cb1">int</span> i = 0; i &lt; 100000; i++)</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; iList.Add(<span
class="cb1">new</span> <span
class="cb2">MyClass</span>());</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; stopwatch.Stop();</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb2">Console</span>.WriteLine(<span
class="cb3">&quot;Elapsed ms: &quot;</span> + stopwatch.ElapsedMilliseconds);</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb2">Console</span>.ReadLine();</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>The only difference between both Add operations is that in the first case, the typed Add method of the generically typed List reference is called.  In the second case, the untyped Add method of the generically typed List is called through the IList reference.</p><p>On my slow Macbook, the first Add operation typically took between 10 and 20 ms.  The second Add operation typically took almost twice as long as the first Add operation.  As you can see, that is a very minor performance issue, and it actually is only consistently noticeable once you're dealing with 100000 elements.  At 50000 elements, both operations typically take the same amount of time with only minor variations in performance on certain runs.</p><p>So yes, once you're dealing with a large enough set of elements, there is indeed a performance difference.  But it's extremely minor and the extra cost of the Add operation is most definitely <strong>the least of your concerns if you're retrieving that many entity instances through an ORM.</strong> The extra amount of memory that needs to be used for those entities and the extra cost of pulling all of that data over the wire is what's really going to bite you, not the extra cost of the Add operation <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F04%2Fput-performance-concerns-into-perspective%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2009/04/put-performance-concerns-into-perspective/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2009/04/put-performance-concerns-into-perspective/"  data-text="Put Performance Concerns Into Perspective" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2009/04/put-performance-concerns-into-perspective/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2009/04/put-performance-concerns-into-perspective/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2009/04/put-performance-concerns-into-perspective/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Transparent Query Batching Through Your Repository</title><link>http://davybrion.com/blog/2009/04/transparent-query-batching-through-your-repository/</link> <comments>http://davybrion.com/blog/2009/04/transparent-query-batching-through-your-repository/#comments</comments> <pubDate>Wed, 01 Apr 2009 11:35:52 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[NHibernate]]></category> <category><![CDATA[Performance]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=1200</guid> <description><![CDATA[All of our projects that use NHibernate (which is all of them except those where the customer explicitly doesn't want us to use it or where it wouldn't make sense to use it) use the same Repository implementation. After the Future and FutureValue queries were added to NHibernate, i modified the implementation of that Repository [...]]]></description> <content:encoded><![CDATA[<p>All of our projects that use NHibernate (which is all of them except those where the customer explicitly doesn't want us to use it or where it wouldn't make sense to use it) use the same <a
href="http://davybrion.com/blog/2008/06/data-access-with-nhibernate/">Repository implementation</a>.  After the <a
href="http://davybrion.com/blog/2009/01/nhibernate-and-future-queries/">Future</a> and <a
href="http://davybrion.com/blog/2009/01/nhibernate-and-future-queries-part-2/">FutureValue</a> queries were added to NHibernate, i modified the implementation of that Repository class.</p><p>Two of the FindAll methods now look like this:</p><div><pre class="brush: csharp; title: ; notranslate">
        public virtual IEnumerable&lt;T&gt; FindAll()
        {
            return Session.CreateCriteria&lt;T&gt;().Future&lt;T&gt;();
        }
 
        public virtual IEnumerable&lt;T&gt; FindAll(DetachedCriteria criteria)
        {
            return criteria.GetExecutableCriteria(Session).Future&lt;T&gt;();
        }
</pre></div><p>The only thing i changed in those methods is calling the Future method, instead of the List method.  That's it.  All of our specific Find-methods (those that execute specific queries) pass through the FindAll(DetachedCriteria criteria) method so they all benefit from this change.</p><p>That means that all of our queries are suddenly batched transparently whenever possible, without impacting any of the calling code.  And that is pretty nice if you ask me.  Batching queries can offer a substantial performance benefit, and we didn't even have to change any of the calling code to achieve it.</p><p>Obviously, this only works for the queries that return IEnumerables (in our case, that's every query that doesn't return a single value).  I also added a few more methods to enable query batching for queries that return a single entity, or a scalar value (i kept the original methods in this code snippet as well so you can see the difference):</p><div><pre class="brush: csharp; title: ; notranslate">
        public virtual T FindOne(DetachedCriteria criteria)
        {
            return criteria.GetExecutableCriteria(Session).UniqueResult&lt;T&gt;();
        }
 
        public virtual IFutureValue&lt;T&gt; FindFutureOne(DetachedCriteria criteria)
        {
            return criteria.GetExecutableCriteria(Session).FutureValue&lt;T&gt;();
        }
 
        public virtual K GetScalar&lt;K&gt;(DetachedCriteria criteria)
        {
            return (K)criteria.GetExecutableCriteria(Session).UniqueResult();
        }
 
        public virtual IFutureValue&lt;K&gt; GetFutureScalar&lt;K&gt;(DetachedCriteria criteria)
        {
            return criteria.GetExecutableCriteria(Session).FutureValue&lt;K&gt;();
        }
 
        public virtual int Count(DetachedCriteria criteria)
        {
            return Convert.ToInt32(QueryCount(criteria).GetExecutableCriteria(Session).UniqueResult());
        }
 
        public virtual IFutureValue&lt;int&gt; FutureCount(DetachedCriteria criteria)
        {
            return QueryCount(criteria).GetExecutableCriteria(Session).FutureValue&lt;int&gt;();
        }
</pre></div><p>So let's recap.  Queries that return IEnumerables are all batched transparently whenever it's possible to do so.  No calling code had to be modified to get this benefit.  Queries that return single values (an entity instance or a scalar value) that still use the 'old' FindOne, GetScalar and Count methods obviously couldn't benefit from the transparent batching without breaking backwards compatibility, but the new methods that were introduced do enable transparent batching for these queries from now on.</p><p>Does all of this sound too good to be true? I'd be skeptic too if i were you but i made these changes a few months ago actually and we have been using this stuff on a couple of projects with zero problems.</p><p>Obviously, you need NHibernate 2.1 Alpha 1 (or later) for this or the current trunk, both of which i would recommend over NH 2.0 at this point.</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F04%2Ftransparent-query-batching-through-your-repository%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2009/04/transparent-query-batching-through-your-repository/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2009/04/transparent-query-batching-through-your-repository/"  data-text="Transparent Query Batching Through Your Repository" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2009/04/transparent-query-batching-through-your-repository/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2009/04/transparent-query-batching-through-your-repository/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2009/04/transparent-query-batching-through-your-repository/feed/</wfw:commentRss> <slash:comments>15</slash:comments> </item> <item><title>Performance Rules Of Thumb</title><link>http://davybrion.com/blog/2009/02/performance-rules-of-thumb/</link> <comments>http://davybrion.com/blog/2009/02/performance-rules-of-thumb/#comments</comments> <pubDate>Sun, 15 Feb 2009 20:44:45 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Performance]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=922</guid> <description><![CDATA[A lot of developers deal with performance differently. Some care too much, trying to optimize every single piece of code they write. Some care too little, not thinking about performance at all until it is proven to be a problem. I think both of these approaches suck and usually try to find a healthy balance [...]]]></description> <content:encoded><![CDATA[<p>A lot of developers deal with performance differently.  Some care too much, trying to optimize every single piece of code they write.  Some care too little, not thinking about performance at all until it is proven to be a problem.  I think both of these approaches suck and usually try to find a healthy balance between them.</p><p>Below is a list of rules of thumb that i always try to keep in mind.  Keep in mind that these are just rules of thumb... they are not rules that never should be broken, nor are they applicable to each and every situation.  In general though, i do believe that if you keep these in mind you can avoid serious performance issues and the need to do heavy architectural refactoring in the long run.  So without further ado, these are the performance-related things that i do care about while i'm writing my code:</p><ul><li><strong>Be careful with anything that goes out of process</strong> (web/wcf service calls, database calls, external systems/components, ...).  The cost of these calls is often higher than you'd imagine and might not become noticeable until the load on your system increases, or when you start executing these calls in long loops.</li><li><strong>Fetch your data in a smart manner</strong>... Never retrieve data in a loop, but retrieve it outside of the loop in a more coarse-grained manner.  Sometimes it makes sense to use some joins to retrieve data, but in other cases you're better off with executing separate queries to avoid retrieving large Cartesian products.  If your data layer implements caching in some way, use it in a smart manner</li><li><strong>Dispose objects that need it as soon as possible</strong>...  Not doing this could lead to costly dangling resources and/or memory leaks... if this eventually leads to swapping/paging you end up with abysmal performance</li><li><strong>Don't transfer more data than you need to</strong>.  Whether you're sending data over a service or you're pushing HTML to a browser, your total bandwidth and/or the client's download speed is usually limited so this could lead to slowdowns that you can often avoid.  Note that i don't recommend making everything as compact as possible, but a little bit of common sense can go a long way here.</li><li><strong>Don't go crazy with multi-threading and asynchronous operations</strong>.  While these can generally help a lot when it comes to responsiveness (and thus, the perceived 'slowness' of your application) they aren't always the perfect solution.  I once saw an 'architect' run a data import process (which had to insert that data in a remote database) over 64 threads, because it was too slow in one thread.  He was surprised to see that his 64-thread solution wasn't faster than his single-threaded version.  I wasn't surprised at all... I suggested getting rid of the multi-threading and to batch the insert statements, which improved the situation greatly.</li><li><strong>Don't hold on to large sets of data for too long</strong>.  A large set of data could be a lot of database records, but it could just as well be a lot of strings, or just other objects in general.  Keeping these in memory for a long time prevents them from being garbage collected as soon as they can be, which can greatly increase memory pressure in your system.  Be especially careful with long-running loops that iterate over large sets of data.  If you no longer need the data after you've left the loop, you're often better off getting rid of each item in the set as you're done processing it.</li></ul><p>And that's pretty much it... outside of the stuff listed above, i typically don't care about performance.  I try to keep my code clean and focused, and rely on profiling to identify performance hotspots.  When the profiler identifies problems, they are often more easy to solve if you've kept your code clean than it would be if you had tried to prematurely optimize in the wrong places.</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F02%2Fperformance-rules-of-thumb%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2009/02/performance-rules-of-thumb/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2009/02/performance-rules-of-thumb/"  data-text="Performance Rules Of Thumb" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2009/02/performance-rules-of-thumb/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2009/02/performance-rules-of-thumb/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2009/02/performance-rules-of-thumb/feed/</wfw:commentRss> <slash:comments>10</slash:comments> </item> <item><title>Batching Remote Operations Is Not Premature Optimization</title><link>http://davybrion.com/blog/2008/12/batching-remote-operations-is-not-premature-optimization/</link> <comments>http://davybrion.com/blog/2008/12/batching-remote-operations-is-not-premature-optimization/#comments</comments> <pubDate>Fri, 12 Dec 2008 22:14:09 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Opinions]]></category> <category><![CDATA[Performance]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=702</guid> <description><![CDATA[I spent a day at Devoxx (formerly known as Javapolis) this week, and one of the presentations i saw was about common performance anti-patterns, given by Alois Reitbauer from DynaTrace. While i didn't really hear anything new during the presentation, i did kinda like how the speaker stressed that while premature optimization is indeed evil, [...]]]></description> <content:encoded><![CDATA[<p>I spent a day at <a
href="http://www.devoxx.com/display/JV08/Home">Devoxx</a> (formerly known as Javapolis) this week, and one of the presentations i saw was about common performance anti-patterns, given by <a
href="http://blog.dynatrace.com/author/alois-reitbauer/">Alois Reitbauer</a> from <a
href="http://www.dynatrace.com/en/">DynaTrace</a>.  While i didn't really hear anything new during the presentation, i did kinda like how the speaker stressed that while premature optimization is indeed evil, certain things simply don't belong in that category and are things you should definitely keep an eye on throughout the development of your projects.</p><p>Those of you who've been reading this blog for a while know that i've often stressed the <a
href="http://davybrion.com/blog/2008/06/the-query-batcher/">importance</a> <a
href="http://davybrion.com/blog/2008/08/batching-sqlcommand-queries/">of</a> <a
href="http://davybrion.com/blog/2008/06/batching-wcf-calls/">reducing</a> <a
href="http://davybrion.com/blog/2008/07/batching/">the number</a> <a
href="http://davybrion.com/blog/2008/09/the-select-command-batcher/">of</a> <a
href="http://davybrion.com/blog/2008/10/batching-nhibernates-dm-statements/">remote</a> <a
href="http://davybrion.com/blog/2008/11/why-on-earth-would-a-developer-do-this/">calls</a>.  Yeah that's right, i just linked to 7 of my own posts in a single sentence :p</p><p>Anyways, there were a few people who thought that my preference for batching queries/service calls was actually a case of premature optimization, and that it was therefor evil and not something you should be doing until it was actually necessary to do so.  The speaker of the presentation explained that there is a difference between premature optimization and pro-active performance management.  Performance and scalability simply do not come for free, and you have to keep certain things in mind if you want your system to have those qualities.</p><p>Now, before i go further, i would like to state that i do believe that clean, simple and reusable code is something that developers should always strive for.   I also believe that you should try to limit the number of times you hit the database, or the number of remote service calls you make in a single business transaction.  Those goals often seem to contradict each other.  There aren't too many data access layers that allow you to easily perform multiple queries in a single roundtrip while still making sure that each query is reusable in a different context.  It gets even worse when it comes to remote services.  As you undoubtedly know, a lot of industry experts will recommend that you provide coarse-grained service interfaces instead of fine-grained service interfaces.  The upside of coarse-grained interfaces is that they often offer better performance due to less chattiness in communication.  Unfortunately, it also often also leads to services that are <strong>implicitly</strong> coupled against the clients that are known to be using them.  With that i mean that many of those coarse-grained services are designed with certain client-characteristics in mind.  And shouldn't services be independent of the clients that use them?  This approach typically has an impact on the reusability of those services for clients which are to be developed after the service has already been deployed.</p><p>So how do we solve these issues? It's pretty simple.  I want each database query to be reusable in whatever way i need: combined with other queries in a single roundtrip, or executed separately.  I also want a fine-grained service interface where i can execute precisely the 'remote action' i need, and avoid the chattiness when i need to execute several of those 'remote actions' in a single business transaction.  The answer is of course: batching of remote operations, whether they are database queries or remote service calls or whatever else that essentially boils down to an out-of-process call.</p><p>I really think that every kind of architecture should at least make this reasonably easy to do so.  It really doesn't take that much effort (or in some cases i'd even call it imagination) to make all of this possible. I'm actually pretty lazy so if i can manage to get it done, there's no reason in the world why you shouldn't.  It can be done pretty easily, and it really doesn't come with that much of a cost.  Of course, writing your code this way takes a little bit more work than doing it the 'easy way' (little more being 'minutes' vs 'hours' though).  But then again, if the 'easy way' were the right way, we wouldn't even be talking about performance anti-patterns, right?</p><p>For me personally, i've gotten to the point where i really couldn't care less about possibly slow performing code in advance, as long as that code is executed in-process.  No matter how good you are, you will practically always guess wrong when it comes to slow-performing in-process code.  Just write clean and readable code and if some parts of it turn out to be slow, you just use a profiler and it will quickly tell you which parts are causing the slowdowns.  It's pretty much always the last place you suspect so why bother writing difficult code for parts that probably weren't going to be a problem anyway.   But for out-of-process stuff: be vigilant, because any performance problem related to it could have easily been avoided from the start.</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2008%2F12%2Fbatching-remote-operations-is-not-premature-optimization%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2008/12/batching-remote-operations-is-not-premature-optimization/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2008/12/batching-remote-operations-is-not-premature-optimization/"  data-text="Batching Remote Operations Is Not Premature Optimization" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2008/12/batching-remote-operations-is-not-premature-optimization/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2008/12/batching-remote-operations-is-not-premature-optimization/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2008/12/batching-remote-operations-is-not-premature-optimization/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Database Caching 2/74 queries in 0.046 seconds using disk: basic
Object Caching 1614/1765 objects using disk: basic
Content Delivery Network via Amazon Web Services: CloudFront: d18sni7re4ly7f.cloudfront.net

Served from: davybrion.com @ 2012-02-07 08:22:11 -->
