Ads Header

Sunday, September 19, 2010

10 Tips for Writing High-Performance Web Applications

Sunday, September 19, 2010 by ASP.NET · 0

This article discusses:
  • Common ASP.NET performance myths
  • Useful performance tips and tricks for ASP.NET
  • Suggestions for working with a database from ASP.NET
  • Caching and background processing with ASP.NET
This article uses the following technologies:ASP.NET, .NET Framework, IIS


Writing a Web application with ASP.NET is unbelievably easy. So easy, many developers don't take the time to structure their applications for great performance. In this article, I'm going to present 10 tips for writing high-performance Web apps. I'm not limiting my comments to ASP.NET applications because they are just one subset of Web applications. This article won't be the definitive guide for performance-tuning Web applications—an entire book could easily be devoted to that. Instead, think of this as a good place to start.
Before becoming a workaholic, I used to do a lot of rock climbing. Prior to any big climb, I'd review the route in the guidebook and read the recommendations made by people who had visited the site before. But, no matter how good the guidebook, you need actual rock climbing experience before attempting a particularly challenging climb. Similarly, you can only learn how to write high-performance Web applications when you're faced with either fixing performance problems or running a high-throughput site.
My personal experience comes from having been an infrastructure Program Manager on the ASP.NET team at Microsoft, running and managing www.asp.net, and helping architect Community Server, which is the next version of several well-known ASP.NET applications (ASP.NET Forums, .Text, and nGallery combined into one platform). I'm sure that some of the tips that have helped me will help you as well.
You should think about the separation of your application into logical tiers. You might have heard of the term 3-tier (or n-tier) physical architecture. These are usually prescribed architecture patterns that physically divide functionality across processes and/or hardware. As the system needs to scale, more hardware can easily be added. There is, however, a performance hit associated with process and machine hopping, thus it should be avoided. So, whenever possible, run the ASP.NET pages and their associated components together in the same application.
Because of the separation of code and the boundaries between tiers, using Web services or remoting will decrease performance by 20 percent or more.
The data tier is a bit of a different beast since it is usually better to have dedicated hardware for your database. However, the cost of process hopping to the database is still high, thus performance on the data tier is the first place to look when optimizing your code.
Before diving in to fix performance problems in your applications, make sure you profile your applications to see exactly where the problems lie. Key performance counters (such as the one that indicates the percentage of time spent performing garbage collections) are also very useful for finding out where applications are spending the majority of their time. Yet the places where time is spent are often quite unintuitive.
There are two types of performance improvements described in this article: large optimizations, such as using the ASP.NET Cache, and tiny optimizations that repeat themselves. These tiny optimizations are sometimes the most interesting. You make a small change to code that gets called thousands and thousands of times. With a big optimization, you might see overall performance take a large jump. With a small one, you might shave a few milliseconds on a given request, but when compounded across the total requests per day, it can result in an enormous improvement.

Performance on the Data Tier
When it comes to performance-tuning an application, there is a single litmus test you can use to prioritize work: does the code access the database? If so, how often? Note that the same test could be applied for code that uses Web services or remoting, too, but I'm not covering those in this article.
If you have a database request required in a particular code path and you see other areas such as string manipulations that you want to optimize first, stop and perform your litmus test. Unless you have an egregious performance problem, your time would be better utilized trying to optimize the time spent in and connected to the database, the amount of data returned, and how often you make round-trips to and from the database.
With that general information established, let's look at ten tips that can help your application perform better. I'll begin with the changes that can make the biggest difference.

Tip 1—Return Multiple Resultsets
Review your database code to see if you have request paths that go to the database more than once. Each of those round-trips decreases the number of requests per second your application can serve. By returning multiple resultsets in a single database request, you can cut the total time spent communicating with the database. You'll be making your system more scalable, too, as you'll cut down on the work the database server is doing managing requests.
While you can return multiple resultsets using dynamic SQL, I prefer to use stored procedures. It's arguable whether business logic should reside in a stored procedure, but I think that if logic in a stored procedure can constrain the data returned (reduce the size of the dataset, time spent on the network, and not having to filter the data in the logic tier), it's a good thing.
Using a SqlCommand instance and its ExecuteReader method to populate strongly typed business classes, you can move the resultset pointer forward by calling NextResult. Figure 1 shows a sample conversation populating several ArrayLists with typed classes. Returning only the data you need from the database will additionally decrease memory allocations on your server.

Tip 2—Paged Data Access
The ASP.NET DataGrid exposes a wonderful capability: data paging support. When paging is enabled in the DataGrid, a fixed number of records is shown at a time. Additionally, paging UI is also shown at the bottom of the DataGrid for navigating through the records. The paging UI allows you to navigate backwards and forwards through displayed data, displaying a fixed number of records at a time.
There's one slight wrinkle. Paging with the DataGrid requires all of the data to be bound to the grid. For example, your data layer will need to return all of the data and then the DataGrid will filter all the displayed records based on the current page. If 100,000 records are returned when you're paging through the DataGrid, 99,975 records would be discarded on each request (assuming a page size of 25). As the number of records grows, the performance of the application will suffer as more and more data must be sent on each request.
One good approach to writing better paging code is to use stored procedures. Figure 2 shows a sample stored procedure that pages through the Orders table in the Northwind database. In a nutshell, all you're doing here is passing in the page index and the page size. The appropriate resultset is calculated and then returned.

In Community Server, we wrote a paging server control to do all the data paging. You'll see that I am using the ideas discussed in Tip 1, returning two resultsets from one stored procedure: the total number of records and the requested data.
The total number of records returned can vary depending on the query being executed. For example, a WHERE clause can be used to constrain the data returned. The total number of records to be returned must be known in order to calculate the total pages to be displayed in the paging UI. For example, if there are 1,000,000 total records and a WHERE clause is used that filters this to 1,000 records, the paging logic needs to be aware of the total number of records to properly render the paging UI.

