How method length Affects performance in .net

Several months ago I was having a discussion (that’s a polite word for argument) with a few co-workers about the optimal length of methods and the topic of performance came up.

Someone with a C++ background brought up the point that shorter methods were less efficient than longer ones due to the extra cost of more V-Table lookups.

At the time, I countered that the performance differences were surely minimal and that the trade-off was justifiable when taking into account the maintainability benefits of shorter methods (increased readability, decreased chance of bugs, etc.).

However, I recently discovered while reading a chapter in Bill Wagner’s Effective C# book that this seemingly common-sense assertion about the way method length affects performance is not necessarily true in the .NET world.

The primary reason has to do with how JIT compilation works, which is another round of compilation that occurs at runtime in order to transform code from IL to machine language.

In order to amortize the startup cost over the life of an application, the CLR compiles code on a method by method basis the first time it is used.

The ultimate result is that longer methods may slow down an application by requiring code to be prematurely compiled before it is actually used.

Consider the following example:

   1: public void DoFunStuff(bool isBossPresent)
   2: {
   3:     if (isBossPresent)
   4:     {
   5:         //do 50 lines worth of crazy shit inline
   6:     }
   7:     else
   8:     {
   9:         //do 50 lines of tamer stuff
  10:     }
  11: }

Regardless of what parameter is passed to the method, all 100+ lines of code will have to be JIT compiled the first time the method is used.

Now consider this refactored version:

   1: public void DoFunStuff(bool isBossPresent)
   2: {
   3:     if (isBossPresent)
   4:     {
   5:         DoCrazyShit();
   6:     }
   7:     else
   8:     {
   9:         DoRelativelyTameStuff();
  10:     }
  11: }

The first time this version of the method is called, the JIT compilation process will be faster because only half as many lines of code need to be compiled.

If true is passed in to this method as a parameter then the CLR will compile everything under the DoCrazyShit method, but will delay compiling the DoRelativelyTameStuff method until the DoFunStuff method is called with a false parameter.

Reducing the number of lines of code that need to be compiled is not the only benefit of shorter methods.

Small, simple methods also facilitate the use of other performance boosting techniques like enregistration (storing variables in the register instead of on the stack) and method inlining (substituting method calls for the implementation).

The moral of the story? Keep the JIT compiler, impatient users, and fellow developers who have to maintain your crap after you retire to some tropical island happy. Keep your methods short!

Popularity: 3% [?]

No related posts.

Book Review: Working Effectively with Legacy Code

LegacyCode_blog I’m only a little behind in reading for my 2010 developer-oriented book reading list, but I seem to be falling quite a bit behind in actually writing up book reviews. Here’s a belated review from my May book, Working Effectively With Legacy Code by Michael Feathers.

I chose this book because I had heard people rave about it years, so I went in with pretty high expectations.

Although I wasn’t quite as smitten by the book as I had hoped, I did find enough value in it to give a presentation based on the concepts and strategies featured in it at the Kansas City Developer’s Conference a few months ago. You can download my slides and sample code here.

Rating - star_sm star_smstar_sm (out of 5)

Prerequisites

  1. You’re interested in TDD (or even just unit testing) – It’s important to note that the author defines legacy code as any code that doesn’t already have tests covering it and that all the strategies presented in the book are aimed at helping you make code more testable. You definitely don’t need much experience or expertise in TDD to benefit from the book, but if you’re philosophically opposed to TDD then this isn’t the book for you.
  2. You’re comfortable with multiple languages – Examples in this book are in C#, C, C++, Java, and Ruby. If you’re not comfortable looking at samples in these languages or it feels like a waste of time deciphering code that you don’t use in your day to day work environment, then you’ll be frustrated with this book.
  3. You understand and use an object oriented language – Although Michael Feathers covers a few non-OO techniques, such as linking and preprocessing based test seams, the vast majority of the techniques rely upon object oriented language features such as inheritance and interfaces. If you spend all of your time working with a procedural language, I would recommend just reading the few relevant pages in the book store rather than investing much time and money in this book.

