Chinh Do

Finds of the Week – Nov 2, 2007

First time here? Check out my greatest hits or look around in the archives, and consider subscribing to the latest posts via RSS or email. I am also on Twitter and Google Plus. Thanks for visiting.
8th November 2007

Finds of the Week – Nov 2, 2007

Here are the finds for this week.

.NET

  • Mike Duncan wrote a nice article on 3 hot uses for HttpContext.Current.Items “They” won’t tell you about. Wish I had thought about this 6 months ago when I was trying to implement a "static" variable that only lasts for the duration of the page request.
  • Too busy with real work to read up on the soon to be released Visual Studio 2008 (by end of November)? Daniel Moth has put together a summary the top 10 things to know about VS 2008 and .NET Framework 3.5 here.
  • For Oracle developers, check out Gojko Adzic’s article on the new function result caching feature in Oracle 11.
  • Java and .NET to drive double-digit wage growth. Yes double-digit wage growth! That should happen more often. By  Gavin Clarke via regdeveloper.co.uk.
  • Doug Stewart wrote another comprehensive article on new features of Visual Studio 2008 and .NET Framework 3.5.
  • There’s something slow, in your program flow. Who you’re gonna call? Profilers of course :-) . M has put together a detailed article of how to use the ANTS profiler. Also check out Improving .NET Application Performance and Scalability by J.D. Meier, Srinath Vasireddy, Ashish Babbar, and Alex Mackman.
  • Marquee de Sells has several interesting points on the consequences of working for Microsoft remotely.

Software and Tools

Vector Magic is the probably best bitmap tracing tool currently available. Check out the amazing samples. Free!

Resharper is a great productivity and code analysis add-in for Visual Studio. It’s the only add-in I currently use. My top 5 favorite Resharper features are:

  • On the fly error/warning checking (squiggly lines). See problems with your code as you type them.

    Resharper On-the-fly Error Checking

  • Refactor (Rename, Extract Method, Introduce Field, etc. )
  • Goto Type/File/File Member. Fastest way to navigate. Every class, file, or method is only a few keystrokes away.

    Resharper Navigation

  • Find Usages. Find what is using a class/method/property. Great for finding code dependencies. Indispensable for learning a new application you are not familiar with.

    Resharper Find Usages

  • Reformat Code.
  • Enhanced Intellisense.

Windows Live Writer is a windows editor for blog posts. Your drafts are saved locally. Works with WordPress. I like it. This post was written using Windows Live Writer.

Gadgets

Miscellaneous

  • At my work it was announced that we will be switching to "Outlook" from Lotus Notes. We are currently on Notes 6 and it’s the most atrocious of a program I have had the pleasure of using on a daily basis. Some of the most basic features like Search does not even work. Argg! I had to create my own Notes index by periodically exporting all messages to text files so that Windows Search will index them. I can’t wait to get back to Outlook/Exchange.
  • Have you wondered why Windows Explorer doesn’t show the size of a folder? Here are the reasons (Raymond Chen via blogs.msdn.com/oldnewthing).

And Now, Something Different

I’ve always been skeptical whenever I hear people say or write that we only use 10% of our brain. Well, it looks like there is no scientific evidence to suggest that. Read more here.

posted in Dotnet/.NET - C#, HDTV, Links, Programming, Reviews, Software/tools, Technology | 2 Comments

6th November 2007

Software Review – Mozy Online Backup (Version 1.8.4.7)

I have been telling myself that I need to set up some sort of automated backup solution for my data for years now. In the past, I have actually used various tape backup solutions but I eventually gave up due to the cost of buying new tape drives that could keep up with the increasing large amount of data.

I decided to give Mozy a try. If you have not heard, Mozy is an online backup solution. Their main selling point is that they will back up your home computer for $4.95 per month. Your data is transfered over your Internet connection and is backed up to Mozy’s servers. I figure $60 a year for a fully automated backup solution and peace of mind is worth it.

Installation and Configuration