Tip 3—Connection Pooling
Setting up the TCP connection between your Web application and SQL Server can be an expensive operation. Developers at Microsoft have been able to take advantage of connection pooling for some time now, allowing them to reuse connections to the database. Rather than setting up a new TCP connection on each request, a new connection is set up only when one is not available in the connection pool. When the connection is closed, it is returned to the pool where it remains connected to the database, as opposed to completely tearing down that TCP connection.
Of course you need to watch out for leaking connections. Always close your connections when you're finished with them. I repeat: no matter what anyone says about garbage collection within the Microsoft® .NET Framework, always call Close or Dispose explicitly on your connection when you are finished with it. Do not trust the common language runtime (CLR) to clean up and close your connection for you at a predetermined time. The CLR will eventually destroy the class and force the connection closed, but you have no guarantee when the garbage collection on the object will actually happen.
To use connection pooling optimally, there are a couple of rules to live by. First, open the connection, do the work, and then close the connection. It's okay to open and close the connection multiple times on each request if you have to (optimally you apply Tip 1) rather than keeping the connection open and passing it around through different methods. Second, use the same connection string (and the same thread identity if you're using integrated authentication). If you don't use the same connection string, for example customizing the connection string based on the logged-in user, you won't get the same optimization value provided by connection pooling. And if you use integrated authentication while impersonating a large set of users, your pooling will also be much less effective. The .NET CLR data performance counters can be very useful when attempting to track down any performance issues that are related to connection pooling.
Whenever your application is connecting to a resource, such as a database, running in another process, you should optimize by focusing on the time spent connecting to the resource, the time spent sending or retrieving data, and the number of round-trips. Optimizing any kind of process hop in your application is the first place to start to achieve better performance.
The application tier contains the logic that connects to your data layer and transforms data into meaningful class instances and business processes. For example, in Community Server, this is where you populate a Forums or Threads collection, and apply business rules such as permissions; most importantly it is where the Caching logic is performed.

Tip 4—ASP.NET Cache API
One of the very first things you should do before writing a line of application code is architect the application tier to maximize and exploit the ASP.NET Cache feature.
If your components are running within an ASP.NET application, you simply need to include a reference to System.Web.dll in your application project. When you need access to the Cache, use the HttpRuntime.Cache property (the same object is also accessible through Page.Cache and HttpContext.Cache).
There are several rules for caching data. First, if data can be used more than once it's a good candidate for caching. Second, if data is general rather than specific to a given request or user, it's a great candidate for the cache. If the data is user- or request-specific, but is long lived, it can still be cached, but may not be used as frequently. Third, an often overlooked rule is that sometimes you can cache too much. Generally on an x86 machine, you want to run a process with no higher than 800MB of private bytes in order to reduce the chance of an out-of-memory error. Therefore, caching should be bounded. In other words, you may be able to reuse a result of a computation, but if that computation takes 10 parameters, you might attempt to cache on 10 permutations, which will likely get you into trouble. One of the most common support calls for ASP.NET is out-of-memory errors caused by overcaching, especially of large datasets.Common Performance Myths
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. But if good programming practices are followed, there is no reason why Visual Basic and C# code cannot execute with nearly identical performance. To put it more succinctly, similar code produces similar results.
Another myth is that codebehind is faster than inline, which is absolutely false. It doesn't matter where your code for your ASP.NET application lives, whether in a codebehind file or inline with the ASP.NET page. Sometimes I prefer to use inline code as changes don't incur the same update costs as codebehind. For example, with codebehind you have to update the entire codebehind DLL, which can be a scary proposition.
Myth number three is that components are faster than pages. This was true in Classic ASP when compiled COM servers were much faster than VBScript. With ASP.NET, however, both pages and components are classes. Whether your code is inline in a page, within a codebehind, or in a separate component makes little performance difference. Organizationally, it is better to group functionality logically this way, but again it makes no difference with regard to performance.
The final myth I want to dispel is that every functionality that you want to occur between two apps should be implemented as a Web service. Web services should be used to connect disparate systems or to provide remote access to system functionality or behaviors. They should not be used internally to connect two similar systems. While easy to use, there are much better alternatives. The worst thing you can do is use Web services for communicating between ASP and ASP.NET applications running on the same server, which I've witnessed all too frequently.


Figure 3 ASP.NET Cache 
There are a several great features of the Cache that you need to know. The first is that the Cache implements a least-recently-used algorithm, allowing ASP.NET to force a Cache purge—automatically removing unused items from the Cache—if memory is running low. Secondly, the Cache supports expiration dependencies that can force invalidation. These include time, key, and file. Time is often used, but with ASP.NET 2.0 a new and more powerful invalidation type is being introduced: database cache invalidation. This refers to the automatic removal of entries in the cache when data in the database changes. For more information on database cache invalidation, see Dino Esposito's Cutting Edge column in the July 2004 issue of MSDN®Magazine. For a look at the architecture of the cache, see Figure 3.

Tip 5—Per-Request Caching
Earlier in the article, I mentioned that small improvements to frequently traversed code paths can lead to big, overall performance gains. One of my absolute favorites of these is something I've termed per-request caching.
Whereas the Cache API is designed to cache data for a long period or until some condition is met, per-request caching simply means caching the data for the duration of the request. A particular code path is accessed frequently on each request but the data only needs to be fetched, applied, modified, or updated once. This sounds fairly theoretical, so let's consider a concrete example.
In the Forums application of Community Server, each server control used on a page requires personalization data to determine which skin to use, the style sheet to use, as well as other personalization data. Some of this data can be cached for a long period of time, but some data, such as the skin to use for the controls, is fetched once on each request and reused multiple times during the execution of the request.
To accomplish per-request caching, use the ASP.NET HttpContext. An instance of HttpContext is created with every request and is accessible anywhere during that request from the HttpContext.Current property. The HttpContext class has a special Items collection property; objects and data added to this Items collection are cached only for the duration of the request. Just as you can use the Cache to store frequently accessed data, you can use HttpContext.Items to store data that you'll use only on a per-request basis. The logic behind this is simple: data is added to the HttpContext.Items collection when it doesn't exist, and on subsequent lookups the data found in HttpContext.Items is simply returned.

