Something interesting I came across today. Two seemingly identical loops in two different languages:
for(int i = 0; i <= 10000000; i++)
{
TimeSpan t2 = DateTime.Now.Subtract(t);
// assume we do something more interesting in
// a real program...
}
Dim t As DateTime = DateTime.Now()
For i As Integer = 0 To 10000000
Dim t2 As TimeSpan = Now.Subtract(t)
' assume we do something more interesting in a
' real program...
t2 = Nothing
Next
There is a difference, obviously—the VB programmer has attempted to set the TimeSpan t2 (a ValueType) to Nothing. The VB compiler doesn’t prohibit you from doing this, as the C# compiler would if that programmer had tried to set t2 = null.
Programmers at my company (other than me) do this constantly. The reason is that they got used to doing it to every object variable in VB6. Whether or not that was actually necessary, I don’t know. It’s beyond the scope of this post, anyway.
At any rate, it shouldn’t matter. At most, it should end up just being one instruction and might even get tossed out by the JIT compiler. Right? Wrong.
On average, the C# loop executes more than 5 times faster. Roughly 5 seconds for VB versus roughly one second for C# on my machine. When you remove the extra line in VB, the times are comparable. If we replace TimeSpan with a reference type but leave the extra line, the times are comparable.
Why? Looking at the MSIL generated when we have this gives us this in Release mode:
; Equivalent to GetType(TimeSpan)
L_001d: ldtoken [mscorlib]System.TimeSpan
L_0022: call [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle([mscorlib]System.RuntimeTypeHandle)
; This is the late-binding way of creating an empty TimeSpan.
L_0027: call object [mscorlib]System.Activator::CreateInstance([mscorlib]System.Type)
L_002c: unbox [mscorlib]System.TimeSpan
L_0031: ldobj [mscorlib]System.TimeSpan
L_0036: stloc.2
Ok, so I can see now what the compiler is trying to do. Whereas the C# compiler would make us explicitly go looking for the TimeSpan.Zero field if we wanted to reset the value of a variable, the VB compiler is trying to help us out by creating an empty structure for us.
It would have saved us a little trouble, if that was at all what we were intending to do. In my case, it just happened because someone is used to typing it. Another problem is that it happens where, even understanding this behavior, you would still not expect it. Consider:
' Reminder - DictionaryEntry is a struct.
For Each entry As DictionaryEntry In hash
' ...
Next
This ends up being equivalent to setting entry = Nothing with each iteration. You’d therefore get the same late binding IL and this loop is many times slower than the “same” loop in C#.
I’m not a language or compiler designer, but here’s what I would like to see done (in order of preference).
- Disallow this with Option Strict On, like C# does currently (a breaking change, obviously).
- Give a compiler warning where it will happen.
- Do a better job of publicizing this kind of behavior. I can’t find any documentation on it.
Brad Abram’s Designing Good Libraries post inspired me to find out if some of the trickier rules mentioned are already caught by FxCop. Obviously many of the casing and naming guidelines are covered.
This code:
private static string[] _privArray = { "a", "b", "c" };
/// <summary>
/// We should not return the static array here,
/// as the elements can be changed by the caller.
/// </summary>
public string[] GetStrings()
{
return _privArray;
}
Is not caught, but this code:
/// <summary>
/// We should not expose a static array like this,
/// because the elements can be changed.
/// </summary>
public static readonly char[] InvalidPathChars = { '\"', '<', '>' };
Is found with this message:
Either replace TheClassFromHell.InvalidPathChars with a strongly typed collection that cannot be changed, or replace the public field with a method that returns a clone of a private array.
It seems like it would be pretty easy to adapt that rule to cover the getter method example. Perhaps I’ll add that to my Festivus-vacation to-do list.
This code isn’t caught either, but it seems like it would be more difficult to find.
/// <summary>
/// The function should return an empty array instead
/// of a null array.
/// </summary>
public string[] GetStringsNull(bool a)
{
if (a)
{
return new string[] { "a", "b" };
}
return null;
}
Man, I love FxCop. Partially because of moments like this:
Correct the spelling of the unrecognized token ‘Sucky’ in namespace ‘SuckyLibrary’.
But mostly because it is more efficient and less stressful than reiterating standards ad nauseum.
On the same topic, I was wondering about this:
Using Structs
-
What happens?
MyStruct[] arr = new MyStruct[10];
-
The constructor for MyStruct is not run here
-
Do not provide a default constructor
It seems to me as if it’s not possible to create a default (parameterless) public constructor for a struct — at least not in C# anyway. Maybe this restriction is not part of the CLR, or maybe we’re talking about constructors with parameters?
Mike “Not getting back onto a network broadcast this century” Patrick just said, and I quote, “We have got a case of the giggles.” I prefer that my bizarre TV ticklefights involve Terry Bradshaw whenever possible, thank you.
Paul Maguire appears to have stopped bothering to groom his mustache sometime in the mid-70s. This walking soup strainer is usually good for at least nine inane and unnecessary slowmo replays per game, all ending in the word “BAM!!!!” Like John Madden, but dumber and not lovable. Tremendous insight is almost certainly locked away in the parts of his brain not yet invaded by his out-of-control ear hair.
Joe Theismann is plagued by a clinical inability to be critical of even the most despicable of players and personnel. His incessant and bizarre asskissing of Kordell Stewart, Chad Scott, Ray Lewis, aging Deion Sanders, Brian Billick, Mike Martz, and many others over the years was what originally prodded me to start watching this broadcast on mute years ago.
Suzy Kolber is the only bright spot, if that can be said about anyone stuck in the sideline role. I liked her hosting the countdown, the one night they had her subbing for Stewart Scott. If there is justice in the world, she will escape the horrible talent black hole that is the 8:00 ESPN game.
What others are saying:
ESPN’s Sunday Night Football Crew Worse than ‘Gigli’
Maybe [the people watching this broadcast are] perfect for the rah-rah hyperbole and endless Ray Lewis ass-kissing.
No, we’re not the NFL’s unquestioning cheerleaders. We’re just hardcore fans with apparently, enough of a penchant for sadomasochism to want to watch this piece of crap. I like the jab at Ray Lewis though. I still want to know where that dangerous bastard was when Joey Porter was shot. Good points overall.
ESPN Sunday Night Football announcers: you’re idiots
In the course of a game, [Patrick’s] primary goal is not to describe the action on the field, but to tout the exploits of key, hype-able players.
This sadly seems to be the case. I don’t have proof of a massive hype conspiracy, but I HAVE lost count of how many times the vastly overrated Ray Lewis has been “miked up” (or whatever the hell they’re calling it these days). He’s never produced a single worthwhile sound bite. I take solace in the hope that the electronic equipment is somehow making him sterile.
Did I mention I can’t stand Ray Lewis? I can’t stand Ray Lewis.