Kevin Dente's Blog

The Blip in the Noise

August 2003 - Posts

String concatenation - + vs StringBuilder

Countless times I've read that the when doing string concatenation, the StringBuilder class is more efficient than the String "+" operator. I pretty much just accepted that advice until a couple of days ago. But after poking around a bit, it now looks like there's some simple and common cases where in fact the opposite is true.

I got started on this because the existence of the String.Concat method finally entered my consciousness. I'm sure I've seen it before, but I never gave it much thought. Between "+" and StringBuilder, I never had much reason to, I guess. And I never see it used in sample code. When I finally grokked it's existence, I did a little Reflector'ing to look at the method's implementation (the Rotor source works just as well). Lo and behold, the Concat methods that take String arguments use what look to be efficient internal string allocation and copy methods to build up the concatenated string. There are Concat overloads for up to 4 string arguments, so I figured for simple cases I'll would just use String.Concat.

But it got even better. I found this interesting article, which talks about the internals of Strings in the .NET framework. It points out that the compiler converts string operator + calls of up to 4 arguments to a call to String.Concat. So a + b +c gets converted into String.Concat(a, b, c), which avoids the creation intermediate string objects.

With my curiosity piqued, I ran a very quick-and-dirty (and decidedly unscientific) test of 10,000 calls to "a + b + c" vs 10,000 equivalent StringBuilder calls. And in fact, a + b + c was faster. Now, I'm not really that worried about the relative performance of the two methods  - we're talking a few ticks here. But since the + operator (and even String.Concat) can be much more convenient to use than StringBuilder for quick and dirty string concatenation, I'm quite happy that I can use it without worrying about horrible inefficiencies. Obviously if you're building up giant XML strings, StringBuilder is the way to go. But if you're combining 4 or fewer strings, + is just fine.

 

 

 

Posted Wednesday, August 27, 2003 12:08 PM by kevindente | 13 comment(s)

New Microsoft Web Service

MS has released an SDK for accessing Microsoft.com downloads. Nice idea. But what I'd really like to see is a SOAP API for accessing the knowledge base. I use that sucker enough that a rich client UI would be very handy. Plus, it would let me fix the annoying limitation that the kbase UI refuses to remember the fact that I always, always, always search for "All of the words entered" with a limit of 150 articles.

Posted Tuesday, August 26, 2003 5:56 PM by kevindente | 2 comment(s)

.NET naming conventions and protected members

While I've been doing a bunch of .NET development over the last year, I haven't really developed any class libraries until now (been web services and web application stuff, mostly). Being a good .NET citizen, I set the CLSCompliant attribute. I was coding merrily along, using the C# coding standard that I've adopted - camel case for members, Pascal case for properties and methods. Everything was ducky until I tried to add a protected field and a corresponding public accessor property. The compiler complained that this wasn't CLS compliant, since case-insensitive languages like VB.NET can't differentiate between the starts-with-lower-case field and the corresponding starts-with-upper-case property. Doh! Not sure why I never thought of that. The .NET framework style guide recommends camel case for protected fields, but I guess they didn't consider the case where there's a corresponding public property when they wrote that recommendation.

My first thought was to switch to the other common style that I've seen (but that I've never been crazy about) - prefixing fields with an underscore. No love - that's also not CLS compliant. My next thought was - what does Microsoft do in the framework classes? I poked around the Rotor source code site, trying to find an example. Guess what? Couldn't find one. The only protected members that I found were either internal or had no corresponding public property. The majority of the fields that I looked at were simply declared as private with a public accessor property.

Now, this was hardly a comprehensive search - I just picked several files at pseudo-random (trying to pick files that would have reasonably substantial code in them). I haven't downloaded the full Rotor source and searched. But that said, I thought it was kind of interesting that there wasn't a single example to be found. The style guide says that a protected instance field is "rarely used", and I get that. The only reason I can envision using one is in performance sensitive code where you don't want a deriving class to incur the overhead of a property accessor. Pretty obscure. So I'm going to stick with the private field, public/protected property model.