Tip 6—Background Processing
The path through your code should be as fast as possible, right? There may be times when you find yourself performing expensive tasks on each request or once every n requests. Sending out e-mails or parsing and validation of incoming data are just a few examples.
When tearing apart ASP.NET Forums 1.0 and rebuilding what became Community Server, we found that the code path for adding a new post was pretty slow. Each time a post was added, the application first needed to ensure that there were no duplicate posts, then it had to parse the post using a "badword" filter, parse the post for emoticons, tokenize and index the post, add the post to the moderation queue when required, validate attachments, and finally, once posted, send e-mail notifications out to any subscribers. Clearly, that's a lot of work.
It turns out that most of the time was spent in the indexing logic and sending e-mails. Indexing a post was a time-consuming operation, and it turned out that the built-in System.Web.Mail functionality would connect to an SMTP server and send the e-mails serially. As the number of subscribers to a particular post or topic area increased, it would take longer and longer to perform the AddPost function.
Indexing e-mail didn't need to happen on each request. Ideally, we wanted to batch this work together and index 25 posts at a time or send all the e-mails every five minutes. We decided to use the same code I had used to prototype database cache invalidation for what eventually got baked into Visual Studio® 2005.
The Timer class, found in the System.Threading namespace, is a wonderfully useful, but less well-known class in the .NET Framework, at least for Web developers. Once created, the Timer will invoke the specified callback on a thread from the ThreadPool at a configurable interval. This means you can set up code to execute without an incoming request to your ASP.NET application, an ideal situation for background processing. You can do work such as indexing or sending e-mail in this background process too.
There are a couple of problems with this technique, though. If your application domain unloads, the timer instance will stop firing its events. In addition, since the CLR has a hard gate on the number of threads per process, you can get into a situation on a heavily loaded server where timers may not have threads to complete on and can be somewhat delayed. ASP.NET tries to minimize the chances of this happening by reserving a certain number of free threads in the process and only using a portion of the total threads for request processing. However, if you have lots of asynchronous work, this can be an issue.
There is not enough room to go into the code here, but you can download a digestible sample at www.rob-howard.net. Just grab the slides and demos from the Blackbelt TechEd 2004 presentation.

Tip 7—Page Output Caching and Proxy Servers
ASP.NET is your presentation layer (or should be); it consists of pages, user controls, server controls (HttpHandlers and HttpModules), and the content that they generate. If you have an ASP.NET page that generates output, whether HTML, XML, images, or any other data, and you run this code on each request and it generates the same output, you have a great candidate for page output caching.
By simply adding this line to the top of your page you can effectively generate the output for this page once and reuse it multiple times for up to 60 seconds, at which point the page will re-execute and the output will once be again added to the ASP.NET Cache. This behavior can also be accomplished using some lower-level programmatic APIs, too. There are several configurable settings for output caching, such as the VaryByParams attribute just described. VaryByParams just happens to be required, but allows you to specify the HTTP GET or HTTP POST parameters to vary the cache entries. For example, default.aspx?Report=1 or default.aspx?Report=2 could be output-cached by simply setting VaryByParam="Report". Additional parameters can be named by specifying a semicolon-separated list.

Copy Code
<%@ Page OutputCache VaryByParams="none" Duration="60" %>
Many people don't realize that when the Output Cache is used, the ASP.NET page also generates a set of HTTP headers that downstream caching servers, such as those used by the Microsoft Internet Security and Acceleration Server or by Akamai. When HTTP Cache headers are set, the documents can be cached on these network resources, and client requests can be satisfied without having to go back to the origin server.
Using page output caching, then, does not make your application more efficient, but it can potentially reduce the load on your server as downstream caching technology caches documents. Of course, this can only be anonymous content; once it's downstream, you won't see the requests anymore and can't perform authentication to prevent access to it.

Tip 8—Run IIS 6.0 (If Only for Kernel Caching)
If you're not running IIS 6.0 (Windows Server 2003), you're missing out on some great performance enhancements in the Microsoft Web server. In Tip 7, I talked about output caching. In IIS 5.0, a request comes through IIS and then to ASP.NET. When caching is involved, an HttpModule in ASP.NET receives the request, and returns the contents from the Cache.
If you're using IIS 6.0, there is a nice little feature called kernel caching that doesn't require any code changes to ASP.NET. When a request is output-cached by ASP.NET, the IIS kernel cache receives a copy of the cached data. When a request comes from the network driver, a kernel-level driver (no context switch to user mode) receives the request, and if cached, flushes the cached data to the response, and completes execution. This means that when you use kernel-mode caching with IIS and ASP.NET output caching, you'll see unbelievable performance results. At one point during the Visual Studio 2005 development of ASP.NET, I was the program manager responsible for ASP.NET performance. The developers did the magic, but I saw all the reports on a daily basis. The kernel mode caching results were always the most interesting. The common characteristic was network saturation by requests/responses and IIS running at about five percent CPU utilization. It was amazing! There are certainly other reasons for using IIS 6.0, but kernel mode caching is an obvious one.

