It's definitely a great idea to finally separate OQL from O/R mappers. The syntax here seems very intuitive.
It brings us closer to Cw. By the way, wouldn't it be even greater if the Navigator object could be extensible?
This way, you could give it an XML document, for example, or a DataTable, or an object that has a property that is an XML document and be able to seemlessly query across the heterogeneous parts?
But maybe I'm asking too much...
So OK, so it seems like I'm a supreme nerd:

But the good news is, my wife isn't:

I'm also not very weird:

Talking about weird...

and

I'm so glad I'm not Windows 1 or Me (see this for the nice descriptions)
But wait, it gets weirder:

The
Unit type exists to represent a length, and contains two different informations: a value and a unit or type. The unit can be absolute (pixels, centimeters, etc.) or relative (percentage, em). They are not lengths in the physical sense because in the relative case, they vary depending on the context. This is just how HTML works with lengths.
So every property that will end up representing a length should be of type
Unit.
Now, while
Unit is a value type (a struct, if you prefer, as opposed to a class), it lacks the basic arithmetic operators. You can't add two
Units, but that's normal, because they may have different units (again, they are not lengths in the physical sense), but you can't multiply them by a number either without writing some code.
An example where you would want to do that is for example the Menu control where we have the possibility to indent the submenus. A menu of depth three will have to be indented by three times the indent property value.
We're doing it more or less this way:
Unit
Multiply(Unit indent, int depth) {
if (indent.IsEmpty) {
return Unit.Empty;
}
if (indent.Value == 0) {
return indent;
}
double indentValue = indent.Value * depth;
// I'd love not to hardcode this but Unit.MaxValue is currently private.
if (indentValue < 32767) {
return new Unit(indentValue, indent.Type);
}
else {
return new Unit(32767, indent.Type);
}
}
Gizmodo: But I think we just disagree.
Gates: No, I actually don't think we disagree.
So can we agree to disagree? Or agree not to disagree about our disagreements, at least? Oh well, I'm confused.
While it's certainly a very good thing that more and more developers are aware of the performance problems of string concatenation and of how
StringBuilder can solve them, it's not as simple as switching to StringBuilder every time you're concatenating more than five strings.
So just in case you don't know, here's what's wrong with concatenating a lot of strings using the + operator (& for our VB friends)... A string is an immutable object, which means that every time you change it, the old string object gets thrown away and a new one is created, which means allocating new memory. So if you repeatedly concatenate a large number of strings, the memory you're going to spend on that is going to grow roughly with the square of the number of strings.
A StringBuilder, on the other hand, just keeps references to all the string bits, and only really concatenates when you call ToString(). Everything stays nicely linear and you can safely concatenate several millions of strings with reasonable performance (not that it's a good idea, but you can).
Now, it doesn't mean that you should use StringBuilder all the time. For example, a common piece of code that you write in
ASP.NET is constructing a client-side script string dynamically from static and dynamic bits (typically, a control's ClientID can be injected in some script that uses the client-side HTML structure rendered by the control). There are three approches you can take to that.
The first one, probably the easiest to write and to read is to use String.Format. Unfortunately, it performs poorly. Use it if readability is more important to you than performance.
The second one is to use StringBuilder, and the third one is to use string concatenation.
The crucial point here is that in the script generation case, we know in advance how many string bits we want to concatenate, which is very different from concatenating an arbitrary number of strings in a loop. Let's look at the last two approaches in details, as simplified in this sample code:
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss.fffffff"));
for (int c = 0; c < 5000000; c++) {
int i = 0;
string a = "a" + i++ + "a" + i++ + "a" + i++ + "a" + i++ + "a" + i++ + "a" + i++ + "a" + i++ + "a";
}
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss.fffffff"));
for (int c = 0; c < 5000000; c++) {
int i = 0;
StringBuilder sb = new StringBuilder(15);
sb.Append("a");
sb.Append(i++);
sb.Append("a");
sb.Append(i++);
sb.Append("a");
sb.Append(i++);
sb.Append("a");
sb.Append(i++);
sb.Append("a");
sb.Append(i++);
sb.Append("a");
sb.Append(i++);
sb.Append("a");
sb.Append(i++);
sb.Append("a");
string a = sb.ToString();
}
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss.fffffff"));
What's interesting is to look at the compiled IL for the concatenation approach.
newarr [mscorlib]System.Object
... lots of array initialization code...
call string [mscorlib]System.String::Concat(object[])
The compiled code does not concatenate each string bit. Instead, it creates an array with all the bits in it (as it knows the size of the array at compile-time) and then calls String.Concat passing it the array as a parameter. This solution is actually faster than the StringBuilder which doesn't make any assumptions on the number of string bits (even though here, we've used the overloaded constructor that specifies the number of bits: this number is just considered a first estimation by the builder).
I've observed this code to perform about four times faster in the concatenation case than in the StringBuilder case. Of course, this test is very primitive and should not be considered to be some kind of absolute truth. For example, I've chosen the number of strings to concatenate quite arbitrarily, and you may find that your own numbers may vary widely from that. As always, never trust someone on performance, do your own tests in your own context.
But as long as you keep your concatenation instructions all in the same instruction (which doesn't prevent you from making it readable using carriage returns and indentations - our VB friends can use the underscore to continue on the next line -), concatenation should be faster in the fixed number of concatenations case.
The recent launch of the
Google Suggest beta attracted a lot of attention to XmlHttp callbacks. Such features where client-side script asks the server for very focused updates to the page without reposting it entirely have been possible ever since frames and javascript exist (I've done a web-based chat application and treeview based on hidden frame posting more than 4 years ago), but the XmlHttp APIs
first found in IE 5 and then in
Mozilla,
Safari and Opera (without the need to use an ActiveX, which is a great improvement) have made it a lot easier and a lot less hacky. There's even an ongoing
W3C attempt at standardizing such APIs (which unfortunately adds a third syntax to the IE and Mozilla syntaxes).