Scott on Writing

Musings on technical writing...

Rob Howard's 10 Tips for Writing High-Performance Web Applications

Rob Howard recently authored an article for MSDN Magazine titled 10 Tips for Writing High-Performance Web Applications.  This article, which contains a lot of material from Rob's Black-Belt ASP.NET Talk given at TechEd this year, offers the following performance tips:

  1. Return multiple recordsets
  2. Efficiently page data access
  3. Connection pooling
  4. Use the ASP.NET Cache API
  5. Per-Request Caching
  6. Background Processing
  7. Page Output Caching & Proxy Servers
  8. Run IIS 6.0 for Kernel Caching
  9. Use GZip Compression
  10. Watch That Server Control View State

I think the #1 performance issue for many ASP.NET applications is bloated view state.  Yes, all of the other tips will improve your performance, but slimming down a page's view state bloat can cut several kilobytes to thousands of kilobytes from your page, thereby increasing both the download and upload (i.e., postback) speed of the page.  Trust me, I know a thing or two about large view state.

When Rob mentioned tip 5, Per-Request Caching, in his TechEd talk, the topic interested me so I wrote an article on it: HttpContext.Items - a Per-Request Cache Store.

Another gem from Rob's article is the Common Performance Myths sidebar, which points out the following:

  • C# code is not faster than VB.NET code
  • ASP.NET page's using code-behind are not faster than ASP.NET page's using the inline method
  • Placing logic in .NET components does not provide a performance benefit over putting that logic directly in the ASP.NET page.
  • Web services should only be used to connect disparate systems or provide remove access to system functionality.  They should not be used as the conduit between two similar, local systems.  As Rob says in the article: “Optimizing any kind of process hop in your application is the first place to start to achieve better performance.“  And Web services are far from performant when compared to technologies designed to transmit data in a specialized protocol optimized for a particular architecture or platform.

One thing I wonder about, though, is Rob's suggestion for paging through large amounts of data.  He suggests using a stored procedure with a temporary table into which you dump the entire contents of the data to page through, and then use a join to snip out the particular records for the specified page (granted, you're just dumping in the primary key field, which is likely already (partially) in memory, so the operation should go fast).  However, in some very rough and very unscientific tests I ran on my database server a couple years ago, this technique started taking several seconds per page once there were hundreds of thousands of records being paged through.  I ought to rerun these tests, though, and in a more controlled environment, since this is the technique used for the ASP.NET Forums, and the ASP.NET Forums seem to page through data efficiently enough.

What I'd really be interested in is comparing this technique to Justin Lovell's technique for SQL pagination, which uses a temporary table like Rob's approach, but rather than dumping the entire contents in, uses a cursor to just snipe out the appropriate number.  (This, of course, requires that you remember the last ID of the page of data you are stepping through, which prohibits you from allowing users to jump to an arbitrary page.)  If limiting oneself to only Next/Previous paging functionality is acceptable, I typically use this approach, myself, which I found to be able to scream through large amounts of data that the stored procedure technique Rob discussed choked on (performance-wise).

Has anyone out there run any sound tests comparing various paging techniques?  I'd be interested in seeing the data...

posted on Wednesday, November 17, 2004 11:32 AM

Feedback

# Vil du have performance? 11/17/2004 3:42 PM guidmaster

Jeg kan kun bakke op omkring Michells entry omkring performace af asp.net applikationer! L

# Bookmark: ASP.NET Performance Techniques 11/17/2004 7:11 PM snook.ca - a collection of tips, tricks and bookma

Scott recaps Rob Howard's 10 tips for writing high performance web applications and adds some interesting info on pagination. Returning multiple recordsets is high on my list of optimizations. It's also one of the reasons I don't like MySQL. As...

# ASP.NET Performance Tips 11/17/2004 9:50 PM Joel's Virtual Desktop

# ASP.NET Performance Tips 11/17/2004 9:50 PM Joel Ross

# re: Rob Howard's 10 Tips for Writing High-Performance Web Applications 11/18/2004 7:05 AM aspnetman

how is the data stored for the articles in the ASP.NET forums? text, ntext?

# re: Rob Howard's 10 Tips for Writing High-Performance Web Applications 11/18/2004 7:25 AM Scott Mitchell

aspnetman, the ASP.NET Forums stores the data for each post as ntext. Here's the table definition, which is available if you download the Community Server :: Forums code from TelligentSystems.com [http://telligentsystems.com/Solutions/forums/]