The Good

  1. Conceptual Scaffolding – The author introduces a few incredibly helpful concepts, test seams and enabling points, which serve as scaffolding for the entire book. This scaffolding technique is incredibly effective in helping readers digest and remember the material and the author deserves high praise for having done this so well.
  2. Pragmatic Approach – Anyone who spends much time maintaining a legacy system has a healthy disdain for unfettered idealism. Michael provides a helpful and realistic assortment of techniques that allow you to iterate a design in a safe and timely manner. He freely admits that a few of his techniques should only be used as an intermediate step to help facilitate getting some initial tests in place, but that doesn’t make them any less useful.
  3. The Power of Naming – Many of the techniques described in the book were familiar to me because I had naturally stumbled upon them myself while trying to put the code I work with everyday under test. Just like with the Gang of Four’s Design Pattern book or Martin Fowler’s Refactoring book, the real value of this book is not in how innovative it is but rather in how meticulous it catalogs and names existing patterns, thus providing a common language for developers to more effectively collaborate on design issues related to testability.

The Bad

  1. Not Very Original in Places – Several chapters in the middle of the book seemed like generic repeats of some of Bob Martin’s SOLID material or Martin Fowler’s Refactoring techniques. If you’ve read those books before, then you’re bound to be a little disappointed like I was when you reach those parts of the book. 

Mixed Feelings

  1. No Use of Mocking Frameworks – Part of me really appreciates the fact that the author did not use any mocking frameworks in the book. Before reading the book, mocking frameworks seemed like magic to me, but now I feel like I have a pretty good idea of how I would implement one from scratch (if I ever wanted to) because I now clearly understand all the different ways to substitute functionality dynamically. It’s actually very simple stuff, I just never took the time to think about it before. On the other hand, not covering the use of a mocking framework in the book also means that someone new to unit testing is going to be ill-equipped to productively enter the world of TDD, where mocking frameworks are pretty much a given these days.

Conclusion – . Despite being slightly disappointed by the book due to some extremely high expectations I still think that this book fills an important knowledge void (how to make legacy code testable) and thus belongs on any developer’s top 10 must-read list.

Popularity: 1% [?]

Related posts:

Going Down the CQS Rabbit Hole

A few weeks ago I attended a rather thought provoking presentation by Udi Dahan on the Command-Query Segregation Principle.

If you’re like me, then you might have confused this newer architectural principle with the other CQS (Command Query Separation), which is the classic OOP design principle that I wrote about in a recent post.

The story goes that Martin Fowler tried to warn Udi and his cohorts that this confusion would occur when they first coined this term, but they decided to stubbornly stick to the term because it described the the architectural approach so perfectly.

The driving force behind CQS is simply the belief that many of the scaling and complexity woes exhibited by the vast majority of systems today can be traced to the misguided effort to unify commands and queries into a single conceptual model.

The thought goes that once you truly break apart these divergent activities and try to solve each problem independently, then some innovative and sometimes even blasphemous ideas start to emerge.

If you’ve never heard Udi talk on the subject, then I recommend reading this fairly concise article on it.

Here is my interpretation of some of the more thought provoking points that I remember from the talk:

Query-Side

  • This should be a read-only, de-normalized data-store with built-in latency that is separate from the command (transactional) data store.
  • Data should be not only de-normalized, duplicated, and aggregated as needed, but also stored in the exact same format required by views. This will eliminate the need for DTO’s and the usual array of transformations that occur on the way from the data layer to the UI layer.
  • Defining acceptable latency is key. Data should be organized according to acceptable staleness thresholds. Data may be duplicated many times to account for the fact that different pages usually have different tolerances for latency.
  • Since data is flattened out completely there is no need for any relations, which also means that RDMS is probably not nearly as ideal as one of the NoSQL databases.
  • Since these data stores only need read-only permissions, why do they need to be on a separate server behind the firewall? Udi points out that putting a document database on a web server that is in front of the firewall is actually more secure than using a caching solution. I can’t wait to have that conversation with our network guys and the PCI auditors…