The installation and initial setup process is pretty straight forward. By default, the software will automatically select files to be backed up, but I am sure most people will need to make changes to the backup selection. Each Mozy account will only support one computer. Yes, I tried to include a network location in my backup sets, but it wouldn’t allow it. External drives connected via USB2 are fine.

Mozy backup sets

There are several configuration options to tweak. In the Schedule tab, you can tell Mozy to backup when your PC is idle, or at specific times:

Mozy backup schedule options

And under the Options tab, you can control many additional settings:

Mozy backup options

For my backup, I leave most settings at the default values, except I checked “Don’t show restore menu in Windows Explorer”. I generally do not let any application install context menu handlers for Windows Explorer. Don’t know if it’s true or not, but I suspect that misbehaving explorer context menu handlers are the source of most mysterious hangs and slow-downs in Windows.

Backing Up Data

The backup process works fairly well. The initial backup will take some time to complete. How much time depends on the size of your backup sets and the upload speed of your Internet connection. My initial backup took about 3 weeks to backup 75 GB of data over a Verizon Online FIOS connection with 2000 kbits of upload bandwidth. Since then I have added another 10GB of data and it has been keeping up just fine.

While the backup is in progress, you can check Mozy’s progress with this informative progress window:

Mozy - backup in progress

Restoring Data

There are currently four different ways to restore files with Mozy:

  • Right-click Restore – Navigate in Windows Explorer to the folder you want and right click, then choose “Restore files in folder”.
  • DVD Restore – Mozy will burn your data to a DVD and send it to you via snail mail. Good for large restores.
  • Web Restore – Use Mozy’s web site to select folders/files to restore and download the files via the web site.
  • Virtual Drive Restore – Navigate to Mozy’s virtual drive and select files to restore from there.

I had some problems initially with Virtual Drive Restore. Every time I tried, I would get an error saying that it could not connect to the server. The error went away after I reset my account password. This is probably the simplest and quickest way to restore a small number of files.

Mozy Backup Virtual Drive Restore

Web Restore is also pretty straight forward. You log into the Mozy web site, choose Restore Files and follow on-screen instructions. One minor issue is that the files are not available immediately. Instead, you will get an email once the restore is complete. Then you can go to the web site to download the files. An additional benefit of Web Restore is that you can restore files from any Internet connected PC. In this way, you can think of Mozy as an Internet mirror of your files.

If you want to restore everything, then DVD Restore is probably the way to go. I have not tried this option.

The last Restore method is Right Click Restore in Explorer. I did not test this method either because I chose not to enable explorer shell integration.

Support

I had to use Mozy’s tech support to resolve an error that I could not resolve myself. Email did not work well as I didn’t receive a reply at all after several days. However, when I tried the “Chat Live” option on the web site, and was immediately connected to a live tech support person. She was able to help me resolve the problem fairly quickly.

Summary

I feel a lot better now that my important files are finally backed up at an off-site location. I am probably better protected now than many small businesses. I can get to the files easily and wherever I need. Mozy works very well once you understand and work with its main limitation: the upload speed of your Internet connection. I have not heard of anyone running into a problem for backing up too much data. Finally, for $4.95 a month… you can’t beat that.

Highly recommended.

posted in Reviews, Software/tools, Technology | 6 Comments

1st November 2007

Finds of the Week – Oct 31, 2007

Here are my finds for this week:

.NET

Tools

  • I hope my hard drive doesn't crash in the next few days… because my initial Mozy backup is still running… about 3 weeks after I started it. At this rate it should be done in a few more days.

    Mozy Backup

  • Oracle SQL Developer is a very nice and full-featured Oracle query and browsing tool. Best of all: it's free.

    Oracle SQL Developer

Windows Mobile / Pocket PC

  • I wrote before about how Verizon Wireless may cut you off if you use up too much bandwidth per month. Good news: Verizon Wireless has just settled a N.Y. probe (news.com) into that practice.
  • I've been checking my Gmail account everyday every since the IMAP announcement on Oct 24. Today, it finally showed up!

    Gmail IMAP

  • Capture Screen Utility from Fann Software is a free screen capture program for Pocket PC and Windows Mobile devices. It's free, and it works.

    Fann Software Screen Capture Utility for Windows Mobile/Pocket PC