As a final note, in poking around the Rotor source it seems that the Microsoft developers mostly used three different coding styles for fields - camel casing, leading underscore, and the old Hungarian style "m_". I wonder if they've settled on one style going forward.

I also wonder if I should just get a life and stop spending so much time thinking (and blogging) about stuff like this.

Posted Wednesday, August 13, 2003 2:00 PM by kevindente | 7 comment(s)

Poking around the VS.NET CodeModel

Today was a pretty darn interesting day. I spent a big chunk of it writing a Visual Studio .NET add-in that uses the CodeModel to munge around with C# source code. The experience ran the gamut, from initial excitement at early successes, to frustration as limitations were encountered, to satisfaction when the goals of the project are finally met. It isn't too often that all of that happens all in one day.

One of my first weblog posts was about Web Service proxies. When WSDL.EXE creates the proxies, it uses fields rather than properties to expose the data elements of the proxy classes. This is unfortunate, because it mean that the proxies can't be used very easily with the .NET databinding architecture (which only works with properties). At various times I've poked around at potential workarounds to this problem, but never came up with a workable and satisfactory solution. As I poked at the CodeModel, it seemed to offer the solution I was looking for.

The idea was to use the CodeModel API to parse the generated proxy classes, converting public fields into private ones and exposing property getters and setters for the fields.  Initial experiments were promising - I quickly had working code that ran through the public fields of a class and changed them from public to private.  The CodeModel API was quite easy to use, and seemed to do what I needed.

“Seemed” is the key word. I hit my first major problem with fields that are annotated by XML serialization attributes. The CodeModel doesn't handle that too well. For example, changing the access modifier of an annotated field from public to private put the “private” keyword before the attribute, and left the public keyword in place (this works for a non-attributed field). I ended up working around it by completely removing the original public field and adding a new private one.

Adding the corresponding property getter and setter was pretty easy, but then I hit the next problem - adding attributes through the API doesn't work. The documentation implies that this should work for C# (the VB.NET CodeModel is read-only, but there's no such limitation documented for C#). It doesn't. This was the trickiest problem to figure out, but it turned out to not be very difficult to code. The EditPoint class let me copy the text of the attribute definition from the original field and paste it in front of the property definition, and that was a good enough solution for my needs.

So things were working pretty well on a small sample. But as I was testing the tool on a rather large WSDL file, I encountered a new problem - sometimes it would hang in the middle of execution. The hang occurred at random places in the WSDL, although it was almost always while calling the CodeClass.AddProperty method. Suspecting maybe a timing or race condition, I threw a Thread.Sleep(100) in between each class, and haven't seen the problem since. I hate hacks like that, but I'm living with it for the moment.

The final challenge was figuring out where to plug the add-in into the project system. My preference was to provide a context menu option directly on the web reference which would trigger the conversion of fields into properties. Again, it wasn't hard - the trick was figuring out which Command Bar to add the menu item to (“Folder“, in this case).

And that was pretty much it. It took less than a day to write, is less than 400 lines of code, and now I have data-bindable web service proxies. I hope Microsoft continues to flesh out and fix the CodeModel stuff in VS.NET. Bugs and limitations aside, it's pretty sweet, and quite powerful.

And of course, I hope Microsoft changes WSDL.EXE to generate properties instead of field. Or changes databinding to work with fields. I'll keep my fingers crossed for Whidbey.

 

Posted Thursday, August 07, 2003 11:46 PM by kevindente | 5 comment(s)

Red vs Blue

I guess I'm a late comer to the Red vs Blue BloodGulch serial. Holy crap, Batman, it's brilliant. I laughed. I cried. OK, I just laughed. A lot. Those guys are amazing.

Posted Friday, August 01, 2003 1:36 PM by kevindente | 51 comment(s)

More Posts