Command-Side

  • Commands should all be asynchronous. This means you fire off the command and immediately return with a message to the user saying that they’ll be notified when the transaction has been processed. It’s amazing how many things really don’t need to be synchronous when you stop to think about them. Udi makes the point that the world got along perfectly fine (and in some cases better) when it ran on paper, which is intrinsically an asynchronous process.
  • Asynchronous is a better user experience. Is it really necessary to make 99.9% of the people wait an extra 10-15 seconds just because there is a slight chance that something may go wrong? Isn’t it a better user experience to handle the exceptional case manually or by having the user revisit the website to fix the problem?
  • To be asynchronous, UI’s must capture intent instead of just being dumb data entry screens. In a classic ticketing system, a user has to select the exact seats he or she wants and then retry multple times because at least one of the seats was taken by another user since the screen first loaded. In the CQS model, the user would simply specify that they wanted five seats near each other that were all within a certain price range and then the system would later send out a notification with the results after sufficient requests were accepted and a packing algorithm was run to satisfy the highest number of requests possible.
  • More onus is now placed upon the UI to ensure commands are valid and have a high probability of success. Once again, it is perfectly acceptable and cost efficient to handle the infrequent cases of failures by putting them in a manual intervention queue and even having a customer service person contact them.
  • Asynchronous through a queuing mechanism like MSMQ is much more reliable and probably the only way to meet most SLA’s (Service Level Agreements).
  • Each command should be totally independent (think separate VS solutions) so that they can be versioned separately. Udi refers to the benefits of reuse as largely a fallacy and the enemy of flexible versioning.
  • Since domain models no longer have to support queries, there is no need for the web of relationships that usually just reflects the RDMS. Entities should only contain what is needed to support the command and can be duplicated across commands.

Here’s a diagram of this model from the paper I linked to at the top:

CQS

In conclusion, this is definitely one of the most thought provoking talks I’ve ever attended.

I’ve already lobbied my boss to send as many people as possible to attend Udi’s training, which covers this topic in much more depth.

I’ve also pushed the task of investigating projects like NServiceBus and MassTransit to the top of my list.

Most of these suggestions are too radical to immediately act upon, but I have to admit that I’m sold on the concepts.

Popularity: 1% [?]

No related posts.

Book Review: Ruby For Rails

RubyForRails.I just finished my April book from my 2010 developer-oriented book reading list, so I thought I would share some thoughts on Ruby For Rails by David Black.

In my last book review post, I mentioned that I was going to finally tackle functional programming this last month with Real World Functional Programming: With Examples in F# and C#. However, my wife sweet-talked me into doing a bunch of enhancements on her Rails site so I changed plans at the last minute so that my reading topic would mesh better with my programming activities.

Rating - star_sm star_sm 1/2 (out of 5)

Prerequisites – As long as you have a basic grasp of OO programming and web development, you shouldn’t have any trouble understanding the content of this book..

The Good

  1. Explains the “Black Magic” behind Rails – Rails is a high level DSL built on a language that offers some unique dynamic features along with a wide array of syntactic sugar. The result is that it’s usually difficult for most new comers to grok what is going on behind the scenes. By devoting so much space to Ruby, the author answers questions that most Rails-centric books ignore.
  2. Effective book structureThe book is broken up into thirds: An brief intro to the Rails framework; a section on Ruby fundamentals; and an more in-depth exploration of Rails. This conceptual ordering is an effective teaching strategy because it first builds up your interest in the framework, then gives you the tools to parse and grok what is happening, and finally provides you with the chance to dig into some more substantial examples.
  3. In-depth approach to topics – I suspect this book focuses more on subtleties than the average ‘how to’ book. For example, the author concocts a rather convoluted example in the chapter on Modules and Program Organization where methods are redefined in various combinations of derived classes and mixed-in modules in order to demonstrate the precise order of method lookup.