Miscellaneous

  • If you are anoyed about that pesky Windows Language Bar that keeps coming back after you tell it to go away, you are not alone. Here's how to get rid of it for good (How-To Geek Blogs).

posted in Dotnet/.NET - C#, Links, Software/tools, Windows Mobile / Pocket PC | 0 Comments

31st October 2007

My Article on Dotnetslackers.com: Bulk Operations Using Oracle Data Provider for .NET (ODP.NET)

My first article for Dotnetslackers.com is up. Here’s an excerpt:

In a typical multi-tier application, one of the biggest performance bottlenecks is the overhead of making round-trips to the database. Minimizing these round-trips is often the first area you should look at during performance tuning. Fortunately, the Oracle Data Provider for .NET (ODP.NET) makes it fairly easy to do this by providing several built-in methods to write and read data in bulk.

You can view the article here.

posted in Dotnet/.NET - C#, Programming | 0 Comments

24th October 2007

Finds of the Week – 10/24/2007

.NET

  • Improve ODP.NET Performance (Mark A Williams, via Oracle Magazine) shows how Connection Pooling, Controlling Fetch Size, and Statement Caching can be used to maximize performance with the Oracle Data Provider for .NET.
  • Did you know that you can profile a selected Unit Test in Visual Studio Team System? Read more at Profiling a Unit Test (Noah Coad, via blogs.msdn.com).

Tools

  • Sysinternals (now part of Microsoft) has released a new version (v11.02) of their extremely useful Process Explorer utility. This is one of my must-have utility on any new system.
  • Process Explorer

  • FileZilla is an open source FTP utility for Windows. It's free and has all the features I use. What more can one ask for?
  • Filezilla

  • I signed up for Mozy two weeks ago. The price is right: $4.95 per month for peace of mind. However, it’s been 2 weeks and the initial backup is still only 50% complete!! I have a Verizon FIOS connection with 2000 Kbps upload speed and about 37GB of data to backup. I’ll post an update on how restores work whenever this thing finishes.
  • Mozy

Windows Mobile / Pocket PC

  • Google has just announced free IMAP for Gmail! Unfortunately, it's not available on my Gmail account yet. I am hoping that the IMAP with Windows Mobile Outlook is better than Gmail mobile (via Pocket IE or Opera Mobile).

Blogs

  • Scott Hanselman's Computer Zen is one of my favorite .NET related blogs. I don't know how he does it, but Scott often writes several detailed posts a day. Don't forget to check out his Tools List post.

Miscellaneous

  • Did you know that the best Wikipedia content is often from anonymous "good samaritans"? "Anonymous contributors with a single edit had the highest quality of any group." Read more here.

And Now, Something Different

Alexa.com's current list of 100 Top Sites in the United States (sorted by traffic) has a couple of interesting entries. In addition to the familiar Yahoo!, Google, and Myspace, there are two Vietnamese related sites: VnExpress at number 70, and Vietfun, at number 80. Besides these two sites, there are no other non-English or minority-centered web sites on the list that I could tell.

Possible explanations:

  • Alexa rankings are way off base.
  • Vietnamese Americans are using the net much more than any other minority groups (unlikely). If this is true, there is an untapped market here.

Anyone else has an explanation?

alexa-rankings-usa-1

alexa-rankings-usa-1

posted in Dotnet/.NET - C#, Links, Programming, Software/tools, Technology, Windows Mobile / Pocket PC | 2 Comments

21st October 2007

Samsung SCH-i760 Windows Mobile Phone Now On Verizon Wireless Web Site

The i760 is now available for order through Verizon Wireless web site. The retail price is $519 but if you can take advantage of various discounts (New Every 2, 2-year contract, data plan), the price will go down to $99.

Samsung Windows Mobile 6 Phone SCH-i760 on Verizon Wireless

