ctodx

This Blog

News

Favorite Posts

Archives

April 2006 - Posts

  • Winning the performance war 5% at a time

    A really fascinating piece by Rico Mariani on what to do when your program is still "too slow" but you've addressed all the obvious performance hotspots.

    He makes the observation again that if you can make dramatic improvements in speed it's usually due to a major design flaw. If you spot this flaw and fix it you'll become a superhero, which is all fun and all, but hopefully if the program is well-designed these stupendous efficiency gains will be few and very far between.

    I well remember one project in my previous job where my team and I were able to speed up a section of code so that it ran in half the time and took up half the memory to do so. This was one of those examples where there was a huge design problem whose eradication meant we were able to achieve these large efficiency gains. However, after that, our gains were much smaller and harder won.

     

  • Good design skills => better refactoring

    I was pondering this over the weekend. Is refactoring always good?

    With the support for refactoring in C# in Visual Studio 2005 and also Refactor! Pro from those awfully nice people at Developer Express, you'd think life is good. We can refactor all we like, all the time.

    The problem is, I think, that doing refactoring for refactoring's sake is just not a great way of spending your time. Going back to Martin Fowler for a moment, he says that "Refactoring is the process of changing a software system in such a way that is does not alter the external behavior of the code yet improves its internal structure," and "in essence when you refactor you are improving the design of the code after it has been written." [Page xvi of "Refactoring"]. In other words, in refactoring some code you are not only trying to make sure that you don't change the external effect of the code (where are your unit tests, then?), but you are trying to enhance (improve? clean up? simplify?) the design (or structure) of the code in doing so.

    You can't just apply refactorings willy-nilly. You have to have some idea, a hazy design in the back of your mind, that's leading you towards a better structure, cleaner code.

    So your guidance in your refactoring exercises should be your knowledge of good design. You should know the Design Patterns, especially important ones like Abstract Factory and Strategy. You should understand the difference between implementation inheritance and interface inheritance, and know when to apply either one and what the benefits and drawbacks of both are. You should have some idea of object-oriented design principles like the Single-Responsibility Principle and Tell, Don't Ask.

    In other words, before you can get the maximum benefit from such great tools as Visual Studio and Refactor!, you have some learning to do first. You have to be a good object-oriented programmer.

  • Code Generation

    I was thinking this morning about code generation. Yes, I know, weird, but it's part of my job to consider our markets and where we're going and whatnot.

    (Aside: I always used to spell weird "wierd" and the Word spellcheck would simply squiggly-underline it for me in red. I could never remember which way round the i and the e went, until one day I read somewhere that the way to remember it is that the word weird is spelt weird. Geddit? In other words, weird is spelt in a way you wouldn't expect; that is, the opposite of "i before e except after c". Problem solved; normal service is now being resumed.)

    I own both CodeRush and CodeSmith. CodeRush is our add-in to Visual Studio that helps you write code faster by mapping simple key sequences in Visual Studio to code templates, whereas CodeSmith is a program that converts ASP.NET-alike templates to gobs of source code.

    As an example of CodeSmith's power consider the .netTiers templates. With this set of templates you can point CodeSmith at your database and it will autogenerate a complete data access layer and business object layer for your schema that uses the Microsoft Enterprise Library. Get your schema right (no small undertaking, that!), and blam in less than 15 minutes you have a Visual Studio solution that provides two tiers of your application. Phenomenal.

    Of course, you can't (or, rather, shouldn't) change this code since the next time you change the database schema you'll want to regenerate all the code again. Still it's a great bonus to productivity (and writing a bazillion data access and business objects by hand is enough to make you go crazy).

    CodeRush, on the other hand, acts in a more localized scope, as you are writing code in the editor. There it gives you immediate feedback. You want a new class? Type c, space, and fill in the name of the class. A method returning a bool? m, b, space, and then fill in the name again. Of course, you don't have to stop there. The coll template produces a complete typed collection for a particular type. Properly commented, in a region and ready to go. Other templates produce an equivalent chunk of code there and then.

    There's a template for CodeSmith that produces a typed collection too, but it's much more convenient to use the CodeRush one because it's right there in the editor when you realize you need one.

    You could even work with both CodeRush and CodeSmith; they are very complementary. The hard thing about using CodeSmith is that you have to work out the template first. Once you have the template, it's simplicity itself to apply it ad infinitum at practically no cost. To create the template, the easiest thing is to write the code you want for one exemplar object in your problem space. Use Visual Studio, CodeRush, and Refactor! to get the best designed, most efficient and maintainable code. Make sure you write and use all the verification code and pre-conditions and invariants. Compile and test to your heart's content. Take your time, make it right. Once it's ready and it works the way you want it, convert it into a template, and using CodeSmith you get the support for all your other objects for free.

    CodeSmith evens uses "code-behind" source files written in C# so that you can provide extensibility methods to do things standard CodeSmith cannot do. Using CodeSmith Studio to write those can be a little awkward (there's nothing like Intellisense), so I tend to use Visual Studio with CodeRush. (It's a shame that CodeSmith's integration with Visual Studio doesn't extend to the editor: when you try and edit a CodeSmith template in Visual Studio, it launches CodeSmith Studio.)

    So all in all, if you're into code generation (and for any large project, you should be), CodeSmith and CodeRush make a great pair.

  • The Program Files folder

    Here we are in 2006. We've gone through (and are still going through) a bunch of attacks on our PCs from malware. With every service pack, Windows is getting to be more secure. We've recognized that running as a standard user is a good thing to do from a safety viewpoint because standard users can't write to important folders like Windows or Program Files. Windows Vista is going to change the landscape on this front, because we're going to have to explicitly mark user accounts as Administrators instead of having them default as such.

    So why on earth do programs still try and write user files like configuration files to their install folder under Program Files? I run as LUA on my tablet unless I need to install a program or driver. I love well-written applications that write configuration and documents to the Documents and Settings folder (mmm, there's a hint there in the name, don't you think?) and I loathe programs that assume I'm running as admin and write to Program Files (because they just crash or they don't save important information). There are two I suffer because they provide good functionality for me (and indeed one of them I just have to run through a batch file that logs me on as Administrator).

    Of course I know why programs do this. It's because their developers run as admins all the time. Their QA people run as admin all the time (they have to install every release to test it and it's just easier to be admin to do that). So, all you developers out there: do you run as a standard user? Even more important, do you test your application as a standard user? Do it now, before your customers get Vista and find out that it won't work properly. In .NET, it's easy to get at the right folder for the user under Documents and Settings.

    Similarly we, as users, shouldn't be adding files or folders to Program Files to store our stuff. It's bloody stupid and shortsighted. A well-written application that does store its documents and configuration under Documents and Settings is well within its rights to just delete its folder in Program Files to uninstall (all the user stuff is elsewhere right?). Heck, we are always complaining that uninstall programs leave "droppings" all over the place, so we shouldn't assume that if we save BigImportantDocument.foo in Foo's Program Files folder it'll survive an uninstall. We, as users, should be using Documents and Settings as well.

    Grrr!
  • Software Transactional Memory

    I happened to be browsing through the Microsoft Research site last night, when I came across a project that I'd read about some months back, filed it as "interesting, must come back and read some more", but filed it in short term memory instead of in OneNote, and promptly forgot about it.

    The biggest problem with writing multithreaded applications is the race condition, with deadlocking coming hard on its heels. To solve race conditions, we're pretty much used to using thread locks: we lock some object, mess around with some data, and then unlock the object (C#, of course, makes this easy with the lock keyword and its associated block). So long as we're religious about putting accesses to the data inside a locked block (and locking the same object), we're fine.

    Except that locking is fairly disruptive, efficiency-wise. Or, rather, trying to lock an object that's already locked is disruptive: context switches abound, even on multi-processor machines. So that's why there's been so much work done on lock-free algorithms and data structures in academe: researchers recognize that on a machine with tens of processors, a locking algorithm is always going to do much worse than a lock-free algorithm.

    The other big, massive, horrendous problem with a locking methodology is that locks are not composable. In other words, if we are not careful (and it can be really difficult to make sure we are careful) composing an operation using two locks may cause deadlocks, which of course is another great reason for exploring lock-free algorithms.

    Anyway, one of the more promising avenues being explored is Software Transactional Memory. This is a multithreaded framework where traditional locks are replaced by lightweight transactions. A transaction is a sequence of memory accesses (read or write) executed by a single thread. Just as with your favorite database engine, transactions are atomic in that the framework guarantees that either the changes in the transaction all take place (commit) or are all discarded (rollback). The transaction framework uses lock-free techniques to ensure the commit or rollback.

    Anyway, the point of all this is that Microsoft Research have released SXM, a software transactional memory framework for .NET and C#. You can read the readme here, and download the code here. For a layman's explanation of STM see wikipedia.
  • Birthday meme

    Go to Wikipedia and look up your birth day (excluding the year). List three neat facts/events, two births and one death in your journal, including the year.

    Facts/Events
    1814 - Napoleon abdicates. He is then exiled to Elba.
    1895 - Oscar Wilde is arrested [for gross indecency] after losing a libel case against John Sholto Douglas, 9th Marquess of Queensberry.
    1974 - In Brighton, United Kingdom, ABBA wins the nineteenth Eurovision Song Contest for Sweden singing "Waterloo."

    Births
    1671 - Jean-Baptiste Rousseau, French poet (d. 1741)
    1929 - André Previn, German-born composer and conductor

    Deaths
    1992 - Isaac Asimov, Russian-born author (b. 1920)

    Additional fact
    The start of the tax year in the United Kingdom (arising from the 11 day correction to March 25 at the adoption of the Gregorian calendar in 1752). (Unfortunately there are 12 days between March 25 and April 6, so where did the extra day come from? - Ed)

    (Hat tip: Geoff Arnold)

  • Too simple to break

    Every now and then, as is my wont, I get to thinking about unit testing, most often in terms of test-driven development. However, I have been known to countenance unit tests outside of that methodology, but you have to ply me with a good meal and an excellent bottle of wine and turn off the tape recorder first, though.

    Many times developers write a class using simple properties; that is, properties which have the standard one-line get and set blocks. Using VS2005 this is simple enough with the prop snippet expansion (and is even easier with CodeRush, of course).

    class Foo {
    ...
      public int Age {
        get { return age; }
        set { age = value; }
      }
    }

    Now the question arises: is it worth writing a unit test for this property? The simplest would probably be this code.

    [Test]
    public void ShouldReadChangedAge() {
      Foo foo = new Foo();
      foo.Age = 49;
      Assert.AreEqual(49, foo.Age);
    }

    But is this worth it? I would argue that, no, it isn't. In fact, there is also a school of thought that says that writing this kind of property is not worth while either ("just use a public field, dude"), but I shall address that question later on.

    The code that implements this property is, in essence, "too simple to break". Instead, we should concentrate our testing efforts on code that is more intricate and more likely to break, such as code with higher cyclomatic complexity. Writing bad code for a property with a one-line getter and setter is pretty hard to do without being obvious about it, and you'll notice the bug pretty quickly too. (The only real example I can think of from the top of my head is to use the wrong backing field.)

    Note that I'm not saying that it is wrong to write such a test. All I'm saying is that you'll get more bang for the unit-testing buck by writing tests for a more complex method (or property for that matter). (Examples of properties that should be tested: one whose getter invokes a calculation to get the value to return, or one whose setter involves several side-effects such as updating other fields or performing other calculations.)

    I'm sure a unit-testing purist would undoubtedly say that not having a test for this property means that the property is untested and therefore prone to failure. This is quite right, but note that using the tools we have at our disposal, you must really want to write bad code to get this kind of property wrong. Also, unit testing, no matter how hard we try, is never guaranteed to uncover all our bugs.

    What we try and do with unit testing is to use our judgment and resources and time to discover and fix bugs as soon as possible in the project's lifetime. Bugs discovered early are almost free to fix. Bugs discovered later are much harder to fix and cost a lot more in terms of time and resources. So we try and balance our time and resources writing production code with the code that tests it. Too much time spent writing unit tests can be just as bad as too much time spent writing production code. In the first case, we are gaining greater confidence in our code at the expense of much greater schedule time, in the second case we are getting the real code written faster at the expense of having a nasty bug (or bugs) possibly to be discovered by our customers. We have to learn to balance this more tests versus less scheduled time trade-off.

    In essence, I'd say don't bother testing code that's too simple to break. But certainly be prepared to defend your assertion that the code you're not testing really is too simple to break.

  • Welcome

    Well, after three weeks in the job, it's time to start blogging.

    Readers who know me know that I already have a blog on my own website at boyet.com and may be wondering if I'm going to be abandoning that one in favor of this one. The short answer is no, with the longer one being that I shall try and reserve my boyet blog for algorithms and data structures and more personal stuff and this one for more company-related stuff.

    Not that I intend for this blog to be just a company ra-ra, let's lay on the marketing-speak blog. Absolutely not. I intend to be candid for sure, well as candid as I can, and you can expect me to discuss issues that we come across, hints on what we're working on, and every now and then some news of our new releases.

    Also I'm getting used to the Community Server product that we're using for this site, so you might see some funky formatting every now and then.

    And now, without further ado, let the blog commence...
LIVE CHAT

Chat is one of the many ways you can contact members of the DevExpress Team.
We are available Monday-Friday between 7:30am and 4:30pm Pacific Time.

If you need additional product information, write to us at info@devexpress.com or call us at +1 (818) 844-3383

FOLLOW US

DevExpress engineers feature-complete Presentation Controls, IDE Productivity Tools, Business Application Frameworks, and Reporting Systems for Visual Studio, along with high-performance HTML JS Mobile Frameworks for developers targeting iOS, Android and Windows Phone. Whether using WPF, ASP.NET, WinForms, HTML5 or Windows 10, DevExpress tools help you build and deliver your best in the shortest time possible.

Copyright © 1998-2017 Developer Express Inc.
All trademarks or registered trademarks are property of their respective owners