The Bad

  1. Not the fastest way to get started with Rails – This was actually my second attempt at reading this book. I first started reading it a couple of years ago, but then abandoned it after few hundred pages in favor of Agile Web Development with Rails, which was much more geared towards getting you to develop realistic apps in Rails quickly. At that point, I had a Rails project lined up and was anxious to get started, so I found the extensive focus on Ruby and in-depth explanations to be frustrating. This time around I was much more interested in gaining a deeper understanding of the framework, so it wasn’t an issue.
  2. Overly Academic Examples – Although the chapter on meta-programming was informative, I was a little frustrated by the end because it rarely went into any details of exactly how these features were utilized to do cool stuff in Rails. I understand that simple academic type examples are sometimes the best way to illustrate a concept, however without the inspiring examples it’s hard to get excited about a language feature.
  3. Target audience too broad – This book had the potential to be a really good intermediate book, but it fell far short because of all of the introductory material interspersed with the advanced nuggets. As a result, I almost missed some of the key ways in which Ruby is different from C# and Java when it comes to object orientation because I fell into skim mode out of boredom. The author should have targeted just an intermediate audience and focused specifically on how Ruby differed from most other object oriented languages.
  4. Writing style not concise – With the exception of the chapter on Regular Expressions, the book seriously lacked in editorial discipline. This really could have easily been remedied by any editor, so I fault Manning for this one. It definitely knocked a star off of my rating because I was so frustrated with redundant passages that added little value, especially in the intro and summary.

Conclusion – Definitely don’t choose this as your first intro to Rails if your goal is to be productive in the framework quickly. In that case, I suggest picking up a copy of Agile Web Development with Rails.

However, if you’re already somewhat familiar with the framework and are much more interested in figuring out the mechanics behind Rail’s unusual constructs (and don’t mind skimming through some introductory material and wordiness), then this book is definitely a worthwhile read.

Popularity: 1% [?]

Related posts:

Website Hall of Shame

Today’s featured website: European Visa Online

I visited this site for the first time today and was greeted with this page.

blog_visa_shame

Seriously?

In case you’re curious, I’m running firefox 3.6.3.

Web developers and designers have scorned and mocked IE 6 for years now due to hoards of bugs and non-compliant behavior that cause endless development headaches.

However, IE 6 rose to a new level of infamy earlier this year when it turned out to be the culprit behind the Operation Aurora exploits, which led to Google and others to officially drop support for the browser due to security risks.

It also led to many European governments, such as Germany, France, and nearly the UK, to officially urge its citizens to switch browsers.

That made this page all the more surprising since it came from the European branch of Visa.

Then again, maybe I shouldn’t be surprised.

One of the very next pages prevented me from changing my initial password because the password generated by KeePass with the default settings was too long….that’s right….too long to meet their password validation rules.

visa_strike4

I easily have over 100 passwords in my password database and I can’t remember the last time I’ve had this problem.

It doesn’t exactly inspire confidence in the area of security, especially considering that Visa is one of the most prominent and ubiquitous financial institution around.

Sigh…

Popularity: 12% [?]

No related posts.

Heroku: Hosted Application Deployment Done Right

A couple of months ago, I had to scramble to find a new hosting company for my wife’s ecommerce site that I had built on Rails.

My former hosting company performed a rather disastrous major upgrade and “move to the cloud” with no workable back-out plan and little expertise in Rails. The end result was that they were forced to officially drop support for Rails apps after three days worth of failed attempts to make it work.

Although Rails is arguably one of the easier platforms to develop on, it is apparently much more difficult to deal with from a hosting perspective.

It didn’t help matters that I was the only customer they had who was actually using Rails (I didn’t find this out until the end). It’s little wonder that they had no expertise in the area and little financial incentive to remedy the situation.

When I set out to find a new hosting company, my first order of business was to find someone with lots of experience hosting Rails apps.

With over 58,000 apps in production (at least according to the marketing hype), Heroku.com definitely met my criteria. Of course, it didn’t hurt that they host sites with simple configuration needs like my own for free.

After several months of using it, I’ve got nothing but positive things to report.

While low cost and high expertise are definitely still huge selling points for me, I think I am most impressed with the deployment story.

Thanks to a nifty heroku gem, I can now deploy my application by simply issuing a few commands after doing a commit to my git repository.

To deploy code, I use the heroku gem in combination with a simple git push.

heroku_push

For database changes, I use the gem to execute my newly committed migration files against my remote database.

   1: C:\> heroku rake db:migrate

I love that I can now do a full deployment without ever leaving my command window.

My old hosting site required me to open an ftp program and a browser and then spend dozens of clicks in order to manually select what I want to upload and execute.

Besides being incredibly tedious, the chance for error was significant.