The SCH-i760 is a Windows Mobile Pro (Pocket PC) 6 phone, featuring a backlit QWERTY keyboard, 1.3 Megapixel camera/camcorder, microSD, WIFI, and bluetooth.

I still have a few more months to go before my New Every 2 discount will kick in :-( .

Samsung SCH-i760

Related Posts

posted in Gadgets, Technology, Windows Mobile / Pocket PC | 2 Comments

17th October 2007

Finds of the Week – 10/17/2007

As an attempt to make this blog appears more busy:-), I will begin my "Finds of the Week" series. Each week, I will share miscellaneous finds and thoughts I ran into that are related to mostly .NET development.

Here are the finds for this week:

.NET

  • Parallel Performance: Optimize Managed Code For Multi-Core Machines; by Daan Leijen and Judd Hall; via MSDN Magazine. In a few years' time, I predict that most new PCs will be multi-core. This article talks about the new Task Parallel Library (TPL) and provides code samples.
  • document.f.q.focus(); The Billion Dollar Line of JavaScript (by gst, via blogstorm.co.ok) talks about how many people use the Search Box on their browser to navigate to various web sites, instead of typing in a URL, and how this practice translates into revenue for Google. Interesting read.
  • alessandro pointed out that and IMG element with an empty src attribute will call the browser to make a request to the default document (usually default.aspx).
  • Understanding Windows Workflow Foundation (by razi bin rais, via Codeproject.com) is a nice overview of Windows Workflow Foundation.
  • Where are the basic controls in Silverlight 1.1? When I started experimenting with Silverlight recently (see my Silverlight Hello World application), the first question that came to my mind was: where are all the basic controls such as button, checkbox, textbox, etc?

    XAML Intellisense drop-down

    Don't worry! Apparently, they are not there because it's still an Alpha release. According to this post from Tim Sneath, the following controls are planned to be included in the released version of 1.1: Button, TextBox, Scrollbar, Slider, ListBox, CheckBox, RadioButton, ComboBox, and UserControl (no TreeView, RichTextBox, or DataGrid).

 

Tools

  • Probably old news to most CSS pros, but just in case you have not heard, FireBug is a very useful extension for FireFox/CSS development. Highly recommended if you ever work with CSS. I could have saved countless hours debugging HTML/CSS issues with this tool.
  • Notepad++ is a new addition to my toolset. Supports syntax highlighting, regular expression search/replace, Unicode, Macros, and is light-weight.

Windows Mobile / Pocket PC

Blogs

Miscellaneous

  • I am pretty bad with keeping in touch with people, and I have found that LinkedIn makes it fairly easy to keep in touch with past colleages. Last week I had some free time so I decided to look up old colleagues on LinkedIn. It was great to hear from many people I worked with years ago. I found many people by simply searching on the name of the company we worked for.

And Now, Something Different

Check out the Windows Live Maps Bird's Eye view below. See the black car entering the cul-de-sac? That's me and my car.

Microsoft Windows Live Maps - Chinh's Car

How do I know that’s my car? Well, for one thing, my car is black. But the real reason I know it’s me is that a moment later, my garage door opened half-way… as I was about to drive into the garage:

Microsoft Windows Live Maps - Chinh's Car

At first glance, it seems to be an amazing coincidence (like one-in-a-million amazing). What is the chance that Microsoft’s Bird’s Eye low flying plane would fly across my house and snap pictures just as I am about drive into my garage? However, after further calculations, it turns out that the real probability is around 1/8640 (5-second window over 43200 average seconds of day-light). Still a very small chance, but certainly not lottery-winning “amazing”.

posted in Dotnet/.NET - C#, Gadgets, Programming, Silverlight, Technology, Windows Mobile / Pocket PC | 2 Comments

10th October 2007

My Silverlight 1.1 Hello World Application

Update 1/27/2009: I posted an updated version of this article targeted for Silverlight Runtime 2.0 here

Imagine being able to author rich Internet applications in your .NET language of choice, without having to mess with Javascript, cross-browser compatibility issues, or ActionScript. That’s the promise of Microsoft Silverlight 1.1. In this article, I will document my attempt at creating a Silverlight 1.1 “Hello World” application. My Hello World application is a little bit more fancy than the typical one… this one involves some animation, and drawing a few shapes from code.

