The success of Vista is of obvious importance to any developer targeting any Vista-only or Vista-enhanced technology, so the latest news that Vista sales are strong and higher than expected is of obvious interest.
It appears that Vista has been a stunning success for Microsoft, surprizing even the optimists inside the Redmond empire. This stands is a stark contrast with reports of general consumer apathy about this release, and many dire predictions about Vista's adoption (predictions that are dubious, given that Vista is pretty much assured a reasonable level of success given its automatic sale to virtually anyone buying a new PC. Corporations naturally delay adoption of new operating systems, as they have with every prior edition, so only a delusional expected it to storm across business desktops).
You can see their Q3 return on the SEC site. Under the Client division, you can clearly see that revenue has rocketed up, from $3.151 billion in Q3 2006, to $5.272 billion in Q3 2007.
There are a couple of massive, almost-Enronesque caveats to these numbers that deserve some serious scrutiny before you start your Vista-only product launch.
Firstly, they deferred $1.2 billion of XP sales from Q1 and Q2 2007 -- sales that qualified for the upgrade coupon -- rolling it into this result.
Client revenue increased for the three months ended March 31, 2007, primarily reflecting licensing of Windows Vista, including recognition of approximately $1.2 billion of revenue previously deferred in fiscal year 2007 pending the January 2007 release to consumers.
Counting out that rather dubious bit of accounting trickery drops the gross revenue to a growth of just $0.8 billion over the year earlier.
Secondly, some of the gain is attributed to the price premium applied to Vista Premium (effectively imposing a price increase over prior XP licenses, as most PC makers automatically deliver the Premium edition.)
During the quarter, the OEM premium mix increased 18 percentage points over the prior year to 71% driven by the demand for Windows Vista Home Premium.
Not to mention that the computer market in general has grown over a year earlier.
Based on our preliminary estimates, total worldwide PC shipments from all sources grew 10% to 12% from the third quarter of the previous year and approximately 8% to 10% from the first nine months of the previous year driven by strong consumer demand in both emerging and mature markets.
Not quite as successful as some reports are claiming: After a year of market growth, subtracting the hard-to-rationalize rolling-forward trickery, and considering that the price for the operating system was effectively raised via the Premium edition, and suddenly the situation doesn't look quite as rosey.
Rough back-of-a-napkin calculations have OS unit sales remaining relatively flat after incorporating in market growth. If this exceeded inside-of-Microsoft estimates, then clearly they're either lying, or they were expecting an implosion. Applauding about Vista's lofty percentage of OS sales should be quelled by the reality that virtually every new client PC OS sold now is Vista -- if a corporation does want XP, their recourse now is to buy a Vista license that grants them the right to install XP, though it'll carefully get added as another vote of confidence by the Microsoft beancounters.
There are several other surprizes in their Q3 report. For instance that the entertainment division (Xbox, Zune) saw revenue drop over a year earlier, and that the Online Services Business -- this is where Microsoft put a lot of attention recently, with the huge push of the Live platform -- saw a marginal revenue increase, with a significant loss increase.
The only bright spot of the whole quarterly report, from my perspective, is the business systems division: Office 2007 has seen good adoption and has very healthily contributed to earnings.
Reports that this quarterly report validates Vista's success are unfounded. Further, it puts a huge question mark over Microsoft's web and hardware initiatives (the complete failure of the diversification to actually add to the bottom line, instead of just drowning in losses -- excused early on as toothing pains, but there doesn't seem to be a point when they'll actually make money -- should raise serious concern. Microsoft is still held aloft by Windows and Office).
I mentioned Microsoft's new Silverlight platform a week ago, opining that it appeared to be nothing more than a Flash competitor...despite all the noise, enthusiasm and bluster that comes out of the gathering of the faithful (Mix '07).
If Flash wasn't already the answer for a particular problem space -- and it seldom is necessary or beneficial given the incredible power and versatility of the foundational web technologies -- why would Silverlight change the equation?
For those instances where Flash is an appropriate solution, the question then is what Silverlight brings to the table that Flash doesn't? What could possibly overcome the new entrant's already limited platform coverage and concerning vendor conflict of interest? Is Silverlight really just another attempt at pushing Windows Media, released as a last-ditch attempt to recapture some of the marketshare that WMV has lost, largely to Flash of all players.
The answer came as Mix progressed, when it was announced that the Silverlight platform will optionally come equipped with a .NET Common Language Runtime (the common language of course being Common Intermediate Language), equipped with a greatly pruned down Framework: the runtime and the framework occupy 2MB, so clearly it's only a tiny subset of the full .NET 2/3 framework.
Supposedly the CIL really is the same CIL used in our desktop and server .NET apps, so hypothetically a given assembly can be used on the desktop, in Silverlight on Windows, and even on Silverlight on the Mac (or any other platform that Microsoft decides to target), which is interesting.
In practice it's never that easy. The minimized framework included with Silverlight means that a lot of code will have dependencies that aren't satisfied in Silverlight, similar to the experiences many will have attempting to run .NET code on a Mono platform (despite Mono having a vastly larger Framework to draw from).
What it does mean, however, is that code (which before deployment will be "compiled" from whatever source language to the remarkably high-level Intermediate Language, much like you can use tools to "compile" Java to JavaScript, or Wasabi to PHP, or between any other Turing-complete language) run within Silverlight will likely demonstrate excellent performance: The .NET team has done a superb job of teasing great performance out of managed code, and I would expect that to carry over to Silverlight as well.
Silverlight was completely uninteresting before, but this new information makes me somewhat curious, and it does technologically differentiate the product.
This should light some fires under the team incorporating the JavaScript Tamarin engine (which humorously came from Flash) in Mozilla products. As it currently stands, the JavaScript interpreter in Mozilla is among the performance frontrunners, however that pack in general is proving to be unacceptably slow as the web becomes increasingly rich.
The Tamarin engine, and similar designs, hyper-accelerates things by doing JIT compilation of ECMAScript Edition 4 (JavaScript 2) to native code where possible, offering potentially enormous performance improvements.
Back to Silverlight, I laugh at those who are giddy with glee about the death of "HTML", or the coming of "Web 3.0" (which is an embarrassing comment being bandied about in regards to Silverlight).
Were Java Applets Web 3.0? Was ActiveX Web 3.0? Was VRML Web 3.0? Flash/Shockwave have been with us since Web 0.9.
Put a Remote Desktop ActiveX control on a page and people will declare it Web 3.0. Who knows, maybe Google will do just that.
Many garbage-collected languages feature "immutable" strings -- once a value is assigned, it can't be manipulated without creating a new instance (either explicitly or implicitly), with obvious performance implications.
Let's start with a scenario where you're concatenating the string variable B and C into the resulting string A.
A = B + C;


