Most Active Server Pages (ASP) applications use string connections to Create HTML-formatted data that is presented to users. This article compares several methods for creating this HTML data stream. In specific cases, some methods are superior to other methods in terms of performance. This document assumes that you have some ASP and Visual Basic programming knowledge.
Directory
- Introduction
- ASP design
- String connection
- Quick Solution
- StringBuilder
- Built-in Method
- Test
- Result
- Summary
Introduction
When compiling an ASP page, developers actually create a formatted text stream.ResponseThe object is written to the Web Client. There are multiple ways to create this text stream, and the method you choose will have a great impact on the performance and scalability of Web applications. Many times, when I helped customers optimize the performance of their Web applications, I found that one of the more effective methods is to change the way HTML streams are created. This article will introduce several common technologies and test their impact on the performance of a simple ASP page.
ASP design
Many ASP developers follow good software engineering principles and try to modularize their code as much as possible. This design usually uses some include files that contain functions that are formatted and generated for specific discontinuous parts of the page. The string output of these functions (usually HTML table code) can be combined to create a complete page. Some developers have improved this method by moving these HTML functions to the Visual Basic COM component to take full advantage of the additional performance provided by compiled code.
Although this design method is good, the method used to create strings that comprise these discontinuous HTML code components will have a great impact on the performance and scalability of the Web site, whether the actual operation is performed in the ASP inclusion file or in the Visual Basic COM component.
String connection
See the followingWriteHTMLThe code snippet of the function. The parameter named Data is just a string array that contains some Data to be formatted as a table structure (for example, Data returned from the database ).
Function WriteHTML( Data )Dim nRepFor nRep = 0 to 99 sHTML = sHTML & vbcrlf _ & "<TR><TD>" & (nRep + 1) & "</TD><TD>" _ & Data( 0, nRep ) & "</TD><TD>" _ & Data( 1, nRep ) & "</TD><TD>" _ & Data( 2, nRep ) & "</TD><TD>" _ & Data( 3, nRep ) & "</TD><TD>" _ & Data( 4, nRep ) & "</TD><TD>" _ & Data( 5, nRep ) & "</TD></TR>"NextWriteHTML = sHTMLEnd Function
This is often used by many ASP and Visual Basic developers to Create HTML code. The text contained in The sHTML variable is returned to the call code, and thenResponse. WriteWrite Data to the client. Of course, this can also be expressed as direct embedding, not includingWriteHTMLFunction page similar code. The problem with this Code is that the string data type (BSTR or Basic string) used by ASP and Visual Basic cannot actually change the length. This means that whenever the length of a string changes, the original representation of the string in the memory will be damaged, and a new representation containing the new string data will be created: this will increase the memory allocation and unallocation operations. Of course, ASP and Visual Basic have solved this problem for you, so the actual overhead will not appear immediately. Memory Allocation and memory unallocation require that all dedicated locks be removed from the Code in the basic runtime era, which requires a large amount of overhead. This problem is especially evident when strings become large and large memory is rapidly allocated and unallocated consecutively, just as it occurs during large string connections. Although this problem has little impact on the single-user environment, in the server environment (for example, ASP applications running on Web servers, it causes serious performance and scalability problems.
Next, let's go back to the above code snippet: How many string allocation operations will be performed in this code? The answer is 16. In this case,&
"Every application of the operator will cause the variablesHTML
The specified string is damaged and re-created. As mentioned above, the overhead of string allocation is large and increases with the increase of the string, so we can improve the above Code.
Quick Solution
There are two ways to reduce the effect of string connection. The first method is to reduce the size of the string to be processed, and the second method is to reduce the number of string Allocation Operations. See the followingWriteHTMLThe version of the code.
Function WriteHTML( Data )Dim nRepFor nRep = 0 to 99 sHTML = sHTML & ( vbcrlf _ & "<TR><TD>" & (nRep + 1) & "</TD><TD>" _ & Data( 0, nRep ) & "</TD><TD>" _ & Data( 1, nRep ) & "</TD><TD>" _ & Data( 2, nRep ) & "</TD><TD>" _ & Data( 3, nRep ) & "</TD><TD>" _ & Data( 4, nRep ) & "</TD><TD>" _ & Data( 5, nRep ) & "</TD></TR>" )NextWriteHTML = sHTMLEnd Function
At first glance, it may be difficult to find the difference between this code and the previous code example. In fact, this code is only insHTML = sHTML &
The following content is enclosed in parentheses. This actually reduces the size of strings processed in most string join operations by changing the priority. In the original code example, the ASP compiler will view the expression on the right of the equal sign and perform computation from left to right. As a result, 16 connection operations are required for each repeat.sHTML
. In the new version, We prompt the compiler to change the operation sequence. Now, it calculates the expression from left to right, from inside the brackets to outside the brackets. This technology allows each repeat to include 15 connection operations. These operations are aimed at small strings that will not grow, and only one operation is aimed at the increasing size.sHTML
. Figure 1 shows the comparison between this optimization method and the standard connection method in memory usage mode.
Figure 1: Comparison between standard connections and brackets in memory usage mode
In specific circumstances, using parentheses can have a significant impact on performance and scalability, which will be further described later.
StringBuilder
We have found a quick way to solve the problem of string connection. In most cases, this method can achieve the best balance between performance and investment. However, to further improve the performance of building large strings, you need to use the second method, that is, to reduce the number of string Allocation Operations. To do this, you need to useStringBuilder. StringBuilder is a class used to maintain configurable string buffers, manage new text fragments inserted into this buffer, and re-allocate strings only when the text length exceeds the string buffer length. The Microsoft. NET Framework provides such a class for free (System. Text. StringBuilder), And we recommend that you use it in all string connection operations in this environment. In ASP and Traditional Visual Basic environments, we cannot access this class, so we need to create it ourselves. The following code is created using Visual Basic 6.0.StringBuilderClass Example (for the sake of conciseness, the error handling code is omitted ).
Option Explicit 'default buffer initial size and growth factor Private Const DEF_INITIALSIZE As Long = 1000 Private Const DEF_GROWTH As Long = 100' buffer size and growth Private m_nInitialSize As LongPrivate m_nGrowth As long' buffer and buffer counter Private m_sText As StringPrivate m_nSize As LongPrivate m_nPos As LongPrivate Sub Class_Initialize () 'default value for setting size and Growth m_nInitialSize = DEF_INITIALSIZE m_nGrowth = DEF_GROWTH 'initialization buffer InitBufferEnd sub' Public Sub Init (ByVal InitialSize As Long, ByVal Growth As Long) if InitialSize> 0 Then m_nInitialSize = InitialSize If Growth> 0 Then m_nGrowth = GrowthEnd Sub 'initialize the buffer Private Sub InitBuffer () m_nSize =-1 m_nPos = 1End Sub 'increase the buffer Private Sub Grow (Optional MinimimGrowth As Long) 'to initialize the buffer (if necessary) if m_nSize =-1 Then m_nSize = m_nInitialSize m_sText = Space $ (m_nInitialSize) Else 'only grows Dim nGrowth As Long nGrowth = IIf (when> MinimimGrowth, Then, MinimimGrowth) m_nSize = m_nSize + nGrowth m_sText = m_sText & Space $ (nGrowth) End IfEnd Sub 'adjust the buffer size to the current size Private Sub Shrink () if m_nSize> m_nPos Then m_nSize = m_nPos-1 m_sText = RTrim $ (m_sText) End IfEnd Sub 'add a single Text String Private Sub AppendInternal (ByVal Text As String) if (m_nPos + Len (Text)> m_nSize Then Grow Len (Text) Mid $ (m_sText, m_nPos, Len (Text) = Text m_nPos = m_nPos + Len (Text) end Sub 'add some Text strings Public Sub Append (ParamArray Text () Dim nArg As Long For nArg = 0 To UBound (Text) AppendInternal CStr (Text (nArg )) next nArgEnd Sub 'returns the current string and adjusts the buffer size. Public Function ToString () as String If m_nPos> 0 Then Shrink ToString = m_sText Else ToString = "" End IfEnd Function "clears the buffer and reinitializes Public Sub Clear () InitBufferEnd Sub
The basic principle used in this class is (m_sText
Used as a string buffer andSpace $The function fills the buffer with space characters to set it to a specific size. If you want to connect more text with existing text, useMid $The function inserts text in the correct position.ToStringThe function returns the text currently stored in the buffer and adjusts the buffer size to the correct length that can hold the text. UseStringBuilderThe ASP code of is as follows:
Function WriteHTML (Data) Dim oSBDim nRepSet oSB = Server. createObject ("StringBuilderVB. stringBuilder ") 'uses the size and growth factor to initialize the buffer oSB. init 15000,750 0For nRep = 0 to 99 oSB. append "<TR> <TD>", (nRep + 1), "</TD> <TD>", _ Data (0, nRep ), "</TD> <TD>", _ Data (1, nRep), "</TD> <TD>", _ Data (2, nRep ), "</TD> <TD>", _ Data (3, nRep), "</TD> <TD>", _ Data (4, nRep ), "</TD> <TD>", _ Data (5, nRep), "</TD> </TR>" NextWriteHTML = oSB. toString () Set oSB = NothingEnd Function
UseStringBuilderIt requires a certain amount of overhead, because every time you use this class, you must create its instance and load the DLL containing this class when creating the first class instance. PairStringBuilderAdditional method calls also require overhead. Use the"&
"Method,StringBuilderExecution depends on multiple factors, including the number of connections, the size of the string to be constructed, and the performance of the initialization parameters of the selected StringBuilder string buffer. Note that in most cases, the amount of space required in the buffer zone is estimated to be slightly higher, far better than increasing.
Built-in Method
ASP contains a very quick way to Create HTML code. You only need to call it multiple times.Response. Write.WriteThe function uses an implicitly optimized string buffer that provides excellent performance. ModifiedWriteHTMLThe Code is as follows:
Function WriteHTML( Data )Dim nRepFor nRep = 0 to 99 Response.Write "<TR><TD>" Response.Write (nRep + 1) Response.Write "</TD><TD>" Response.Write Data( 0, nRep ) Response.Write "</TD><TD>" Response.Write Data( 1, nRep ) Response.Write "</TD><TD>" Response.Write Data( 2, nRep ) Response.Write "</TD><TD>" Response.Write Data( 3, nRep ) Response.Write "</TD><TD>" Response.Write Data( 4, nRep ) Response.Write "</TD><TD>" Response.Write Data( 5, nRep ) Response.Write "</TD></TR>"NextEnd Function
Although this Code may provide us with the best performance and scalability, it has damaged encapsulation to some extent, because the code inside the function is now written directly.ResponseTherefore, the calling code loses control to a certain extent. In addition, moving this Code (for example, moving to the COM component) will become more difficult because this function worksResponseThe stream has dependency.
Test
The four methods mentioned above are tested by a simple ASP page (containing a single table that provides data from a virtual String Array. We use Application Center Test (ACT) from a single client (Windows XP Professional, PIII-850MHz, 512 mb ram) for a single Server (Windows 100 Advanced Server, dual PIII-1000MHz, 256 mb ram. ACT is configured to use five threads to simulate the load when five users connect to the website. Each test includes a 20-second push time and a subsequent 100-second load time, creating as many requests as possible during the load.
You can run the test repeatedly for different numbers of connection operations by changing the number of repetitions in the master table loop, as shown in figureWriteHTMLThe code snippet in the function is shown in. Each running test is executed using the four different methods mentioned above.
Result
The following charts show the effects of various methods on the throughput of the entire application and the response time of the ASP page. Through these charts, we can understand the number of requests supported by the application and the time required for users to wait for the page to be downloaded to the browser.
Table 1: Description of the abbreviated connection method used
Abbreviated Method |
Description |
RESP |
Built-inResponse. WriteMethod |
CAT |
Standard connection ("& ) Method |
PCAT |
Brackets ("& ) Method |
BLDR |
StringBuilderMethod |
In terms of simulating the workload of a typical ASP application, this test is far from the actual situation. From Table 2, we can see that the page is not very large even if it is repeated for 420 times. Currently, many complicated ASP pages are relatively high on these numbers, and the settings may be beyond the limit of this test range.
Table 2: page size and connection count of the test example
Repeated times |
Number of connections |
Page size (in bytes) |
15 |
240 |
2,667 |
30 |
480 |
4,917 |
45 |
720 |
7,167 |
60 |
960 |
9,417 |
75 |
1,200 |
11,667 |
120 |
1,920 |
18,539 |
180 |
2,880 |
27,899 |
240 |
3,840 |
37,259 |
300 |
4,800 |
46,619 |
360 |
5,760 |
55,979 |
420 |
6,720 |
62,219 |
Figure 2: throughput results
As we can see from the chart in figure 2, as we expected, there are multipleResponse. WriteMethod (RESP) provides us with the optimal throughput throughout the entire repeat test range. But it is surprising that the drop in the standard string connection method (CAT) is so huge, while the parentheses method (PCAT) still performs much better when repeated execution for more than 300 times. When we repeat about 220 times, the performance improvement brought by the String cache exceedsStringBuilderThe overhead inherent in the method (BLDR) is worth the additional overhead required to use StringBuilder on this ASP page.
Figure 3: Response Time result Diagram
Figure 4: CAT response time result omitted
The charts in figure 3 and 4 show the response time measured by the time to the first byte (in milliseconds ). As the response time of the standard string connection method (CAT) increases too fast, charts that do not include this method are provided (figure 4) to analyze the differences between other methods. It is worth noting thatResponse. WriteMethod (RESP) andStringBuilderThe method (BLDR) increases linearly with the increase of the number of repetitions, while the Standard connection method (CAT) and the method with parentheses (PCAT) then it increases rapidly after a certain threshold value is exceeded.
Summary
This article focuses on how to apply different string construction technologies in the ASP environment, which also applies to all solutions to create large strings using Visual Basic code, such as creating XML documents manually. The following principles help you determine which method is most suitable for your needs.
- First try to add the"
&
"Method, especially when dealing with existing code. This method has little impact on the code structure, but you will find that the performance of the application will be significantly enhanced, or even exceed the predefined goal.
- Use without damaging the required encapsulation levelResponse. Write. This method can avoid unnecessary in-memory string processing to provide optimal performance.
- UseStringBuilderConstruct strings that are truly large or have a large number of connections.
Although you may not see the performance growth shown in this article, I have used these techniques in real ASP Web applications, performance and scalability can be greatly improved with little extra investment.