Silverlight Hello

If you are new to Silverlight, Silverlight 1.1 (currently in Alpha) is the version that will include the .NET CLR and allow you to write Silverlight code with .NET languages such as C#.

Most Silverlight 1.1 C# examples I found on the web use the XAML file to declare and set object properties. In my example, I am going to create and draw most objects from the code behind c# class.

Installing Visual Studio 2008

If you don’t have Visual Studio 2008 already installed. You can download it from here. Downloading and installing Visual Studio 2008 to my Virtual PC took about 3 hours (1 for the download and 2 for the install).

Note: It’s possible to
develop Silverlight 1.1 applications with Visual Studio 2005
, but the process is not integrated as with Visual Studio 2008

Installing Silverlight Runtimes and Tools

Install the following runtimes and tools from here. I am linking to the main page instead of the individual downloads just in case the download links change.

  • Microsoft Silverlight 1.0 Runtime.
  • Microsoft Silverlight 1.1 Alpha September Refresh
  • Microsoft Silverlight Tools Alpha Refresh for Visual Studio 2008 Beta 2 (July 2007)

Create a New Silverlight Project

  • In Visual Studio, choose File/New/Project and select Visual C#/Silverlight/Silverlight Project. The Silverlight project type is added when you install the Microsoft Silverlight Tools above.
  • Give your project a name.

Creating a new Silverlight Project

Silverlight Project Files

After the project has been created, you are presented with the default Page.xaml file:

Page.xaml

Your Solution should now have the following files:

Page.xaml

The two files that you will be working with are Page.xaml and TestPage.html. Page.xaml stores the markup for the design elements (for more info on XAML, see this MSDN article). TestPage.html is the regular HTML page that will host the main Silverlight object. Silverlight.js is the Javascript helper file for Silverlight applications.

For our example, we will be adding code to Page.xaml.cs. This is what Page.xaml.cs looks like initially:

Page.xaml

Add Some Code

Ready to write some code (complete source code at the end of the article)? First, we are going to add a Storyboard element to our Page.xaml. This Storyboard element serves as a timer for the animation we are going to display.

<Canvas.Resources
 class="kwrd">>
    <Storyboard x:Name
        class="kwrd">="mainTimer" Duration="00:00:00"
            class="kwrd">/>
</Canvas.Resources>

Then, we add some code to the Page.xaml.cs file (click here

for simple “Hello World” version… if you just want a simple Hello World app):

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;

namespace CdoHelloWorld
{
    public partial class Page : Canvas
    {
        /// <summary>Represents a cell on the grid</summary>
        private class Cell
        {
            public double X; //
                x-coordinate of cell
            public double Y; //
                y-coordinate
            public bool On; //
                True if cell is "on"
            public double Order; //
                Display order
        }

        private List<Cell> cells = new List<Cell>(); 
            class="rem">// list of all cells
        private int xSize = 26; 
            class="rem">// width of the grid, in number of cells
        private int ySize = 7; 
            class="rem">// height of the grid
        private int numCells; //
            total number of cells
        private int cellIdx = 0;

        public void Page_Loaded(
            class="kwrd">object o, EventArgs e)
        {
            // Required to initialize variables
            InitializeComponent();

            // Assign a random value to each cell 
            Random rnd = new Random(Environment.TickCount);
            numCells = (int)(xSize * ySize);

            for (int y = 0; y < ySize; y++)
            {
                for (int x = 0; x < xSize; x++)
                {
                    Cell cell = new Cell();
                    cell.X = x * (this.Width / xSize);
                    cell.Y = y * (this.Height / ySize);
                    cell.Order = rnd.NextDouble();
                    cells.Add(cell);
                }
            }

            string template = " "
                            + " x x xxxx x x xx "
                            + " x x x x x x x "
                            + " xxxx xxxx x x x x "
                            + " x x x x x x x "
                            + " x x xxxx xxxx xxxx xx "
                            + " ";