Because of the immutability of strings, this is effectively what you're doing even when you're simply concatenating onto a string, and it's for this reason that string-concatenation is often a ghastly slow affair. Many developers have faced this when building a string through concatenation in a loop, for instance dynamically generating a TABLE and its content, or building an XML document.
Consider the following:
myString = myString + "A";
As visualized above, generally that would cause the runtime to create a new memory allocation large enough to hold the concatenated length, then copy the first value and then the second value to the new buffer.
In a loop, where a string is continually adding new content to the end of itself -- a very common need -- the performance will generally take quadratic time (as it's repeatedly allocating and copying a larger and larger string).
I've encountered this frequently enough in .NET, deciding when the ugliness and heft of a StringBuilder is necessitated versus when to just suck up the terrible concatenation performance, however this came up recently in a web project requiring a large amount of display data to be dynamically constructed on the client end.
JavaScript doesn't have a native string builder (a big oversight), so I needed to evaluate how basic string concatenation compared with some of the hackish string builder similes for disparate cases. I was quickly reminded that while Firefox doesn't have great string concatenation performance, it absolutely annihilates Internet Explorer (incl. 7) doing the same.
Try this basic benchmark in both browsers to see for yourself: On the machine I'm typing this on, Firefox completes 131,072 iterations in 1984ms, while Internet Explorer had only completed 32768 iterations after 11078ms (not only did just 1/4 the iterations take 5 times as long, but the iterations it did complete were the smaller, much easier ones, making the disparity much greater than it appears).
I became curious how Firefox implemented string concatenation so performantly, and from that to extrapolate how the Internet Explorer team screwed it up so royally, and honestly to see if I could easily tease even more performance out of it. Given that we have the source (and the ability to easily change it and build it to test differences), I jumped into js/jsstr.c in the Firefox source to take a look (all code subject to the MPL and the Mozilla Foundation retains all rights).
JSString *
js_ConcatStrings(JSContext *cx, JSString *left, JSString *right)
{
size_t rn, ln, lrdist, n;
jschar *rs, *ls, *s;
JSDependentString *ldep; /* non-null if left should become dependent */
JSString *str;
if (JSSTRING_IS_DEPENDENT(right)) {
rn = JSSTRDEP_LENGTH(right);
rs = JSSTRDEP_CHARS(right);
} else {
rn = right->length;
rs = right->chars;
}
if (rn == 0)
return left;
if (JSSTRING_IS_DEPENDENT(left) ||
!(*js_GetGCThingFlags(left) & GCF_MUTABLE)) {
/* We must copy if left does not own a buffer to realloc. */
ln = JSSTRING_LENGTH(left);
if (ln == 0)
return right;
ls = JSSTRING_CHARS(left);
s = (jschar *) JS_malloc(cx, (ln + rn + 1) * sizeof(jschar));
if (!s)
return NULL;
js_strncpy(s, ls, ln);
ldep = NULL;
} else {
/* We can realloc left's space and make it depend on our result. */
ln = left->length;
if (ln == 0)
return right;
ls = left->chars;
s = (jschar *) JS_realloc(cx, ls, (ln + rn + 1) * sizeof(jschar));
if (!s)
return NULL;
/* Take care: right could depend on left! */
lrdist = (size_t)(rs - ls);
if (lrdist < ln)
rs = s + lrdist;
left->chars = ls = s;
ldep = JSSTRDEP(left);
}
js_strncpy(s + ln, rs, rn);
n = ln + rn;
s[n] = 0;
str = js_NewString(cx, s, n, GCF_MUTABLE);
if (!str) {
/* Out of memory: clean up any space we (re-)allocated. */
if (!ldep) {
JS_free(cx, s);
} else {
s = JS_realloc(cx, ls, (ln + 1) * sizeof(jschar));
if (s)
left->chars = s;
}
} else {
/* Morph left into a dependent prefix if we realloc'd its buffer. */
if (ldep) {
JSPREFIX_SET_LENGTH(ldep, ln);
JSPREFIX_SET_BASE(ldep, str);
#ifdef DEBUG
{
JSRuntime *rt = cx->runtime;
JS_RUNTIME_METER(rt, liveDependentStrings);
JS_RUNTIME_METER(rt, totalDependentStrings);
JS_LOCK_RUNTIME_VOID(rt,
(rt->strdepLengthSum += (double)ln,
rt->strdepLengthSquaredSum += (double)ln * (double)ln));
}
#endif
}
}
return str;
}
The key to Mozilla's performance is this line, and the surrounding concept of "dependant" strings:
s = (jschar *) JS_realloc(cx, ls, (ln + rn + 1) * sizeof(jschar));
In a nutshell, when you perform the operation A = B +
C, where B and C are strings, it reallocates the memory
assigned to B -- depending upon the memory manager and
fragmentation, this can often be done in place with no memory copy
-- setting B to indicate that it is now a dependant string (e.g.
"don't free the associated memory when you garbage collect B"),
then copying C to the tail.


A and B are now pointing to the same location in memory. In a loop where a string is adding to itself, it is just constantly realloc'ing -- copying to a new memory location when the memory manager can't expand the requested amount in place, otherwise just doing a land grab of memory trailing the string -- and copying the new data on the end.
Changing this bit of code to do a straight new malloc and copy
on all concatenations yielded an executable with Internet
Explorer-like glacially slow string concats, exactly as
expected.
Which made me curious: What if we predictively accommodated the often growing nature of strings, allocating a bit of extra space at the outset, making it more likely that realloc's could be accommodated in place? In the grand scheme of things, the memory taken by JavaScript strings is marginally small, so a little extra padding on result-of-concatenation strings shouldn't hurt.
I implemented the following function in js/jsstr.c.
size_t js_GetNextSize(size_t desired_size)
{
int max = 0, i;
for (i = 1; i != JSSTRFLAG_DEPENDENT; i <<= 1)
{
if (desired_size & i)
{
max = i;
}
}
if (max)
{
return max << 1;
} else
{
return desired_size;
}
}
That's nothing more than a trivial implementation of ceil(log2(n)), however I tried to implement in the most transparent, cross-platform way possible.
Now I changed the realloc line referenced above to read:
s = (jschar *) JS_realloc(cx, ls, js_GetNextSize((ln + rn + 1) * sizeof(jschar)));
All reallocs will be to the next power of 2 of the requested size -- if a realloc demands 37 bytes, it'll allocate 64 bytes, and if it demands 7 bytes then it'll allocate 8 -- trading a relatively small amount of memory usage for processing time and memory bandwidth.
Re-running the benchmark linked earlier now shows my custom build of Firefox completing 131,072 iterations in 60 to 90ms (versus 1984ms before, so it completed it in less than 1/20th the time of the already speedy Firefox. Internet Explorer would take minutes to perform that many iterations). Firefox memory usage has not changed to a measurable degree, even during heavy browsing.
This change -- allocating a little extra space to accommodate realloc calls -- is likely the technique used in Opera 9, as this turbo version of Firefox was neck and neck with the speedy Opera 9 on this bit of functionality.
Now to delve through other parts of the excellent JavaScript
code...
The need for always available email had me recently
equipping up with a Motorola Q
Windows Mobile 5-based smartphone. With
Exchange Direct Push email capabilities (where the device opens
an idled HTTP connection, being notified expediently when new
messages are available with the minimum of data throughput), it has
served the core purpose admirably, and is a wonderfully handy
little device.
The addition of wireless, always-available communications has made it infinitely more useful than prior abandoned outings with PDAs.
Ultimately it's a Blackberry(TM) competitor. While I'm only 60km from RIM headquarters, for me this was a better device than the more commonly chosen option. In this case the technology infrastructure didn't require a third-party to unnecessarily act as an middleman of messages.
I don't only use it for email, though. Every now and then the device serves secondary duty as a web browsing tool: The landscape QVGA screen isn't exactly copious, but it's enough for basic browsing for some sites, catching up on tech news and happenings in situations where a traditional network isn't available, and I don't want to open up a laptop.
This blog looks great on it. The "content" column perfectly filling the screen by luck rather than intent. The homepage requires an excessive 229KB of transfers, but at least most of those bytes are filled with content text. Nonetheless, I think I'm going to change the settings to show fewer days of history on the main page.
Despite the grand pronouncements by the telcos about their high speed, next generation networks, the speed is often closer to dial-up, and where throughput is high the latency is often poor, making pages with dozens of elements a time consuming affair. Even with a speedy connection, many telcos have low throughput limits with exorbitant fees beyond that.
Loading a page like Joel's discussion page -- a very basic text discussion site -- remarkably pegs in at 280KB or so of transfers (grab a copy of the extraordinary Firebug add-in for Firefox and look at the Net tab. It is often eye opening), overwhelmingly for scripts that have no use on the discussion site.
Sure, caching helps for subsequent requests, but on small devices there's often little room set aside to cache 100s of KBs of irrelevant scripts. Worse, the linked versioning -- adding a date version number as a parameter -- used by Joel and crew has seen the cached scripts invalidated frequently.
It's too bad there wasn't a, err, "function-level linking" for JavaScript, automatically eliminating all of the unused script from pages that don't require it.
One of the better sites for mobile browsing is Google: Recognizing the limits of the device (presumably by noting the Mozilla/4.0 (compatible; MSIE 4.01; Windows CE; Smartphone; 176x220) user agent string -- not sure why it says 176x220 when the actual resolution of the device is 320x200), it renders a pared-down (even more!) version of the search engine, better still automatically proxying search results through an agent that filters pages down to more mobile friendly forms. Very nice.
It's a good thing that Google filters results, as many sites just render terribly in the small confines of QVGA on a Windows Mobile 5 device.
Obviously the mobile browsing market is a tiny, but growing, contingent of users, but it is something I'm going to pay more heed to. Too often we presume that everyone has a 7Mbps high speed pipe feeding an ultra high resolution display, when that isn't always the case. As smartphones continue to take off, and providers facilitate use by easing off on the restrictions and excessive charges, it's going to become a very important market.
Every now and then I browse over to the popular Coding Horror blog: It's like turning on an episode of the A-Team and collapsing into a comfortable couch on a hot summer day, ice cubes clinking around in a sweaty cup of lemonade.
It's a nice way to zone out, distracting my consciousness from a vexing problem in hopes that a background process running in the Brain.ThreadPool completes and returns a solution.
A recent entry, C# and the Compilation Tax, piqued my interest, reminding me of a prior entry I posted about Edit and Continue (where I discussed the potential over-reliance on automated helpers.)
In his post, the Coding Horror author observes that in actual use .NET has evolved into a single language environment, with C# increasingly dominating (though it's doppelgänger, VB.NET, is only a marginally different variant -- C# is the Lexus ES300 to VB.NET's Toyota Camry).
Who knew? Would you also believe that the Java Virtual Machine can be targeted by languages other than Java?
Cats and dogs getting along! Microsoft and Linux making up (see also: Microsoft the Patent Troll)! Robert Mugabe the economic development champion!
He goes on to note his disappointment that the Visual Studio IDE doesn't support automatic, continuous compilation for C# projects, which would enable it to quickly highlight egregious mistakes in his code.
In the comments to his post, I offered up the opinion that the reliance upon such a piece of functionality might be detrimental to the craft of software development.
Jeff,
I encourage you to go a week with minimal automated code-correctness checks. When you've gotten to the point where you rely upon continuous automated checks (which can miss a tremendous number of problems where the code is syntactically and type correct, but logically broken), you've seriously harmed your craftsmanship.
Dennis Forbes on May 15, 2007 07:10 AM
Mr Atwood replied-
Dennis,
Ah yes, that old logical trap. Better tooling makes us weak! It's a crutch we begin to rely on that cheapens our craft!
This is even debunked all the way back in Mythical Man-Month:
"There is a widespread recognition that debugging is the hard and slow part of system programming, and slow turnaround is the bane of debugging. So the logic of interactive programming seems inexorable."
http://www.codinghorror.com/blog/archives/000026.htmlAnd then, as for the logical fallacy of "easy tools make you weak":
"So let's get real. Bad programmers write bad code. Good programmers write good code. RAD lets bad programmers write bad code faster. RAD does NOT cause good programmers to suddenly start writing bad code."
http://www.codinghorror.com/blog/archives/000090.htmlThis isn't a zero-sum game; better tools let good programmers work faster. The bad programmers, well, it doesn't really matter what you give them because the output will be the same: disappointing.
Logical fallacy...zero-sum...a reference to the Mythical Man-Month...add in "orthogonal" and you've got a Score:5 on your hands.
In between appeals to authority -- Jeff is a big fan of Code Complete and the Mythical Man-Month, always ready to quote them as the indisputable, final word on all matters relating to software development -- Jeff makes the critical, err, "logical fallacy" of presuming that my questioning of his automatic compilation dependency (to avoid assigning literal integers to strings, apparently) is an indictment of all accouterments of software development.
Hardly, Jeff. It might make for a convenient strawman, but it's certainly not the argument being presented.
I'm not calling for a return to punch-card programming, or even back to the days when we'd reference our 50lbs of Visual C++ reference material to lookup the parameters of an API function.
I even think IntelliSense is quite a great little bit of functionality.
When you're randomly typing garbage into your editor, complaining that the continuous invocation of the compilation shortcut is cramping your style (and your fingers), however, you've developed a serious problem.
Sometimes these features are there to coddle a beginner, carefully keeping them within the painted lines and away from the dangerous electrical sockets along the wall. That would explain why it was a more important feature in VB.NET than C#...not that VB.NET is any more trivial -- it's just a syntactic variant -- but it is the language that beginner programmers are generally guided into.
And to his last point: My experience has been that the best developers just naturally start using less and less "helpers", to the extreme where you have incontestably great developers like Linus Torvalds arguing against fundamental helpers like interactive debuggers.
I'm certainly nowhere near as extreme as Mr. Torvalds -- indeed, apparently Linus has softened his stance somewhat -- but I wouldn't dare to claim his experienced perspective "debunked" because Fred Brooks -- operating in an environment where what is defined as "immediacy" would be glacially slow by today's standards, and whose metrics had nothing to do with Edit and Continue or continuous automatic compilation -- can be selectively reinterpreted and applied against a completely different world.
Sorry, Jeff, but I don't buy the infinite monkeys on an infinite number of keyboards model of software development. I can only envision tools like continuous compilation and edit and continue as the hand-holding of beginners, and the crutch of hacks.
Jeff Atwood, of Coding Horror fame, recently rebutted my post "Beginners and Hacks", which itself was a reply to his post "C# and the Compilation Tax".
Jeff makes some great points, but at the outset I have to disagree with his statement "The present model of software development is clearly monkeys all the way down. And if you're offended to be lumped in with the infinite monkey brigade, I'd say that's incontestable proof that you're one of us."
No, Jeff, I don't develop via the Infinite Monkeys Model. It disturbs me that any professional in this industry would volunteer for such a pejorative.
While humility is often a good thing, there is a limit. Every developer can't be Linus Torvalds or John Carmack, but every single developer should still have professional self-respect, and a desire to do and be the best that they can.
As for my denial of membership in the worldwide IMB representing "incontestable proof" that I'm among that group, that comment had me reminiscing about a shop I worked in about a decade ago: A new hire had proposed a questionable set of development changes, some of which I was passionately opposed to. He dismissed such disagreement via a hilarious bit of circular reasoning--
a) If you passionately disagree, you are being
"defensive"
b) If you're being defensive per the definition given in a),
it must be because you are wrong.
It's a simple, comforting way of dismissing opposing perspectives:
Everyone who disagrees is just being defensive because they're
wrong. It was so remarkable that it has always stuck with me as an
example of self-delusional perception.
Jeff goes on to compare his apparent utter dependence on continuous compilation code checking with squiggle-line spell-checking. Even if I were to accept that simile, which I don't at all, let's humor that comparison for a moment.
I've written about the importance of correct spelling before, and have lauded the integration of automatic, continuous spellchecking in Firefox. I'm typing this entry in Microsoft Word, which has helpfully alerted me to several misspellings (mostly the result of typos).
I greatly appreciate these tools, and how they help me with the craft of writing.
Yet I'm not a professional writer. I am, in actuality, a hack and a beginner.
By noting that differentiation, am I then saying that a professional, dedicated-to-the-craft writer would actively abhor such a tool (see the Frank Navasky character from You've Got Mail as just such an anti-technology luddite)?
Of course not, and that is not and has never been the argument I'm making. Those who jump to such a conclusion are just being defensive, and thus, we have learned, must be wrong. No I'm not calling for editing in notepad, or making shoes like we made them 150 years ago.
Instead I'd wager that you'd find the average professional writer, dedicated to the craft of putting words to print, has dramatically less dependency on such accoutrements than "beginners and hacks": They have elevated their creations to the point where something as rudimentary as spelling no longer represents a significant part of their "problem". They compose their creations so carefully that they're less likely to have such errors in the first place: When every line is a conscientious, careful, considered work of art, it's less likely that a typo-detection utility is as important.
For a blowhard blogger like me, vomiting paragraphs of raw thought into an editor, this sort of handholding is much more important, and the use of spell-checking actually speaks directly to my point. Writing is not my craft, and these literary creations aren't craftsmanship. I've even been known to mix up it's and its on occasion, to the delight of my critics.
This brings us to the crux of the whole "debate": It was never about the advanced functionality of tools, or even the use of said features or whether they "annoy" me or not, but instead I'm speaking to a growing trend of laziness and carelessness in coding, where developers emit screens of code (probably gloating about their remarkable LOC achievements), and after spending as much time fixing up the many automatically detected errors they spend weeks trying to diagnose the much more insidious logic, design and usage errors that almost certainly permeate their creation.
If their work is so carelessly authored that they consider continuous automated correctness checks a heavily leaned upon, necessary feature of their environment, then I wouldn't put much stock in the quality otherwise.
That is the problem that I argued against, simply stating that when you feel naked and abandoned without these assistants, finding yourself automatically doing frequent compilations to catch egregious mistakes, then you've probably lost touch of the craft, and one's work isn't getting the loving attention it deserves.