I have to admit that it is occasionally disconcerting not to have direct access to view the files or data (although plugins and commands exist to download the current version of both). However, this streamlined deployment process makes it totally worth it. It’s a perfect case of appropriately optimizing for the 95% usage scenario.

The only heroku requirement that ended up costing me any work during the migration process was on the database side, since Heroku requires PostgreSQL and my app was running on MySQL.

I have to admit that I almost abandoned my plans when I first found out that it would require switching databases, but I was pleasantly surprised at how little work was actually involved thanks to the level of abstraction offered by ActiveRecord and Migrations.

I think I only ended up making about a dozen code changes to my various queries and it turned out that all of those could have been avoided if I had been smarter about how I formed the queries (not embedding boolean values directly into the condition parameters).

The only other stumbling block for me was learning to use git, but up until recently I got by with only learning a handful of commands and still relying on svn to be my central repository. It wasn’t ideal, but it helped me to smooth out the up front learning curve.

In summary, if you are looking for a new home for your Rails app, then I highly recommend checking out heroku.com.

Popularity: 1% [?]

Related posts:

Thinking More Functionally with PowerShell

Whenever I review PowerShell scripts, I usually consider loops (especially nested ones) to be a code smell.

It usually indicates to me that script is unnecessarily procedural and could benefit from being rewritten in a more functional manner.

Take this simple code snippet as an example. It searches sql files for a particular string (the poor man’s equivalent of ReSharper’s “Find Usages” in the sql world).

   1: $files = (Get-ChildItem -path $rootPath -include *.sql -recurse | sort FullName);
   2: foreach ($file in $files)
   3: {
   4:     $SqlFileContents = Get-Content $file;
   5:     $SqlFileString = "";
   6:     foreach ($item in $SqlFileContents)
   7:     {
   8:          $SqlFileString = $SqlFileString + " " + $item.ToString();
   9:     }
  10:
  11:     if($SqlFileString.Contains($searchText) -eq $True)
  12:     {
  13:         Write-Host "Reference found in : $file";
  14:     }
  15: }

Now consider this revised version, which takes the more functional approach of utilizing the pipeline to carry out a series of operations on a collection of files.

   1: Get-ChildItem -path $destinationPath -include *.sql -recurse | where{([string](Get-Content $_)).Contains($searchText) -eq $True} | sort FullName | select FullName;

I’m don’t use PowerShell frequently enough to feel confident that I can figure out the most elegant way to solve a problem, but the second approach seems like a huge improvement to me. It’s more concise and arguably even more readable.

So the next time you catch yourself writing loops in PowerShell (or C# for that matter), take a step back and try a more functional approach on for size.

UPDATE: Neil Barnwell reminded me in a comment about the Select-String cmdlet, which not only greatly simplifies the script but also adds the extra functionality of displaying line numbers and text excerpts in the results.

   1: Get-ChildItem -path $destinationPath -filter *.sql -recurse | select-string $searchText

I feel stupid for having forgot about the cmdlet, but at the same time it was fortuitous because otherwise I probably would have had to spend a lot more time coming up with a better example to make the same point for this post…:-)

Popularity: 1% [?]

No related posts.

How to use Cross-Site Scripting to Rickroll your Co-Workers

What happens when you mix one of the most evil things in music with the evil that is cross-site scripting?

Let’s just say that the potential for shenanigans is endless.

Observe the result of entering the following embed tag into an editable column for one of our internal web apps.

   1: <embed src="http://www.youtube.com/v/XZ5TajZYW6Y&hl=en_US&fs=1&rel=0&autoplay=1" type="application/x-shockwave-flash" width="640" height="385" autoplay="true"></embed>.

blog_RickRolled

Like a huge number of websites, this one directly displays the user-input on the screen without first scrubbing it with something like HttpUtility.HtmlEncode() (.NET world).

Want to partake in the fun?

All you have to do is find an internal website in your development environment that is vulnerable by trying to paste the embed tag into a textbox of some editable grid. If the video displays after saving, then simply send a fellow developer or tester an email asking them to go to the vulnerable page and verify some made-up bug. When they pull it up, they will be rickrolled.

Many thanks to Dan, our new tester, for catching this bug and hatching the evil plot.

Any other suggestions on fun things I can do to my co-workers before this bug gets fixed (without getting me fired)?