            for (int i = 0; i < template.Length; i++)
            {
                if (template[i] == 'x')
                {
                    cells[i].On = true;
                }
                else
                {
                    cells[i].On = false;
                }
            }

            // Sort the cells by the random values
            cells.Sort(
                delegate(Cell c0, Cell c1)
                {
                    return c0.Order.CompareTo(c1.Order);
                }
            );

            mainTimer.Completed += new EventHandler(mainTimer_Completed);
            mainTimer.Begin();
        }

        void mainTimer_Completed(object sender, EventArgs e)
        {
            // Get the next cell
            Cell cell = cells[cellIdx];

            // Draw the cell
            Rectangle r = new Rectangle();
            r.Stroke = new SolidColorBrush(Colors.DarkGray);
            if (cell.On)
            {
                r.Fill = new SolidColorBrush(Colors.Red);
            }
            else
            {
                r.Fill = new SolidColorBrush(Colors.LightGray);
            }
            r.Width = this.Width / xSize;
            r.Height = this.Height / ySize;
            r.SetValue(Canvas.LeftProperty, cell.X);
            r.SetValue(Canvas.TopProperty, cell.Y);
            Children.Add(r);
            cellIdx++;

            if (cellIdx <= numCells)
            {
                // restart the timer
                mainTimer.Begin();
            }
        }

    }
}

Here’s the simple version of the code:

TextBlock t = new TextBlock();
t.Text = "Hello world!";
Children.Add(t);

Firefox Bug and Workaround

There is a known problem that causes the Silverlight object to not show up in Firefox. To fix the problem, remove the DOCTYPE declaration from the HTML file. See this MSDN forum thread.

Deploying Silverlight Applications to Your Web Server

To deploy my application, I simply copied the files including the ClientBin directory to my web server. Any web server will do (the server that hosts my Hello World application is an apache server).

And Now, Ladies and Gentlements, My Hello World Silverlight App

Click here.

Source Code

Download complete source code for this article.

kick it on DotNetKicks.com

posted in Dotnet/.NET - C#, Programming, Silverlight | 6 Comments

29th September 2007

StringBuilder is not always faster – Part 2 of 2

In a previous article (“StringBuilder is not always faster), I provided some quick benchmark data and gave “rules of thumb” for when to use StringBuilder and when to use traditional string concatenations. In this follow-up article, I will attempt to provide a more detailed analysis.

If you don’t want to bother with the details, jump directly to the conclusions here.

A Look at the Generated MSIL

A reader, Matt, suggested that it’s possible the compiler may have noticed that I never use the generated test objects in my benchmark code and not created them. That would definitely invalidated my test results!

Here’s the original benchmark code:

for (int i = 0; i <= 1000000; i++)
{
    // Concat strings 3 times using StringBuilder
    StringBuilder s = new StringBuilder();
    s.Append(i.ToString());
    s.Append(i.ToString());
    s.Append(i.ToString());
}

And this one, using traditional concatenation, took slightly less time (1344 milliseconds):

for (int i = 0; i <= 1000000; i++)
{
    // Concat strings 3 times using traditional concatenation
    string s = i.ToString();
    s = s + i.ToString();
    s = s + i.ToString();
}

According to Lutz Roeder’s .NET Reflector (great tool), the answer is no. Here’s the IL from Reflector:

.entrypoint
.maxstack 2
.locals init (
    [0] int32 i,
    [1] class [mscorlib]System.Text.StringBuilder s,
    [2] string V_2,
    [3] bool CS$4$0000)
