Why Interleaved Text Outperforms Response.Write

Introduction
In his article Performance Metrics for the ASP Response Object
James Greenwood noted some interesting things with IIS 5.0. His benchmarks showed that a style of ASP
coding that interleaves script (VBScript) with text is faster than using pure script (with the
Response.Write method). This article examines why this should be so in IIS 5.0.

Two Coding Styles
The two coding styles that are being compared are illustrated by these fragments of code. The first
fragment shows how to use interleaved text to render HTML content:

For n = 1 To 500000
%>.<%
Next

While this example shows how to output HTML using ASP's Response.Write syntax:

For n = 1 To 500000
Response.Write "."
Next

The "interleaved text" style is commonly used in classic ASP pages, and is comprised of VBScript
server-side code appearing inside script delimiters (<% ... %>) or in
<Script> blocks interleaved with fragments of text. Some refer to this as
"context-switching," thinking that the ASP interpreter has to switch from an HTML context to a
VBScript context. In the "pure script" style, all the output is done via the Response.Write
method.

James Greenwood clocked the "Interleaved Text" fragment at 0.534 seconds while the "Pure Script"
clocked in at 0.721 seconds. Actual mileage will vary depending upon your configuration, but there
are sound architectural reasons why the interleaved text is faster in IIS 5.0.

ASP Architecture from 50,000 ft.
When an HTTP request comes in for an Active Server Page, the ASP engine reads the requested ASP page.
It then translates the text (text outside of the script blocks) into script method calls to output
text. Note that this step is performed only one time and that it is performed before the page is sent
down to the script engine. The ASP script engine may cache the ASP pages in this "pre-processed" form
so that subsequent requests for the same page may omit this step.

This means that in the "Interleaved Text" sample above, that ASP translates the %>.<%
into something like (but not exactly) Response.Write ".".
After the page has been translated into script, the page is given to the scripting engine (typically
VBScript), and the script engine executes the page producing the HTTP response. (This is a very high
level view of ASP architecture – see John Flander's book ASP
Internals for more details.)

The Hidden WriteBlock Method
Since the interleaved text code outperforms the pure script code, what is ASP doing? By intercepting
the code that was sent down to the scripting engine, I found that the ASP engine is translating non-script
text into a call to a hidden Response method called WriteBlock. The WriteBlock
method is visible in the type library for ASP, but is barely documented. Here's how it works:
The WriteBlock method takes a block number as a parameter, the block number refers to a block that the
ASP engine has in its memory area. The VBScript engine in this case does not have the text of the
block that will be written. All the script engine has is a numeric identifier that tells the ASP
engine to output that block.

You can call the WriteBlock method yourself, if you like. For example:

<%@ Language=VBScript %>

Hello
<%%>
World
<% Response.WriteBlock(0) %>

This fragment will write output Hello World Hello because ASP tags the first block ("Hello")
as block 0. When the Response.WriteBlock statement is encountered, it simply outputs it
again. To complete this example, here's the approximate text that the VBScript engine will receive:

Response.WriteBlock(0)
Response.WriteBlock(1)
Response.WriteBlock(0)

The first WriteBlock refers to the string "Hello"; the second to "World"; and the third
to "Hello". The script engine has no idea that ASP generated the first two script calls while we
"manually" inserted the third. To it, script is script.

Why is it Faster?
We've said that ASP pages are translated into script before the script engine gets the page. We've
said that text blocks are mapped into a call to the hidden Response method WriteBlock.
Still, why is this faster?
The answer is that by building a string table (the blocks) before the script engine processes the
page, the ASP page is able to perform certain optimizations that ordinarily would not occur. By using
WriteBlock, ASP is able to store the text in the same form that will be outputted to the
browser. The Response.Write method, by contrast converts the text from Unicode to the
output character set each time that it is called.

Referring to the original benchmark fragments, the interleaved text fragment is going to convert the
"." to the output format only once. The pure script fragment is going to do it fifty-thousand times.
This accounts for the performance difference.

A Methodological Note
Considering the ASP architecture as described above, you may see that the time for the script to
execute is not necessarily the complete time to process the ASP page. Script timers cannot measure
the time that it takes to translate the mixed text and script into just script because the script
itself does not start running until the pre-processing is complete.
This points to a small flaw in the script timer methodology – namely that the time to translate the
page into script is not counted.

Practical Implications
What are the practical implications if interleaved text is faster than pure script? It means nothing.
Write so that your code is readable and maintainable. If the purpose it to display unchanging text,
then use text outside of a script block. If the output needs programmatic control, use script. If
you find yourself coding Response.Write statements with many quoted quotes ("""" - to escape
the quotes), then maybe a interleaving some text will make your code more readable.

What About the With Statement?
Stayed tuned for the next installment where we consider another interesting point from James
Greenwood's article: why is the VBScript With statement so slow? Until then,

About the AuthorRoger Kaiser Jr. is a freelance programmer residing
40 miles west of Philadelphia, PA. He is seeking beta testers and heavily loaded ASP web sites for
an ASP Performance and Optimization toolkit that he is developing. You may contact him at
Roger.Kaiser@Kennett.net.