CREATE TABLE [forums_Posts] (
[PostID] [int] IDENTITY (1, 1) NOT NULL ,
[ThreadID] [int] NOT NULL ,
[ParentID] [int] NOT NULL ,
[PostAuthor] [nvarchar] (64) NOT NULL ,
[UserID] [int] NOT NULL ,
[ForumID] [int] NOT NULL ,
[PostLevel] [int] NOT NULL ,
[SortOrder] [int] NOT NULL ,
[Subject] [nvarchar] (256) NOT NULL ,
[PostDate] [datetime] NOT NULL ,
[IsApproved] [bit] NOT NULL ,
[IsLocked] [bit] NOT NULL ,
[IsIndexed] [bit] NOT NULL ,
[TotalViews] [int] NOT NULL ,
[Body] [ntext] NOT NULL ,
[FormattedBody] [ntext] NOT NULL ,
[IPAddress] [nvarchar] (32) NOT NULL ,
[PostType] [int] NOT NULL ,
[EmoticonID] [int] NOT NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

# re: Rob Howard's 10 Tips for Writing High-Performance Web Applications 11/19/2004 9:34 AM Marshall Brooke

I use the SP approach but I keep a track of the TotalCount for the result set and pass this value between ASP.NET and SQL. If the TotalCount=0 then I need to put all the records into a temp table to get the TotalCount. Otherwise, I use SET ROWCOUNT to the upper page size of the query meaning for pagesize=10,the first page only requires the first ten records to be put into the temp table (SET ROWCOUNT 10). The last page will require all records to be put into the temp table, but this is a pretty good performance point otherwise.

# re: Common Performance Myths 11/29/2004 8:15 AM anon

"One of the most common myths is that C# code is faster than Visual Basic code. There is a grain of truth in this, as it is possible to take several performance-hindering actions in Visual Basic that are not possible to accomplish in C#, such as not explicitly declaring types."

# re: Rob Howard's 10 Tips for Writing High-Performance Web Applications 1/4/2005 7:56 PM George Hicks

Unfortunately, the method you mention only sorts by PK. The temp table method allows for sorts on other fields.

Incidentally, if anyone runs a test, I'd also be interested how this non-temp table compares. I'm not exactly sure where I came across this but it works well when I've used it. Here's the pseudo sql:

select top pagesize fields
from table
where condition
and pkey not in (
select top ((pagesize*pagenum)-1) pkey
from table
where condition
order by sortlist
)

select count(pkey) from table
where conditionorder by sortlist

# Upcoming Talk at the SoCal .NET Technical Summit 8/24/2006 7:28 AM Scott on Writing

# Upcoming Talk at the SoCal .NET Technical Summit 8/24/2006 7:56 AM Community Blogs

On Saturday, September 23rd, I'll be speaking at the SoCal .NET Technical Summit in Irvine, CA at the

Title:  
Name:  
Url:
Protected by Clearscreen.SharpHIPEnter the code you see:
Comments   

Add To Your Reader

My Links

Archives

Post Categories

 

I am a Microsoft MVP for ASP.NET.
I am an ASPInsider.
<May 2008>
SMTWTFS
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

Comment Stats

DayTotal% of Total
Sunday 1866.8%
Monday 37913.9%
Tuesday 45316.7%
Wednesday 50418.5%
Thursday 53519.7%
Friday 49418.2%
Saturday 1666.1%
Total 2717100.0%

Hour1Total% of Total
12:00 AM 652.4%
1:00 AM 682.5%
2:00 AM 622.3%
3:00 AM 742.7%
4:00 AM 572.1%
5:00 AM 1033.8%
6:00 AM 1084.0%
7:00 AM 1585.8%
8:00 AM 1716.3%
9:00 AM 1475.4%
10:00 AM 1716.3%
11:00 AM 1816.7%
12:00 PM 1886.9%
1:00 PM 1696.2%
2:00 PM 1605.9%
3:00 PM 1324.9%
4:00 PM 1073.9%
5:00 PM 923.4%
6:00 PM 913.3%
7:00 PM 963.5%
8:00 PM 833.1%
9:00 PM 782.9%
10:00 PM 792.9%
11:00 PM 772.8%
Total 2717100.0%

Comments by Blog Entry Date/Time

Day Entry MadeAvg.Total
Sunday 5.54144
Monday 5.22339
Tuesday 4.28419
Wednesday 7.67637
Thursday 6.90607
Friday 5.48411
Saturday 5.33160
Total 5.842717

Hour1 Entry MadeAvg.Total
12:00 AM 5.0035
1:00 AM 1.002
5:00 AM 0.000
7:00 AM 7.0035
8:00 AM 5.35107
9:00 AM 6.32278
10:00 AM 6.47246
11:00 AM 4.41181
12:00 PM 6.88330
1:00 PM 3.00111
2:00 PM 5.41222
3:00 PM 8.64285
4:00 PM 4.0589
5:00 PM 5.92154
6:00 PM 4.52113
7:00 PM 9.67174
8:00 PM 9.80147
9:00 PM 5.05111
10:00 PM 5.4265
11:00 PM 4.5732
Total 5.842717

Learn More About Comment Stats
1 - All times GMT -8...


Blog Stats

Favorite Web Sites

My Books

My MSDN Articles