L_0000: nop
L_0001: ldc.i4.0
L_0002: stloc.0
L_0003: br.s L_003b
L_0005: nop
L_0006: newobj instance void [mscorlib]System.Text.StringBuilder::.ctor()
L_000b: stloc.1
L_000c: ldloc.1
L_000d: ldloca.s i
L_000f: call instance string [mscorlib]System.Int32::ToString()
L_0014: callvirt instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(string)
L_0019: pop
L_001a: ldloc.1
L_001b: ldloca.s i
L_001d: call instance string [mscorlib]System.Int32::ToString()
L_0022: callvirt instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(string)
L_0027: pop
L_0028: ldloc.1
L_0029: ldloca.s i
L_002b: call instance string [mscorlib]System.Int32::ToString()
L_0030: callvirt instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(string)
L_0035: pop
L_0036: nop
L_0037: ldloc.0
L_0038: ldc.i4.1
L_0039: add
L_003a: stloc.0
L_003b: ldloc.0
L_003c: ldc.i4 0xf4240
L_0041: cgt
L_0043: ldc.i4.0
L_0044: ceq
L_0046: stloc.3
L_0047: ldloc.3
L_0048: brtrue.s L_0005
L_004a: ldc.i4.0
L_004b: stloc.0
L_004c: br.s L_0078
L_004e: nop
L_004f: ldloca.s i
L_0051: call instance string [mscorlib]System.Int32::ToString()
L_0056: stloc.2
L_0057: ldloc.2
L_0058: ldloca.s i
L_005a: call instance string [mscorlib]System.Int32::ToString()
L_005f: call string [mscorlib]System.String::Concat(string, string)
L_0064: stloc.2
L_0065: ldloc.2
L_0066: ldloca.s i
L_0068: call instance string [mscorlib]System.Int32::ToString()
L_006d: call string [mscorlib]System.String::Concat(string, string)
L_0072: stloc.2
L_0073: nop
L_0074: ldloc.0
L_0075: ldc.i4.1
L_0076: add
L_0077: stloc.0
L_0078: ldloc.0
L_0079: ldc.i4 0xf4240
L_007e: cgt
L_0080: ldc.i4.0
L_0081: ceq
L_0083: stloc.3
L_0084: ldloc.3
L_0085: brtrue.s L_004e
L_0087: ret

Size of Concatenated Values and StringBuilder with Initial Capacity

More questions from Matt: how does the performance curve change if the concatenated values are larger? And what if you seed the StringBuilder object with an initial capacity?

To answer the questions, I wrote some more benchmarks (complete source code at the bottom of this article) to compare three different methods of concatenation:

  • “+” concatenation: This is the traditional a + b + c method.
  • StringBuilder: Create a StringBuilder object using the default constructor and calling Append().
  • StringBuilder/Pre-allocated: Create a StringBuilder object and preallocate the initial capacity so that it does not need to expand later.

String Size = 10

The chart below shows elapsed times (ms) of the three concatenation methods, with the concatenated string size equaled to 10 characters

StringBuilder Benchmark - Elapsed time vs Concatenations - String Size 10

As the chart illustrates, when the size of the concatenated value is small (10 characters in this test), “+” concatenation (blue line) performs faster than StringBuilder until the number of concatenations reaches 6. After 6, StringBuilder starts to work exponentially faster.

However, when compared with the StringBuilder/Pre-allocated method, StringBuilder starts to perform as fast as “+” concatenation much earlier: at 3 concatenations.

Note: The orange line for StringBuilder is not very linear. My guess is that it’s due to the need to allocate space as needed. The memory allocation itself will consume CPU cycles. The default StringBuilder constructor will allowcate 16 bytes initially. Thereafter, it will allocate two times the current capacity whenever needed.

String Size = 100

StringBuilder Benchmark - Elapsed time vs Concatenations - String Size 100

When the concatenated value is 100 characters, the all three methods perform very similarly up to three concatenations, then StringBuilder/Pre-allocated pulls ahead at 4 concatenations.

Concatenated String Size = 1000

StringBuilder Benchmark - Elapsed time vs Concatenations - String Size 1000

At 1000 characters, things begine a little bit more interesting: StringBuilder/Pre-allocated is faster in all cases (although the difference is very small until about 6 concatenations). Since it may not be always possible or practical to know the final string size ahead of time, for this graph, I also added two more series to show what happens if you over-estimate or under-estimate the final capacity. As expected, there is a performance penalty for both. The more inaccurate your estimated capacity is, the higher of a performance penalty you will get.

