As a research project, Scott Eric Kaufman is seeing how fast a meme can spread. If you have a blog, please post a link to his post.
Thursday, November 30, 2006
Monday, November 20, 2006
Friday, November 17, 2006
The new version adds support for display of RuntimeMethodInfo and RuntimeConstructorInfo visualization, support for Delegate.MethodInfo visualization. Perhaps coolest of all it now has the ability to incrementally show the method's IL being built with each click of the new context-menu option.
Thursday, November 09, 2006
Some of the magazines I get (and I get bunches) are expensive, some are free, some of those are occasionally worth the read. But rarely is the editorial of any of them worth the soy it's printed with. Imagine my surprise when I found this editorial in the November, 2006 issue of Windows IT Pro:
You buy a house. After you move in, your walls and floors are suddenly soaking wet because all the pipes are leaking. You learn that your builder is infamous for constructing popular houses that have porous plumbing. Then you find some plumbing companies that specialize in fixing your builder's pipes. These plumbers have become hugely successful by understanding how to cut holes in your walls, access the pipes, fix them in whatever way they feel is appropriate, then charge you for getting rid of the leaks your builder was responsible for. The plumbers might have knocked holes in your walls, but at least you're no longer drowning.
Naturally, you join your neighbors in demanding that your builder stop constructing houses with dangerous plumbing. After years of complaints, the builder finally sees the light and revamps the whole plumbing system. The builder also realizes that when plumbers need to work on the pipes (as they inevitably must), whacking holes in random walls isn't the best approach and burglars could also use those holes to plunder the house. So the builder decides to create access panels through which plumbers can reach the pipes but that shut burglars out.
Everybody lives happily ever after, right? Not really. Plumbers are outraged: Not only has the builder eliminated a huge plumbing market by constructing houses with better pipes, but the builder is also preventing the plumbers from taking the quickest, easiest route to reaching the pipes. No more knocking holes in walls. How dare the builder improve its product in ways that prevent other businesses from profiting from the product's defects?
Karen Forster, be proud! You've captured completely the attitudes of McAfee and Symantec to the Kernel Patch Protection built into Vista x64. Personally, I'm happy to see both of those cruft-ware companies experience as much pain as possible, given the number of PC's I've had to clean up (and how difficult that is) after one of thier suites has inserted tenticles into every nook and cranny of some machine (now no longer functional). I'm still mad about the way McAfee broke pages with largish-viewstate, and the way that went unfixed for literally years.
If you want to know who will play along, Trend-Micro is happy to use Microsoft's new APIs, and I'm a customer because of that respect.
Tuesday, November 07, 2006
I've had this one in the hopper for a while, but recently people have been asking, so...
I was curious about why my Dynamic Reflection Library code was benchmarking as 6% faster than native code (e.g. that produced bu the C# compiler) for reference types, so I did a little disassembly and grokking. Note, I did remember to make sure that the Supress JIT optimization on module load option was not checked and this is a release build with compile-time optimizations enabled.
Here's the native-call code with for a single compile-time call
T child = firstEntry.Breed(secondEntry, (Gender)neighbor);:
0000037a mov eax,dword ptr [ebp-38h]
0000037d mov dword ptr [ebp-70h],eax
00000380 push 0
00000382 push 0
00000384 push 0
00000386 mov ecx,esi
00000388 mov edx,0CA000057h
0000038d call 7919286A
00000392 push edi
00000393 mov edx,dword ptr [ebp-70h]
00000396 mov ecx,dword ptr [ebp-30h]
0000039c call dword ptr [eax]
Now for the explicit generics call for the matching Explicit call
T child = firstEntry.Breed(secondEntry, (Gender)neighbor);:
0000046a push esi
0000046b push ebx
0000046c mov edx,edi
0000046e mov ecx,dword ptr [ebp-60h]
00000471 mov eax,dword ptr [ecx+0Ch]
00000474 mov ecx,dword ptr [ecx+4]
00000477 call eax
That's tons simpler, how come? The simple answer is that since the native call code is dealing with an interface, the code has to go through an indirect call. Meanwhile, the generated delgate code (what my Dynamic class creates) gets JITted out of existence and replaced with a direct call to the actual method on the destination class (Person.Breed in this case). Similar savings all through the test method body leave even more opportunity to keep the locals in registers and the lack of indirect calls saves a bunch of memory/cache-line access per-loop pass.
For my benchmark program (itself an interesting read) the
BenchCallDynamicExplict<Person>(Adjuster<Person>, Random rnd) method loop code (not counting setup and teardown) is 0x1F3 bytes in JIT form, the
BenchCallCompileTime<Person>(Adjuster<Person>, Random rnd) loop code is 0x2E5 bytes, which is 252 bytes longer.
Looking further at this code, if I constrain the
T to be a class (e.g. a reference-type not a value-type/
struct) then I get exactly the same code, so there's no point in that, I modified the benchmark code to remove the "hack" that required a
new() constraint and passed an progenitor instance to eliminate the disadvantage for the compile-time (which needs to go through an interface). Even that doesn't change the code significantly.
The moral of this exercise is that sometimes the generated code, by giving much clearer information to the JIT process about exactly what methods are being called will allow it to generate much faster code. I'm not saying that you should do this kind of optimization everywhere, or indeed almost anywhere, but I am saying that when you write low level code to simplify your life and make things faster, you sometimes get much more than you can expect as a benefit.
Take that C# compiler, I win! Oh, and you guys on the JIT team... you rock!
Not that I like the "version number" any more than I like the whole Web 2.0 thing, but YAY!
Monday, November 06, 2006
With elections one day away (finally!), I was actually brought to tears of laughter by this lovely Ze Frank episode.
Me, I have grown to hate both blueberries and strawberries, though one of the strawberries seems to be pretty good... of course he's fighting a real peach of a blueberry, who I would rather see unemployed than doing the crappy job so far...
Speaking of which, if you want a real auditor, wouldn't it make sense to pick an accountant that isn't a strawberry or blueberry? Maybe we should look a little deeper for some unique flavor.
Of course, that's just my opinion, feel free to think for yourselves...
Friday, November 03, 2006
I've updated my Dynamic LCG-based Reflection wrapper tonight. This new version finally has extensive XML documentation in place. I also refactored a little bit of the code to eliminate duplicate calls and sped up the code a tiny bit.
As of this release, I'm actually 6% faster than native calls (e.g. the code emitted by the C# compiler is actually slower) against reference-types when doing explicit binding to methods. This means that there is realistically little to no cost doing name-based binding to arbitrary methods at runtime.
Head on over to the CodePlex project for more information and the downloads.
Thursday, November 02, 2006
First off, if you don't lurk on CodeProject, I mock you... but assuming you either don't, or just missed this one, Günter Prossliner posted a great bit of code that lets you dynamically "implement" any interface against a class instance by at runtime building a shim class that forwards all the calls through to matching methods in the target.
This is what is commonly called DuckTyping, and allows you to program "as if" an object implements any arbitrary interface, even if it really doesn't inherit from that class. In my Dynamic library, I let you do that for a single method at a time. Günter's code lets you do it an interface at a time, which is obviously cooler if you have multiple methods that you expect a class to implement (and for which you can define an interface).
I think my next weekend project will be to port his code, which uses dynamic assemblies, to use my Dynamic library instead (and thus benefit from LCG).