Popularity: 1% [?]

No related posts.

Thank Goodness April Fools Only Comes Once a Year

Imagine my surprise when I went to answer my phone this morning and it was gone. The phone cord led up to my bookshelf, which was locked.

AprilFools_phone

As you probably already guessed, the prankster stole my key.

It’s a good thing I don’t get many calls (other than this morning from the prankster).

Popularity: 1% [?]

Related posts:

Book Review: Clean Code

cc_bookReview_CleanCodeI just finished my March book from my 2010 developer-oriented book reading list, so I thought I would share some thoughts on Clean Code by (Uncle) Bob Martin before moving on to my April book, Real World Functional Programming: With Examples in F# and C#.

Rating - star_sm star_sm star_sm (out of 5)

Prerequisites – The code samples in the book are in Java, so if you’re not a Java developer it’s probably worth going through a quick tutorial first. Most of the examples rely on low level coding constructs, so you can skip familiarizing yourself with the Java APIs and focus on just the basic language syntax and the common data structures. A quick 10 minute read of this high level language comparison will probably be sufficient for most C# developers.

The Good

  1. Conceptually Cohesive – Choosing “Clean Code” as a title and topic of a book was somewhat risky because it is such an intrinsically nebulous concept. However, Bob Martin overcomes these hurdles by defining “clean” as any practice that makes code easier to understand. Just like usability experts carved a respectable science out of UI design, this book adds objective weight to the topic by examining seemingly subjective practices through a lens of measurable efficiency. For example, “code noise”, such as redundant comments, is bad because it causes unnecessary eye movements and scrolling. Likewise, descriptive names, short methods, and small classes are all preferable because they minimize the short-term memory requirements of the reader and thus increase the speed of comprehension as well as the capacity to discover logic flaws.
  2. Thought Process Over Rules – Although the catalog of code smells and heuristics that Bob Martin provides towards the end of the book are helpful, his ability to recreate his thought process while refactoring code is definitely one of the more valuable parts of the book. Context is everything and learning rules without fully understanding when it is appropriate to apply them will almost always cause more harm than good (e.g. design patterns). The way the author sometimes changes his mind and even reverses himself as the code takes shape is a superb teaching technique because it models how to fully analyze the context. There were several times where I disagreed with his final solution, yet still felt satisfied that I had learned new ways to think more critically about the choices I was making.
  3. Code-Centric – Like rules without context, abstract concepts without extensive grounding in concrete examples are worse than useless. Another strength of the book is that it is code-heavy without ever being repetitive or wasting time on obvious examples.

The Bad

  1. Length of Case Studies – Although I firmly agree with the code-centric approach the book takes, I think it was a mistake to chose such large code samples to refactor in the second half of the book. I might have been more patient with the constant page flipping and mental gymnastics involved in reconstructing how code had changed if I weren’t already so used to using tools like Resharper, Subversion, Beyond Compare, and Fisheye. At the end of the later chapters I felt the same frustration I feel anytime I’m forced to revert to a manual task that provides a fraction of the value for a lot more effort. I just don’t think books are the appropriate medium for these types of large code reviews.
  2. Several Extraneous Chapters – There were several chapters in the middle of the book that seemed out of place and thus distracted from the main theme. For example, the chapter and rather large supplemental appendix section on concurrency devoted too much time to multi-threading fundamentals rather than focusing on the main them of how to increase readability. Likewise, several other chapters covered topics that were not directly relevant or were dealt with at a level that was too superficial. It reminded me of methods that Uncle Bob criticized in the book for mixing levels of abstraction. It would have been better if they had just been cut out of the book.

Conclusion – I struggled when trying to come up with an overall rating for this book because I absolutely loved the first hundred pages of the book but was decidedly less excited about the rest of it. Ultimately, I gave it three stars because I think it deals with a really important topic and does it quite well for a sizable part of the book.

If you are either a junior level developer or else haven’t read many other books about refactoring (e.g. Martin Fowler’s classic Refactoring), then I would consider this book a must-read and would definitely buy it. Otherwise, you’re probably better off just borrowing it and only reading the first one hundred pages or so.

Popularity: 1% [?]

Related posts:

Next Page »