What about String.Concat?

Lars Wilhelmsen asked “What about string.Concat?” According to my research, string.Concat is basically identical to “+” used on a single line.

This:

string s = "a" + 
                    class="str">"b" + "c";

Is the same (same generated IL) as this:

string s = string.Concat(
 class="str">"a", "b", "c");

But not this:

string s = "a";
s = s + "b";
s = s + "c";

Remember, the “+” must be on the same logical line, otherwise, the compiler will convert each line into a separate string.Concat operation, resulting in slower performance.

AJ has written a post detailing string.Concat here. Thanks, AJ, for pointing it out.

And String.Format?

Flyswat wanted to know about string.Format. I did some quick benchmark code again. The string.Format code below took 58 milliseconds to run 100,000 iterations:

string s = string.Format(
          class="str">"Value: {0}", strVal);

While this code, using “+” concatenation, only took 9 milliseconds (also 100,000 iterations):

string s = "Value: " + strVal;

According to the above numbers, string.Format is significantly slower than “+” concatenations. The difference in speed is similar between s.AppendFormat(“Value: {0}”, strVal) and s.Append(“Value: ” + strVal). I have used String.Format a lot in my code and I have not thought about this performance penalty. It does make sense. String.Format (or StringBuilder.AppendFormat) has to scan the string looking for format specifiers… that takes time. String.Format is very useful to make the code easier to read or when you actually need to format numbers. Even with this new data, I will not neccessarily shy away from using string.Format. I will however definitely be much more observant when using it, especially when used inside a loop or performance critical code path.

Conclusions

The new benchmarks do point to StringBuilder/Pre-allocated as the fastest method regardless of number of concatenations, when the concatenated string value is large (1000 characters).

With that in mind, here are my slightly modified rules of thumbs for string concatenation. Remember, “rules of thumb” are short statements to provide general princicles, and may not be accurate for every single situation. For performance criticial code, you should consider running some benchmarks/profiling yourself.

  • For 1-4 dynamic concatenations, use traditional “+” concatenation.
  • For 5 or more dynamic concatenations, use StringBuilder.
  • When using StringBuilder, try to provide the starting capacity as close to the final string size as possible.
  • When building a big string from several string literals, use either the @ string literal or the + operator.
  • For performance critical code, consider running your own benchmarks

Additional Reading

Notes

The benchmarks in this article were run on a Pentium 4 2.4 GHz CPU, with 2GB of RAM. With .NET framework: 2.0.

Source Code for Benchmarks

Source code here.

kick it on DotNetKicks.com

posted in Dotnet/.NET - C#, Programming | 9 Comments

28th September 2007

My New & Improved Samsung i730 Windows Mobile Phone

A few days ago, my old and trusty Samsung SCH-i730 Windows Mobile phone decided to bite the dust. One moment, I pulled it out of my pocket to look at the time and it was dead… just like that. No sound. No display. It was an eerie sight. I tried a soft reset, changed battery, hard reset, nothing.

Luckily, since I had purchased insurance for the phone (the only time I purchased insurance for an electronic gadget), I called Verizon. Two days later, I now have a brand new i730.

Samsung SCH-i730 box

Normally, this would be a none-event. However, something interesting happened: the replacement phone works much better than the one I used to have. Read about the problems I had with the old phone here. On the new phone, everything runs noticeably faster. There is no more unexplained slowness. Audio during phone calls now works as expected with no cut outs.

New Samsung SCH-i730 Windows Mobile Phone

I have two theories on why:

  • I had upgraded my old phone to Windows Mobile 2005 and that version of the Windows Mobile OS was causing problems on the phone
  • I had a defective phone

I will never know for sure the real cause, since the old phone is no more.

Samsung i730 owners out there, if your phone doesn’t seem to work quite right and have the problems described here, either try to downgrade to Windows Mobilde 2003, or if you have not upgraded to WM2005, you just may have a defective device.

posted in Gadgets, Technology, Windows Mobile / Pocket PC | 0 Comments