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   

My Links

Ads Via DevMavens

Archives

Post Categories

 

I am a Microsoft MVP for ASP.NET.
I am an ASPInsider.
<March 2010>
SMTWTFS
28123456
78910111213
14151617181920
21222324252627
28293031123
45678910

Comment Stats

DayTotal% of Total
Sunday 2056.8%
Monday 42514.1%
Tuesday 51917.2%
Wednesday 55518.4%
Thursday 58019.2%
Friday 54718.1%
Saturday 1886.2%
Total 3019100.0%

Hour1Total% of Total
12:00 AM 782.6%
1:00 AM 812.7%
2:00 AM 682.3%
3:00 AM 822.7%
4:00 AM 692.3%
5:00 AM 1264.2%
6:00 AM 1183.9%
7:00 AM 1816.0%
8:00 AM 1926.4%
9:00 AM 1585.2%
10:00 AM 1886.2%
11:00 AM 1936.4%
12:00 PM 2016.7%
1:00 PM 1846.1%
2:00 PM 1695.6%
3:00 PM 1354.5%
4:00 PM 1153.8%
5:00 PM 1073.5%
6:00 PM 1013.3%
7:00 PM 1073.5%
8:00 PM 923.0%
9:00 PM 882.9%
10:00 PM 913.0%
11:00 PM 953.1%
Total 3019100.0%

Comments by Blog Entry Date/Time

Day Entry MadeAvg.Total
Sunday 4.97159
Monday 4.80384
Tuesday 4.04477
Wednesday 7.39680
Thursday 6.26676
Friday 5.07466
Saturday 4.78177
Total 5.403019

Hour1 Entry MadeAvg.Total
12:00 AM 5.2937
1:00 AM 1.002
5:00 AM 0.000
7:00 AM 3.8550
8:00 AM 3.72134
9:00 AM 6.06297
10:00 AM 5.63276
11:00 AM 4.22194
12:00 PM 6.16351
1:00 PM 3.09133
2:00 PM 4.89230
3:00 PM 7.64321
4:00 PM 4.00108
5:00 PM 6.07170
6:00 PM 4.64116
7:00 PM 8.95188
8:00 PM 8.63164
9:00 PM 5.00115
10:00 PM 6.31101
11:00 PM 4.5732
Total 5.403019

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


Blog Stats

Favorite Web Sites

My Books

My MSDN Articles