Tip 9—Use Gzip Compression
While not necessarily a server performance tip (since you might see CPU utilization go up), using gzip compression can decrease the number of bytes sent by your server. This gives the perception of faster pages and also cuts down on bandwidth usage. Depending on the data sent, how well it can be compressed, and whether the client browsers support it (IIS will only send gzip compressed content to clients that support gzip compression, such as Internet Explorer 6.0 and Firefox), your server can serve more requests per second. In fact, just about any time you can decrease the amount of data returned, you will increase requests per second.
The good news is that gzip compression is built into IIS 6.0 and is much better than the gzip compression used in IIS 5.0. Unfortunately, when attempting to turn on gzip compression in IIS 6.0, you may not be able to locate the setting on the properties dialog in IIS. The IIS team built awesome gzip capabilities into the server, but neglected to include an administrative UI for enabling it. To enable gzip compression, you have to spelunk into the innards of the XML configuration settings of IIS 6.0 (which isn't for the faint of heart). By the way, the credit goes to Scott Forsyth of OrcsWeb who helped me figure this out for the www.asp.net severs hosted by OrcsWeb.
Rather than include the procedure in this article, just read the article by Brad Wilson at IIS6 Compression. There's also a Knowledge Base article on enabling compression for ASPX, available at Enable ASPX Compression in IIS. It should be noted, however, that dynamic compression and kernel caching are mutually exclusive on IIS 6.0 due to some implementation details.

Tip 10—Server Control View State
View state is a fancy name for ASP.NET storing some state data in a hidden input field inside the generated page. When the page is posted back to the server, the server can parse, validate, and apply this view state data back to the page's tree of controls. View state is a very powerful capability since it allows state to be persisted with the client and it requires no cookies or server memory to save this state. Many ASP.NET server controls use view state to persist settings made during interactions with elements on the page, for example, saving the current page that is being displayed when paging through data.
There are a number of drawbacks to the use of view state, however. First of all, it increases the total payload of the page both when served and when requested. There is also an additional overhead incurred when serializing or deserializing view state data that is posted back to the server. Lastly, view state increases the memory allocations on the server.
Several server controls, the most well known of which is the DataGrid, tend to make excessive use of view state, even in cases where it is not needed. The default behavior of the ViewState property is enabled, but if you don't need it, you can turn it off at the control or page level. Within a control, you simply set the EnableViewState property to false, or you can set it globally within the page using this setting: If you are not doing postbacks in a page or are always regenerating the controls on a page on each request, you should disable view state at the page level.

Copy Code
<%@ Page EnableViewState="false" %>

Conclusion
I've offered you some tips that I've found useful for writing high-performance ASP.NET applications. As I mentioned at the beginning of this article, this is more a preliminary guide than the last word on ASP.NET performance. (More information on improving the performance of ASP.NET apps can be found at Improving ASP.NET Performance.) Only through your own experience can you find the best way to solve your unique performance problems. However, during your journey, these tips should provide you with good guidance. In software development, there are very few absolutes; every application is unique.
See the sidebar "Common Performance Myths".



Copy Code
CREATE PROCEDURE northwind_OrdersPaged ( @PageIndex int, @PageSize int ) AS BEGIN DECLARE @PageLowerBound int DECLARE @PageUpperBound int DECLARE @RowsToReturn int -- First set the rowcount SET @RowsToReturn = @PageSize * (@PageIndex + 1) SET ROWCOUNT @RowsToReturn -- Set the page bounds SET @PageLowerBound = @PageSize * @PageIndex SET @PageUpperBound = @PageLowerBound + @PageSize + 1 -- Create a temp table to store the select results CREATE TABLE #PageIndex ( IndexId int IDENTITY (1, 1) NOT NULL, OrderID int ) -- Insert into the temp table INSERT INTO #PageIndex (OrderID) SELECT OrderID FROM Orders ORDER BY OrderID DESC -- Return total count SELECT COUNT(OrderID) FROM Orders -- Return paged results SELECT O.* FROM Orders O, #PageIndex PageIndex WHERE O.OrderID = PageIndex.OrderID AND PageIndex.IndexID > @PageLowerBound AND PageIndex.IndexID < @PageUpperBound ORDER BY PageIndex.IndexID END



Copy Code
// read the first resultset reader = command.ExecuteReader(); // read the data from that resultset while (reader.Read()) { suppliers.Add(PopulateSupplierFromIDataReader( reader )); } // read the next resultset reader.NextResult(); // read the data from that second resultset while (reader.Read()) { products.Add(PopulateProductFromIDataReader( reader )); }

Monday, September 13, 2010

A Brief Discussion On Visual Studio 2010 Top Features

Monday, September 13, 2010 by Vips Zadafiya · 0

In this article I will describe about some new features of Visual Studio 2010 which I explored till now. These features are really very useful in terms of productive development. This article is mainly targeted for beginners of Visual Studio 2010 but everybody can get benefit on the same.

Introduction


You guys all know that Microsoft Visual Studio 2010 will be launched on 12-April-2010 worldwide and currently it is in Release Candidate (RC) state. I am exploring it for a while since Beta 2 & found it really useful than the earlier versions. There are lots of features added into the account of Visual Studio 2010 which will improve the productivity of application development. Developers can use it for faster coding, collaborating among the whole team & more. In this post I will describe the new features of Visual Studio 2010 which I already explored. I think this will be beneficial for all.


Following are the new features in Visual Studio 2010.

Multi-targeting Application Development:


Using Visual Studio 2010 you can not only develop applications for the .Net 4.0 but also can use it for the development of earlier versions of the framework. While creating a new project in the IDE you will see the option to select between different types of .Net Framework (i.e. 2.0, 3.0, 3.5 & 4.0).

image
Depending upon your choice it will filter the project templates in the New Project dialog. If you select “.Net Framework 4.0” it will show all the project types but if you select “.Net Framework 2.0” it will only show the projects supported by .Net Framework 2.0.

image
Not only this, as Visual Studio 2010 builds on top of Windows Presentation Foundation (WPF), you will find it more useful while searching for a specific project type. Suppose, you want to develop an application for your client in WPF & you are finding it very difficult to search within a huge collection of project types. Don’t worry. There is a “Search Box” right to the dialog for you to help finding the same. Just enter the keyword (in this case “WPF”) & see the magic. While typing, it will auto filter based on the keyword you entered.

image


Faster Intellisense Support:

Visual Studio now came up with faster intellisense support. It is now 2-5 times faster than the earlier versions. The IDE will now filter your intellisense as you type. Suppose, you want to create an instance of “WeakReference” & due to the search algorithm of the VS2010 IDE, you don’t have to write the full word of the Class. Just type “WR” and it will automatically filter out that & show you “WeakReference” in the intellisense. Try it out.

image


Editor Zoom Functionality:

You will find this feature useful while you are showing some presentation or doing a webcast. Earlier VS2010 you have to open the options panel & then you have to change the font size of the editor, which was little bit troublesome. Now that issue is gone. You don’t have to follow where to go to change the text size. While inside the editor window, just press the control key (CTRL) and use your mouse wheel to increase/decrease the zoom level.

image


Faster Assembly loading in “Add Reference”:

In Visual Studio 2010 loading of assemblies in the “Add Reference” dialog is pretty fast. In earlier versions, it freezes the dialog for some time to load all the assemblies. In 2010 IDE, by default it focuses on the “Project” tab & in the background loads the other tabs. In case it is opening the dialog focusing on the “.Net” tab you will notice that instead of loading all the assemblies at a time, it loads those in a BackgroundThread. Thus improving the loading time a bit faster.

image


Detach Window outside IDE:

Are you working on dual monitor? If so, you will find this feature very useful. VS2010 IDE now supports detaching Window outside the editor. Suppose, you want to detach your “Error”, “Output”, “Solution Explorer” or “Properties” window in the second monitor while working in the editor in the first monitor, you can do that now. Thus it gives you more space in the editor & separating your important windows outside the IDE.

image

Reference Highlight:

Another feature of Visual Studio 2010 IDE is the reference highlight. By this feature, it will highlight you all the call to that method or member variable, which you can find easy enough to search all the position of the reference wherever it has been called.

image


Faster Code Generation:

Before discussing about this feature with you, let me ask you a question “Are you using TDD i.e. Test Driven Development?”. If so, you will find this feature not only useful but very much attractive. So, what is that? Wait, lets ask yourself another question “How to write code while doing Test Driven Development?”. Thinking? Right, you have to implement the skeleton of the class & methods first and then you have to write the UnitTestcases to implement the actual logic. VS2010 came up with the excellent feature of generating codes for you. Have a look into the following snapshot:

image
As you can see, I don’t have a class named “Person” in my project and hence it is marking it as UNKNOWN by highlighting it in Red. If you look into the first snapshot in depth you can find out that though the class is not present in my namespace or even in the project, it is creating the class reference in the intellisense. Great, right? Wait a minute. If you now place you cursor on top of “Person” and press F10 while holding down ALT+Shift, you will see a dropdown comes up in the screen with two menu item asking you to either generate the class for you or generate a new type.

The first option you can find it easy. If you chose that, it will generate a class file named “Person” for you in the project. Lets go for the second choice where you will get more options & will find it much more interesting. This will open up a new dialog “Generate New Type” for you. There you can chose which access modifier you need (private/public/protected/internal), you can chose different types of code to generate (enum/class/struct/interface), you can also modify the location of the class file. You can either put it in the same project or you can chose a different project available in the solution. Not only that, you can also create a new file for the class or append the class in another file. In short, this feature gives you various options to customize.

image
Same thing is applicable while generating methods. Have a look into that.

Box Selection:

This is another nice feature of Visual Studio 2010. Let’s describe this using an example. Suppose, you declared some properties as public & in near future you want to mark them as internal. How can you do this? You will go and replace the access modifier one by one to internal. Am I right? Yup, in Visual Studio 2010 you can do this work very easily. Press Alt+Shift and draw a Box Selection using your cursor which will look like the first snapshot. Then type the desired characters to replace the text within the selected boundary.

image
Here in the example, the public keywords of the properties has been marked using the Box Selector and when typing, it is actually changing in all the lines. Have a look into the second snap where I am typing “internal” to replace “public” and that’s populating in all the lines where I marked.


Easy Navigation:

It is very easy now when you want to navigate to your specific code. As Visual Studio 2010 is built on top of WPF hence it has now proper filtering as and when you type. Press CTRL+, to open up the “Navigate To” dialog and this will show a list of matching criteria once you start typing in the “Search terms” field.

image

Better Toolbox Support:

Visual Studio now came up with better Toolbox support. You can now search Toolbox Item very easily. Just type the desired name of the Toolbox Item and the IDE will jump into the focus of matched element. Pressing TAB will bring the focus to the next matching element.

image

Breakpoints:

It has now a better feature in terms of Bookmarks. A team can now collaborate bookmarks between them by using the import/export bookmarks. You can now pin the debug value so that you can access it in later point of time, also you can now add a label to your bookmark.

image

Lets give a brief idea on this. Suppose, you are debugging your module & while debugging you found an issue in another’s module and want to let him know that there is a bug in his code and creating issues in your module. Just sending out an information requires debugging to the code again & finding out the issue by the another team member. Now in VS2010 IDE, you can now pin the debug value and export that bookmark with proper comments as an XML & send it out to your another team member. Once he imports it to his IDE, he can see the bookmark with the debug value available from the last session. From this point he can debug the root cause instead of finding out the area again. This is very useful in terms of collaborating debug information with the team.

image

The only thing that I don’t like here is, the XML which uses line number to store the breakpoint information. If the code has been modified in the other member side, it will not work correctly. The only requirements of the import/export to work correctly is “There should not be any modification in the shared code file”.

IntelliTrace:

Visual Studio has now the feature called “IntelliTrace” by which you can trace each step of your debug points. This is very useful when it comes to a larger UI where you can find the calling thread information in the IntelliTrace Window.

image


Conclusion


There are more features like better TFS Support, in-built support for Cloud development, modeling, reports etc. which I have not explored till now. Once I explore those, will post it as a separate thread. So for now, go ahead and learn Visual Studio 2010 features and get familiar with it for productive development.

Thursday, September 9, 2010

Web Application Testing Tools - Open Source

Thursday, September 9, 2010 by Unknown · 1

Many organizations are surprised to find that it is more expensive to do testing using tools. In order to gain benefits from testing tools, careful thought must be given for which tests you want to use tools and to the tool being chosen.

Anteater is a testing framework designed around Ant, from the Apache Jakarta Project. It is basically a set of Ant tasks for the functional testing of Web sites and Web services (functional testing being: hit a URL and ensure the response meets certain criteria). One can test HTTP parameters, response codes, XPath, regexp, and Relax NG expressions. Anteater also includes HTML reporting (based on junitreport) and a hierarchical grouping system for quickly configuring large test scripts. When a Web request is received, Anteater can check the parameters of the request and send a response accordingly. This makes it useful for testing SOAP and XML applications.

The ability to wait for incoming HTTP messages is something unique to Anteater, which makes it especially useful when building tests for applications that use high level SOAP-based communication, like ebXML or BizTalk. Applications written using these protocols usually receive SOAP messages and send back a meaningless response. It is only later that they inform the client, using an HTTP request on the client, about the results of the processing. These are the so-called asynchronous SOAP messages, and are the heart of many high-level protocols based on SOAP or XML messages.

Written in Java, HttpUnit emulates the relevant portions of browser behavior, including form submission, Javascript, basic HTTP authentication, cookies, and automatic page redirection, and allows Java test code to examine returned pages either as text, an XML DOM, or containers of forms, tables, and links.

jWebUnit is a Java framework which facilitates creation of acceptance tests for Web applications. It provides a high-level API for navigating a Web application combined with a set of assertions to verify the application's correctness. This includes navigation via links, form entry and submission, validation of table contents, and other typical business Web application features. It utilizes HttpUnit behind the scenes. The simple navigation methods and ready-to-use assertions allow for more rapid test creation than using only JUnit and HttpUnit.

Bugkilla is a tool set to create, maintain, execute, and analyze functional system tests of Web applications. Specification and execution of tests is automated for both the Web frontend and business logic layers. One goal is to integrate with existing frameworks and tools (an Eclipse Plugin exists)

The Grinder, a Java load testing framework freely available under a BSD-style Open Source license, makes it easy to orchestrate the activities of a test script in many processes across many machines, using a graphical console application. Test scripts make use of client code embodied in Java plugins. Most users of The Grinder do not write plugins themselves; they use one of the supplied plugins. The Grinder comes with a mature plugin for testing HTTP services, as well as a tool which allows HTTP scripts to be automatically recorded.

Jameleon is an automated testing tool that separates applications into features and allows those features to be tied together independently, creating test cases. These test cases can then be data-driven and executed against different environments. Jameleon breaks applications into features and allows testing at any level, simply by passing in different data for the same test. Because Jameleon is based on Java and XML, there is no need to learn a proprietary technology.

It's an acceptance testing tool for testing the functionality provided by applications, and currently supports the testing of Web applications. It differs from regular HttpUnit and jWebUnit in that it separates testing of features from the actual test cases themselves. If I understand it correctly, you write the feature tests separately and then script them together into a reusable test case. Incidentally, you can also make these test cases data-driven, which gives an easy way of running specific tests on specific environments.

The framework has a plugin architecture, allowing different functional testing tools to be used, and there is a plugin for testing Web applications using HttpUnit/jWebUnit. The test case scripting is done with XML and Jelly.

Jameleon combines XDoclet, Ant and Jelly to provide a potentially powerful framework for solid functional testing of your Webapp. It strikes a good balance between scripting and coding, and allows you to set up multiple inputs per test by providing input via CSV files. Along with the flexibility come a complexity and maintenance overhead, but you are getting your Webapp tested for you.

LogiTest is the core application in the LogiTest suite. LogiTest is designed to aid in the testing of Web site functionality. It currently supports HTTP and HTTPS protocols, GET and POST methods, multiple document views, custom headers, and more. The LogiTest application provides a simple graphical user interface for creating and playing back tests for testing Internet-based applications.

Solex is a set of Eclipse plugins providing non-regression and stress tests of Web application servers. Test scripts are recorded from Internet browsers, thanks to a built-in Web proxy. For some Web applications, a request depends on a previous server's response. To address such a requirement, Solex introduces the concept of extraction and replacement rules. An extraction rule tied to an HTTP message's content will bind an extracted value with a variable. A replacement rule will replace any part of an HTTP message with variable content.

The tool therefore provides an easy way to extract URL parameters, Header values, or any part of a request or a response, bind their values with variables, and then replace URL parameters, Header values, or any part of a request with the variable content. The user has the ability to add assertions for each response. Once a response has been received, all assertions of this response will be called to ensure that it is valid. If not, the playback process is stopped. Several kinds of rules and assertions are provided. The most complicated ones support regular expressions and XPath.

Tclwebtest is a tool for writing automated tests of Web applications in Tcl. It implements some basic HTML parsing functionality to provide comfortable commands for operations on the HTML elements (most importantly forms) of the result pages.

TagUnit is a framework through which custom tags can be tested inside the container and in isolation from the pages on which they will ultimately be used. In essence, it's a tag library for testing tags within JSP pages. This means that it is easy to unit test tags, including the content that they generate and the side effects that they have on the environment, such as the introduction of scripting variables, page context attributes, cookies, etc.

Web Form Flooder is a Java console utility that analyzes a Web page, completes any forms present on the page with reasonable data, and submits the data. It crawls links within the site in order to identify and flood additional forms that may be present. It is great for load testing of Web forms, checking that all links work and that forms submit correctly.

XmlTestSuite provides a powerful way to test Web applications. Writing tests requires only knowledge of HTML and XML. The authors want XmlTestSuite to be adopted by testers, business analysts, and Web developers who don't have a Java background. XmlTestSuite supports "test-driven development". It lets you separate page structure from tests and test data. It can also verify databases. It's like JWebUnit, but has simple XML test definitions and reusable pages. The problems with raw HTTPUnit or JWebUnit are that:

  1. It's very hard to get non-programmers to write tests.
  2. Tests are so ugly you can't read them. (Trust me; HttpUnit test classes are a nightmare to maintain.)
  3. Web tests generally change far more often than unit tests, and so need to be altered, but your refactoring won't change them automatically (i.e., changing a JSP in IDEA will not cascade to the test like changing a class will).

Wednesday, September 8, 2010

IIS 7 Compression. Good? Bad? How much?

Wednesday, September 8, 2010 by ASP.NET · 0


IIS 7 Compression. Good? Bad? How much?

If you haven't properly utilized compression in IIS, you're missing out on a lot!  Compression is a trade-off of CPU for Bandwidth.  With the expense of bandwidth and relative abundance of CPU, it's an easy trade-off.  Yet, are you sure that your server is tuned optimally?  I wasn't, which is why I finally sat down to find out for sure.  I'll share the findings here.
A few years ago I wrote about compression on IIS 6.  With IIS 6, the Microsoft defaults were a long ways off of the optimum settings, and a number of changes were necessary before IIS Compression worked well.  My goal here is to dig deep into IIS 7 compression and find out the impact that the various compression levels have, and to see how much adjusting is needed to finely tune a Windows web server.
Note: If you don't care about all the details, jump right down to the conclusion.  I've made sure to put the key review information there.

What's my purpose here?

 To find out the bandwidth savings for the different compression levels, contrast them against the performance impact on the system and come up with a recommended configuration.

Understanding IIS 7 and its Differences from IIS 6

IIS 6 allowed compression per extension type (i.e. aspx, html, txt, etc) and allowed it to be turned on and off per site, folder or file.  Making changes wasn't easy to do, but it was possible with a bit of scripting or editing of the metabase file directly.
IIS 7 changes this somewhat.  Instead of compression per extension, it's per mime type.   Additionally, it's easier to enable or disable compression per server/site/folder/file in IIS 7.  It's configurable from IIS Manager, Appcmd.exe, web.config and all programming APIs.
Additionally, IIS 7 gives the ability to have compression automatically stopped when the CPU on the server is above a set threshold.  This means that when CPU is freely available, compression will be applied, but when CPU isn't available, it is temporarily disabled so that it won't overburden the server.  Thanks IIS team!  These settings are easily configurable, which I'll cover more in a future blog post.
Both IIS6 and IIS7 allow 11 levels of compression (actually 'Off' and 10 levels of 'On').  The goal for this post is to compare the various levels and see the impact of each.

Objectives and Rules

The first thing I had to do was determine what tests I wanted to run, and how I could achieve them.  I also wanted to ensure that I could clearly see the differences between the various levels.  Here are some key objectives that I set for myself:
  1. Various file sizes: All tests had to be applied to various sizes of files.  I initially tested using the default IIS7 homepage (689bytes), a 4kb file, a 28kb file and a 516kb file.  I figured that would give a good range of common file sizes.

    As it turned out, part way through I discovered that performance is severely affected on files of about 200kb and greater, so I did another series of tests on 100kb, 200kb, 400kb and 800kb files.
     
  2. Test compression only:  It was important to me that compression was the only factor and that other variables didn't cloud the picture.  For that reason, all of my test pages generate almost no CPU on their own.  Almost all of the CPU increases in my tests are from compression only.
     
  3. Compression ratio:  I used Port 80 Software's free online web tool to get the compression amount.
     
  4. Stress Testing:  I used Microsoft's free WCAT tool.  For the heavy load testing I used two WCAT client servers so that I can test the IIS server to the limit.  One client couldn't quite bring the IIS server to 100% CPU.
     
  5. Baseline Transactions per Second: After testing for a while, I realized that the most useful data was with a fixed trans/sec goal.  Otherwise, if I tested with a virtually instant page and thousands of transactions per second, the compression resource usage is unrealistic and the data confusing.  Very few real-life IIS servers handle thousands of very-fast pages per second.  So, to make the numbers more useful, I added a 125ms delay to each page so that my server could serve up 120trans/sec with 0% CPU when compression is turned off.
     
  6. Compression at all CPU Levels: I had to turn off the CPU roll-off so that all pages are compressed, even at 100% CPU.  IIS 7's default setting of CPU roll-off is great, but it gets in the way of this testing.
     
  7. Solid Computer: Since compression is CPU bound, it's important that the server isn't a dinosaur.  The test server is a Dell M600 with a Quad Core Intel Xeon processor (E5405 @ 2.00Ghz). The server only has 1GB of RAM but the physical memory was never used up for these tests, so it had all the memory that it needed.  The disks are SAS, 10K RPM in a RAID 1 configuration.
I'll include the raw data at the bottom of the post for anyone that is interested.
Let's take a look at the results.

Compression Levels

IIS 7 Compression Ratio
As shown in the graph here, the largest increase was between compression level 3 and 4.  After that, the compression improvements were very gradual.  However, if you check out the raw data below though, every level offered at least some incremental benefit.

Time to First Byte

Here's a fun test I've always wanted to do, but never got around to it.  I was curious how quickly a compressed vs. a non-compressed page would load under minimal server load.  In other words, if there is plenty of CPU to spare, does a compressed page load at near line-speed?  While both Time to First Byte (TTFB)--when the page starts to load--and Time to Last Byte (TTLB)--when the page finishes loading--are valuable, I felt that the TTFB gave the picture that I needed.
IIS 7 Compression - TTFB
As you can see, all but the 516kb came in at about 0 milliseconds, even compressed.  Note that the 28kb and 4kb lines are hidden behind the 689 bytes line.  Even the 516kb file came in at under 80ms.  What's 80ms??  That's very low unless you have a really busy site.  As far as I'm concerned from this data, even a 516kb file loads at line speed as long as the server isn't bogged down.  
Let's think about the 80ms a bit more.  Dynamic pages, database calls and other factors play a much bigger role.  Plus, the <80ms saves over 300kb on the page transfer, which is a savings of 2.34 seconds on a 1Mbps line!  (Calculation based on: 300kbytes savings.  A 1Mbps line will transfer 1024Kbps/8 = 128KB per second.  300/128KB/s = 2.34 seconds)
All of the smaller pages load almost instantly, so the impression that the end user gets from a non-pegged server is going to be better with compression on.  Note that my testing doesn't take Internet latency and limits into account.  So, as long as the server can compress it at near line speed, it's going to benefit the site visitor all the more.

CPU Perspective

The following two charts are from a second round of testing that I did, so the file sizes are different than in the previous test.  In my first round of testing I found that the file size makes a huge difference.  With anything under 100kb, the compression overhead is almost non-existent.  However, once you have file sizes of a couple hundred kb or greater, the CPU overhead is significant.
I ran the tests on 100kb, 200kb, 400kb and 800kb files.  To put the size in perspective, I spent a good 10 minutes getting content from various sites to come up with 800kb of text.  I used pages like this from Scott Guthrie's blog, and it still took multiple pages to collect 800kb of text.  That particular page only has 145kb of text on it, but it's 440kb in size because of the HTML mark-up.  So, a 400kb file isn't overly common (not many people have as many blog comments as Scott Gu), but it's certainly possible.
To obtain a good CPU chart, I had to use some trickery.  I wanted to create a test where I could hit the server as hard as a heavily utilized server is hit, but somehow keep non-compression related CPU to 0.  I achieved this by using System.Threading.Thread.Sleep(125) in the pages.  This sets a 125ms delay that doesn't use any CPU.  Then I set the WCAT thread count to 30 per server (2 WCAT client computers).  This became my baseline since, with these settings, the IIS server handled 120 Transactions/second.  From looking at some busy production servers here at ORCS Web, I concluded that that was a reasonable level for a busy server.  The CPU load without compression was nearly zero, so I was pleased with this test case. 
IIS 7 Compression - CPU Usage
I found this the most interesting.  Notice that each file size hit a sweet spot at a different compression level.  For example, if you figure that your files are mostly 200kb and smaller, you may want to use Compression Level 4, which uses almost no CPU for a 200kb file. 
This is on a Quad Core server, targeting 120 transactions/second.  As you can see, if you plan to have that level of traffic on your server, and your file sizes are into the hundreds of kilobytes, you may want to watch the compression utilization on the server.  It may be using more resources that you realize.  I don't think most people have much to worry about though as the average page size is less than 100kb, and the load on the average server is often much less than 120 transactions/second.
I'll mention more in the conclusion, but it's worth briefly mentioning now that you should consider having different compression levels for static and dynamic content.  Static content is compressed and cached, so it's only compressed once until the next time the file is changed.  For that reason, you probably don't care too much about the CPU overhead and can go with a setting of 9. 
On the other hand, dynamic pages are compressed every time (for the most part, although further details on cached dynamic pages can be found here).  So, the setting for the dynamic compression level is much more important to understand.
This also lets us realize that it would be foolish to turn on compression just for the fun of it.  Formats that don't compress much (or are already compressed) like JPG's, EXE's, ZIP's and the like, are often large and the CPU overhead to try to compress them further could be substantial.  These aren't compressed by default in IIS 7.

Transactions per Second

IIS 7 Compression - Transactions per second
Just as a reminder, my goal was to start with 120 transactions/sec.  The server could handle much more, but this was controlled so that 120 was considered the base.  That was achieved with <1% CPU when non-compressed.
Notice that 100kb and 200kb files can still be served up at nearly the same rate.  Once you get to 800kb file sizes though, the server spends massive computing power to compress each page.  Part of that isn't just compression related.  Notice that even with compression turned off, IIS could only serve up 80 Transactions/sec using the same WCAT settings.  However, the transacctions/sec drops off considerably with each compression level.

Conclusion

So, what is my recommendation?  Your mileage will vary, depending on the types of files that you serve up and how active your involvement in the server is.
One great feature that IIS 7 offers is the CPU roll-off.  When CPU gets beyond a certain level, IIS will stop compressing pages, and when it drops below a different level, it will start up again.  This is controlled by the staticCompressionEnableCpuUsage and dynamicCompressionDisableCpuUsage attributes.  That in itself offers a large safety net, protecting you from any surprises.
Based on the data collected, the sweet spot seems to be compression level 4.  It's between 3 and 4 that the compression benefit jumps, but it's between 4 and 5 that the resource usage jumps, making 4 a nice balance between ‘almost full compression levels' and ‘not quite as bad on resource usage'.
Since static files are only compressed once until they are changed again, it's safe to leave them at the default level of 7, or even move it all the way to 9 if you want to compress every last bit out of it.  Unless you have thousands of files that aren't individually called very often, I recommend the higher the better.
For dynamic, there is a lot to consider.  If you have a server that isn't CPU heavy, and you actively administer the server, then crank up the level as far as it will go.  If you are worried that you'll forget about compression in the future when the server gets busier, and you want a safe setting that you can set and forget, then leave at the default of 0, or move to 4.
Make sure that you don't compress non-compressible large files like JPG, GIF, EXE, ZIP.  Their native format already compresses them, and the extra attempts to compress them will use up valuable system resources, for little or no benefit.
Microsoft's default of 0 for dynamic and 7 for static is safe.  Not only is it safe, it is aggressive enough to give you ‘most' of the benefit of compression with minimal system resource overhead.  Don't forget that the default *does not* enable dynamic compression. 
My recommendation is, first and foremost, to make sure that you haven't forgotten to enable dynamic compression.  In almost all cases it's well worth it, unless bandwidth is free for you and you run your servers very hot (on CPU).  Since bandwidth is so much more expensive than CPU, moving forward I'll be suggesting 4 for dynamic and 9 for static to get the best balance of compression and system utilization.  At this setting, I can set and forget for the most part, although when I run into a situation when a server runs hot, I'll be sure to experiment with compression turned off to see what impact compression has in that situation.
Disclaimer: I've run these tests this last week and haven't fully burned in or tested these settings in production over time, so it's possible that my recommendation will change over time.  Use the data above and use my recommendations at your own risk.  That said, I feel comfortable with my recommendation for myself, if that means anything.  Additionally, at ORCS Web, we've run both static and dynamic at level 9 for years and have never attributed compression as the culprit to heavy CPU on production servers.  My test load of 120 transactions/sec is probably more than most production servers handle, so even 9 for both static and dynamic could be a safe setting in many situations.

The How

Here are some AppCmd.exe commands that you can use to make the changes, or to add to your build scripts.  Just paste them into the command prompt and you're good to go.  Watch for line breaks.
Enable Dynamic Compression, and ensure Static compression at the server level:
Alternately, apply for just a single site (make sure to update the site name):
To set the compression level, run the following (this can only be applied at the server level):
IIS 7 only sets GZip by default. If you use Deflate, run the previous command for Deflate too.
Note that when changing the compression level, an IISReset is required for it to take effect.

Data

In case the raw data interests you, I've provided it here.
Compression ratio


Level 400kb Text 28kb Text 1kb Text 516kb text

Size % Size % Size % Size %
Off 3904 0% 28274 0% 689 0% 528834 0%
0 1713 57% 13878 51% 594 14% 238630 55%
1 1636 59% 12825 55% 588 15% 221751 59%
2 1597 60% 12342 57% 587 15% 213669 60%
3 1592 60% 11988 58% 587 15% 206795 61%
4 1434 64% 11400 60% 457 34% 190362 65%
5 1428 64% 11228 61% 457 34% 184649 66%
6 1428 64% 11158 61% 457 34% 181087 66%
7 1428 64% 11151 61% 457 34% 180620 66%
8 1428 64% 11150 61% 457 34% 180485 66%
9 1428 64% 11150 61% 457 34% 180481 66%
CPU Usage per Compression Level


Level 100kb 200kb 400kb 800kb

CPU T/sec CPU T/sec CPU T/sec CPU T/sec
Off 1% 120 1% 119 3% 103 6% 81
0 1% 125 1% 115 11% 117 65% 83
1 1% 112 1% 113 42% 103 59% 73
2 1% 126 1% 123 48% 103 65% 76
3 1% 122 2% 125 44% 107 79% 75
4 1% 120 2% 122 43% 95 79% 62
5 1% 120 44% 111 68% 79 90% 47
6 6% 117 47% 111 83% 75 95% 33
7 27% 105 57% 117 83% 70 98% 31
8 45% 105 60% 120 84% 66 98% 29
9 45% 90 60% 90 84% 66 98% 29


Time to First Byte (TTFB) - minimal load.  In milliseconds.


Level 4kb 28kb 689bytes 516kb
Off 0 0 0 0
0 0 0 0 15
1 0 0 0 24
2 0 0 0 26
3 0 0 0 33
4 0 0 0 40
5 0 0 0 57
6 0 0 0 78
7 0 0 0 79
8 0 0 0 78
9 0 0 0 78

Comments

Best Practice No 4:- Improve bandwidth performance of ASP.NET sites using IIS compression » Technology Articles - Technology And Programming Articles said: