ADO, asp

ADO 객체를 이용한 데이터 타입과 SQL Server (MS-SQL) 과 데이터 타입 매핑

SQL형식 TYPE속성 SIZE


INT adInteger 0
TYNYINT adTinyInt 0
SMALLINT adSmallInt 0
Decimal(10,0) adNumeric Precision(10)
NumericScale(0)


VARCHAR(10) adVarChar 10
CHAR(1) adChar 1
NCHAR(50) adWChar 50
NVARCHAR(MAX) adVarWChar 214748364


DATETIME adDBTimeStamp 0
SMALLDATETIME adDBDate 0


'Development > ASP' 카테고리의 다른 글

ADO & SQL 데이터타입  (0) 2013.10.31
ADO Command 객체중 리턴값을 반환할때  (0) 2013.05.30
서버사이드 비동기 접근  (0) 2013.05.30
ASP 에서 XML파서를 이용한 AJAX 한글처리  (0) 2013.05.30
XMLHTTP  (0) 2013.05.30
MSXML2.ServerXMLHTTP  (0) 2013.05.30

Set ReturnCmd = Server.CreateObject("ADODB.Command")

 With ReturnCmd

  .ActiveConnection = SamGukZiLoginDB

  .CommandText    = "INFOR_SELECT"

  .CommandType   = adCmdStoredProc

' /* 반드시 여기 존재해야 한다. */

.ParaMeters.Append .CreateParameter("RETURN", adInteger, adParamReturnValue)

  .ParaMeters.Append .CreateParaMeter("@P_ID" , adVARCHAR, adParamInput, 12, id)  

  .Execute , , adExecuteNoRecords

  ReturnValue = .ParaMeters("RETURN")

  Response.Write ReturnValue

 End With

'Development > ASP' 카테고리의 다른 글

ADO & SQL 데이터타입  (0) 2013.10.31
ADO Command 객체중 리턴값을 반환할때  (0) 2013.05.30
서버사이드 비동기 접근  (0) 2013.05.30
ASP 에서 XML파서를 이용한 AJAX 한글처리  (0) 2013.05.30
XMLHTTP  (0) 2013.05.30
MSXML2.ServerXMLHTTP  (0) 2013.05.30

 Dim HttpURL                                                                                                                                                              

  HttpURL = "http://192.168.0.0/Publish/gm_DataRequest.asp"                                                                                              

 Dim oXmlHTTP                                                                                                                                                             

  Set oXmlHTTP = Server.CreateObject("MSXML2.ServerXMLHTTP")                                                                                                              

   'oXmlHTTP.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"                                                                                         

   oXmlHTTP.Open "GET", HttpURL, false                                                                                                                                    

   oXmlHTTP.Send ""                                                                                                                                                       

 Dim HttpStatus                                                                                                                                                           

 Dim WriteStr                                                                                                                                                             

HttpStatus = oXmlHTTP.Status                                                                                                                                            

If Err.Number <> 0 Or HttpStatus <> 200 Then                                                                                                                            

if HttpStatus = 404 then                                                                                                                                               

 WriteStr = "존재하지 않는 페이지 입니다.(404)"                                                                                                                                    

Elseif Httpstatus >= 401 And HttpStatus < 402 Then                                                                                                                     

 WriteStr = "접근이 금지된 페이지 입니다.(401)"                                                                                                                                    

Elseif Httpstatus >= 500 And HttpStatus <= 600 Then                                                                                                                    

 WriteStr = "내부 서버 오류 입니다.(500)"                                                                                                                                       

Else                                                                                                                                                                   

 WriteStr = "서버가 다운되었거나 올바른 경로가 아닙니다."                                                                                                                                 

End If                                                                                                                                                                 

'오류가 없음 (문서를 성공적으로 로딩함)                                                                                                                                                 

Else                                                                                                                                                                    

WriteStr = URLDecodeUTF8(oXmlHTTP.ResponseText)                                                                                                                        

End If                                                                                                                                                                  

Set oXmlHTTP = Nothing                                                                                                                                                    

'Development > ASP' 카테고리의 다른 글

ADO & SQL 데이터타입  (0) 2013.10.31
ADO Command 객체중 리턴값을 반환할때  (0) 2013.05.30
서버사이드 비동기 접근  (0) 2013.05.30
ASP 에서 XML파서를 이용한 AJAX 한글처리  (0) 2013.05.30
XMLHTTP  (0) 2013.05.30
MSXML2.ServerXMLHTTP  (0) 2013.05.30

//XMLHttpRequest 객체생성

var oXmlHTTP = getXmlHttp();

if (window.XMLHttpRequest)

{

 oXmlHttp = new XMLHttpRequest();

}else{

 oXmlHttp = new ActiveXObject("Microsoft.XMLHTTP");

}

oXmlHTTP.open("POST", "AJAX.asp", false); // 동기방식으로 연결


//리퀘스트 내용을 XML문자열로 만든다. ASP는 기본적으로 EUC-KR로 처리하기 때문에 따로 정의할필요는 없습니다.

//한글을 전송할때는 태그내용을 <![CDATA[ ]]>로 선언해야 합니다.

var strXML = "";

strXML = strXML + "<gwinaemi>";

strXML = strXML + "<strList><![CDATA[내용]]></strList>";

strXML = strXML + "</gwinaemi>";

//리퀘스트 전송

oXmlHTTP.send(strXML);

//받아온 XML문자열에서 에서 strList태그의 내용을 추출 viewText객체의 innerHTML 로 넣는다.

eId("viewText").innerHTML = oResXML.getElementsByTagName("strList").item(0).firstChild.nodeValue;

 

--------------------------------------------------------------------------------------------------------------

'''''AJAX.asp파일쪽의 처리


'''''받아온 XML문자열을 Request.BinaryRead로 읽어서 

'''''microsoft.xmldom 파서로 읽어 Scripting.Dictionary객체로 반환

'''''필요한 리퀘스트 내용은 딕셔너리에서 호출한다.

Dim vntPostedData, lngCount 

lngCount = Request.TotalBytes 

vntPostedData = Request.BinaryRead(lngCount)

Dim oXMLDom                        

Set oXMLDom = Server.CreateObject("microsoft.xmldom")

oXMLDom.load(vntPostedData)

Dim oDicXMLRequest

set oDicXMLRequest = Server.CreateObject("Scripting.Dictionary")

If oXMLDom.parseError = 0 Then

        Dim objNode

        Set objNode = oXMLDom.documentElement

        set oXMLDom = nothing

        Dim i

        For i = 0 To objNode.childNodes.length - 1

                oDicXMLRequest.Add objNode.childNodes.Item(i).nodeName, objNode.childNodes.Item(i).Text

        Next

        set objNode = nothing

else

        set oXMLDom = nothing        

End if

 

Response.ContentType = "text/xml"

Response.Charset = "ks_c_5601-1987"


''''''''''''''''XML문서의 형태로 돌려보낸다. encoding을 ASP의 기본엔코딩인 ks_c_5601-1987로 지정한다.

Response.write "<?xml version=""1.0"" encoding=""ks_c_5601-1987""?>" & chr(13) & chr(10)


''''''''''''''''oDicXMLRequest에서 strList의 내용을 불러낸다.

Response.write "<gwinaemi><strList><![CDATA[" & oDicXMLRequest("strList") & "]]></strList></gwinaemi>"

[출처] asp에서 XML파서를 이용한 ajax 한글 처리 방법[펌]|작성자 스톤콜드


 

 

 

 

보너스.----------------------------------------------------------------------------

 

'*************************************

'* XML 긁어오기 시작!!

'************************************* 

Set objXmlHttp  = Server.CreateObject("Msxml2.ServerXMLHTTP.3.0")

objXmlHttp.open "POST", "http://www.abc.com/text_xml.asp?event_kind="&event_kind&"&user_id="&user_id&"&user_key="&user_key&"&gift_kind="&gift_kind, false


objXmlHttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"

objXmlHttp.send  '요청

strResponseText = objXmlHttp.responseText  '응답 텍스트 저장

Set objXmlHttp  = Nothing

'DOM 파서를 이용해 파싱 

Set objMsXmlDom = Server.CreateObject("microsoft.XMLDOM")

objMsXmlDom.async = false

objMsXmlDom.loadXML( strResponseText ) '스트링으로 로드하기 때문에 loadXML 메서드 사용.

'데이터 추출.

referResult   = ""& Trim( objMsXmlDom.getElementsByTagName("referResult").Item(0).Text )

message = ""& Trim( objMsXmlDom.getElementsByTagName("message").Item(0).Text )


Set objMsXmlDom = Nothing

'*************************************

'* XML 긁어오기 끝!!

'************************************* 

function hrefMark(){ }

'Development > ASP' 카테고리의 다른 글

ADO Command 객체중 리턴값을 반환할때  (0) 2013.05.30
서버사이드 비동기 접근  (0) 2013.05.30
ASP 에서 XML파서를 이용한 AJAX 한글처리  (0) 2013.05.30
XMLHTTP  (0) 2013.05.30
MSXML2.ServerXMLHTTP  (0) 2013.05.30
ASP Dictionary Object  (0) 2012.10.17

url1 = "http://icon.hanmail.net/top/0303/logo2.gif"

Set xh = CreateObject("MSXML2.ServerXMLHTTP")

xh.Open "GET", url1, false

xh.Send()

imgData = xh.ResponseBody

Set  xh = Nothing


Set stm =CreateObject("ADODB.Stream")

stm.open()

stm.type=1

stm.write imgData

stm.SaveToFile Server.MapPath("/") & "\logo.gif", 2

stm.close()

Set  stm = Nothing



'Development > ASP' 카테고리의 다른 글

서버사이드 비동기 접근  (0) 2013.05.30
ASP 에서 XML파서를 이용한 AJAX 한글처리  (0) 2013.05.30
XMLHTTP  (0) 2013.05.30
MSXML2.ServerXMLHTTP  (0) 2013.05.30
ASP Dictionary Object  (0) 2012.10.17
ASP, VBScript 형변환, 날짜/시간함수  (0) 2012.05.23

How do I read the contents of a remote web page?

You can include static txt and HTML files from remote servers by using a component (such as AspHTTP, ASPTear 1.50, or VB's built in InetCtrls) to parse the remote URL's content. 

 

You can also try this method out; it was tested with the MSXML objects which are installed with Windows 2000. You should make sure you have the latest versions of MSXML and XML Core Services (see MSXML Downloads). If you download the newer version, take special note of the new ProgID you should be using -- MSXML 4.0 now supports side-by-side installation, which means the ProgID below will actually use the older version. 

 

<% 

    url = "http://www.espn.com/main.html" 

    set xmlhttp = CreateObject("MSXML2.ServerXMLHTTP") 

    xmlhttp.open "GET", url, false 

    xmlhttp.send "" 

    Response.write xmlhttp.responseText 

    set xmlhttp = nothing 

%>

 

And here it is in JavaScript: 

 

<script language=javascript runat=server> 

    var url = "http://www.espn.com/main.html"; 

    var xmlhttp = new ActiveXObject("MSXML2.ServerXMLHTTP"); 

    xmlhttp.open("GET", url, 0); 

    xmlhttp.send(""); 

    Response.Write(xmlhttp.responseText); 

    var xmlhttp = null; 

</script>

 

If you use a URL that doesn't exist, or you are behind a firewall that blocks certain web sites, or the site is behind a firewall that blocks traffic to port 80 / 443, or you are using a proxy server, or the site requires authentication, you will receive this error: 

 

msxml4.dll (0x80072EE7) 

Server name or address could not be resolved

 

To correct, you will have to figure out which of the issue(s) is standing in your way, and discuss workarounds with your or their network administrator(s). 

 

Don't forget that if your remote page has relative image URLs, or style sheets, or JavaScript files, or frames, or links, it won't work perfectly when ported to your server(s). To overcome this, you'll want to add a BASE HREF tag to keep all the images coming from the correct location. For example, the above code (which gets all the text from espn.com, but is formatted weird and doesn't function 100% as intended), is modified only slightly to work correctly: 

 

<% 

    url = "http://www.espn.com/main.html" 

 

    ' add a BASE HREF tag 

    Response.write "<BASE HREF='" & url & "'>" 

 

    set xmlhttp = CreateObject("MSXML2.ServerXMLHTTP") 

    xmlhttp.open "GET", url, false 

    xmlhttp.send "" 

    Response.write xmlhttp.responseText 

    set xmlhttp = nothing 

%>

 

For information on increasing or decreasing the time allowed for the XMLHTTP objects to retrieve a response from a remote server, see Article #2407. 

 

If you need to POST data you can so by adding a header that tells the receiver you're sending FORM data: 

 

<% 

    url = "http://www.espn.com/main.html" 

    set xmlhttp = CreateObject("MSXML2.ServerXMLHTTP") 

    xmlhttp.open "POST", url, false 

    xmlhttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded" 

    xmlhttp.send "x=1&y=2" 

    Response.write xmlhttp.responseText 

    set xmlhttp = nothing 

%>

 

Another thing you may want to do, going back to the original script, is make sure the server is there! If not, you can display a message... and you can customize it to display whether the server was not found at all, or if the server was found but you got a bad response (e.g. a 404 Page Not Found). Note that if you do not need to parse the content of the remote web page, that using the HEAD method here is far more efficient than using GET or POST... since only the headers are retrieved from the remote server, not any of the content. 

 

<%  

    ' deliberate typo:  

    url = "http://www.espn.co/main.html"  

 

    set xmlhttp = CreateObject("MSXML2.ServerXMLHTTP")  

    on error resume next  

    xmlhttp.open "HEAD", url, false  

    xmlhttp.send ""  

    status = xmlhttp.status 

    if err.number <> 0 or status <> 200 then 

        if status = 404 then 

            Response.Write "Page does not exist (404)." 

        elseif status >= 401 and status < 402 then 

            Response.Write "Access denied (401)." 

        elseif status >= 500 and status <= 600 then 

            Response.Write "500 Internal Server Error on remote site." 

        else 

            Response.write "Server is down or does not exist." 

        end if 

    else  

        Response.Write "Server is up and URL is available."  

    end if  

    set xmlhttp = nothing  

%>

 

You might want to parse the results, instead of sending them straight to the client: 

 

<% 

    url = "http://www.espn.com/main.html"  

    set xmlhttp = CreateObject("MSXML2.ServerXMLHTTP")  

    on error resume next 

    xmlhttp.open "GET", url, false 

    xmlhttp.send ""  

    if err.number <> 0 then 

        response.write "Url not found" 

    else 

        if instr(xmlhttp.responseText,"Stanley Cup")>0 then 

            response.write "There's a story about the playoffs." 

            response.write "<a href=" & url & ">Go there</a>?" 

        else 

            response.write "There is no story about the playoffs." 

        end if 

    end if 

    set xmlhttp = nothing 

%>

 

You may be interested in performing an asynchronous request, e.g. hitting an ASP page that acts like a batch file that gets fired but does not need to return any results. You can simply change the third parameter of the open call to TRUE (and leave out the reference to the responseText value): 

 

<% 

    url = "http://www.espn.com/main.html" 

    set xmlhttp = CreateObject("MSXML2.ServerXMLHTTP") 

    xmlhttp.open "GET", url, true 

    xmlhttp.send "" 

    set xmlhttp = nothing 

%>

 

Finally, you may want to spoof your user agent, since the MSXML object sends something like "Mozilla/4.0 (compatible; Win32; WinHttp.WinHttpRequest.5)" -- many sites will view this as a spider or 'screen scraper', and for various reasons, might present alternate content -- here are two samples: 

 

<% 

    url = "http://www.espn.com/main.html"  

 

 

    ' this sample posts as the actual browser being used: 

 

 

    br = Request.ServerVariables("HTTP_USER_AGENT") 

    set xmlhttp = CreateObject("MSXML2.ServerXMLHTTP")  

    on error resume next 

    xmlhttp.open "GET", url, false 

    xmlhttp.setRequestHeader "User-Agent",br 

    xmlhttp.send ""  

    if err.number <> 0 then 

        response.write "Url not found" 

    else 

        response.write xmlhttp.responseText 

    end if 

    set xmlhttp = nothing 

 

 

 

    ' this sample posts as "My funky browser." 

 

 

    set xmlhttp = CreateObject("MSXML2.ServerXMLHTTP")  

    on error resume next 

    xmlhttp.open "GET", url, false 

    xmlhttp.setRequestHeader "User-Agent","My funky browser." 

    xmlhttp.send ""  

    if err.number <> 0 then 

        response.write "Url not found" 

    else 

        response.write xmlhttp.responseText 

    end if 

    set xmlhttp = nothing 

%>

 

 

If you encounter errors... you can use ParseError to determine the problem. 

 

<% 

    set xmlhttp = CreateObject("MSXML2.ServerXMLHTTP")  

    ' ... stuff ... 

    on error resume next 

    xmlhttp.send ""  

    if err.number <> 0 then 

        response.write "Error: " & xmlhttp.parseError.URL & _ 

            "<br>" & xmlhttp.parseError.Reason 

        response.end 

    end if 

    ' ... stuff ... 

%>

 

A common error you might receive: 

 

msxml3.dll error '80072efd'  

A connection with the server could not be established

 

Make sure that the URL is actually reachable. You may have spelled the domain name wrong, or the site may actually be down. 

 

Test using a browser from that machine, or simply running a tracert / ping. Note that ping won't always return results, because many sites block all such traffic (mainly to help eliminate DOS attacks). However, ping should at least let you know the IP address, which means that the domain name was resolved correctly through DNS. Otherwise, it might be that your DNS server is preventing connection.

'Development > ASP' 카테고리의 다른 글

ASP 에서 XML파서를 이용한 AJAX 한글처리  (0) 2013.05.30
XMLHTTP  (0) 2013.05.30
MSXML2.ServerXMLHTTP  (0) 2013.05.30
ASP Dictionary Object  (0) 2012.10.17
ASP, VBScript 형변환, 날짜/시간함수  (0) 2012.05.23
ADO 객체 메소드, 속성  (0) 2012.04.17

ASP 로 개발을 하면서 정말로 불편했던 PHP 의 배열과 같이

데이터를 키, 값 형태로 할수가 없었는데.. 있었구나..

이미 비쥬얼베이직에서는 존재하고 있었는데.. 자꾸 잊게되는건..

ASP 과 '비쥬얼베어직 스크립트' 를 기반으로 한다는거다.

하지만 기본적으로 ASP 자체적으로 지원해주는 것은 아니다. 


그러므로 CreateObject 메소드를 통해서만 참조하여 사용할 수 있다.

암튼.. 그래서.. 있다.ㅋㅋ


Dictionary 객체. 그냥 배열처럼 인덱스, 값 형태로도 사용이 가능하지만, 무엇보다 좋은건

명시적으로 키, 값 형태로 사용할 수 있다는 것이다.

그러니 의미 그대로. 사전. 단어와 뜻 만으로 사용하겠다는 의미가 되는것 같다.


아래 CODE EX 를 참조하여 속성과 메소드를 테스트해보면 좋겠다.

무엇보다 난 제일 활용하기 좋은건 클래스의 멤버들에게 할당할때인데 참으로 편리하고,

유지보수에 용이하다.ㅎㅎㅎ


속 성

CompareMode

키 값을 이진비교(0) 또는 텍스트비교(1)중 하나 택일. 1이면 "A"와"a"는 같은 문자로 취급. 0 이면 다른 문자. 상수값 :vbBinaryCompare(0), vbTextCompare(1)

Count

Dictionary 안에 저장된 멤버수

Item

Key 에 해당하는 값(의미)

Key

단어가 되는. Item 을 상징하는 Key

메소드

Add

추가할당

Exists

존재여부로 True / False 반환

Items

Item 을 배열로 반환

Keys

Key 를 배열로 반환

Remove

해당 멤버 제거

RemoveAll

전체 제거


※ CODE EX

Set oDic = Server.CreateObject("Scripting.Dictionary")

'/* 할당 */

oDic.Add "MyName", "JKUN"

oDic.Add "BlogDomain", "http://www..jkun.net"


'/* 출력 */

oDicKeyList = oDic.Keys

oDicItemList = oDic.Items


For i = 0 To (oDic.Count - 1)

Response.Write "<p>" & oDicKeyList(i) & " : " & oDicItemList(i) & "</p>"

Next


위 코드를 예제로 테스트 해보시면 그냥 아~ 이렇구나 하실겁니다.

그리고 센스있게 댓글 달면 더욱 좋지요~

'Development > ASP' 카테고리의 다른 글

XMLHTTP  (0) 2013.05.30
MSXML2.ServerXMLHTTP  (0) 2013.05.30
ASP Dictionary Object  (0) 2012.10.17
ASP, VBScript 형변환, 날짜/시간함수  (0) 2012.05.23
ADO 객체 메소드, 속성  (0) 2012.04.17
ASP String Bulider (문자열 처리능력향상)  (0) 2012.04.04

출처 : http://blog.naver.com/const34/20042866990

▣ 함수(Function) - 변환 관련 함수, 날짜/시간 관련 함수
&sec 학습목표
  1. ASP에서 지원하는 함수의 종류와 특징을 안다.
  2. ASP에서 지원하는 함수를 사용할 수 있다.

 

함수는 프로그램 코드내에서 반복적으로 사용되는 루틴이나 모듈을 구성할때 사용하는 것이다. 이런 함수를 보통 프로그래머가 구성을 하는 것이 원칙이다. 그러나 일일이 구성하는 것은 특히 사용자가 쉽게 표현하지 힘든 특정처리부분을 처리하기는 어렵다. 때문에 ASP에서 내장함수로 제공하여 준다.

함수의 사용예제를 링크걸어 두겠다.

ASP-Function 다운로드 ]

또 Microsoft에서 제공하는 MSDN에 방문해 보면 VBScript에 대한 모든 정보를 접할 수 있는데 함수도 그안에서 사용법과 주의할 점을 찾을 수 있다.

찾이가는 방법은 일단 MSDN.microsoft.com에서 상단 주메뉴에서 Library를 선택한다. 화면이 바뀌면 아래에 서브메뉴가 펼쳐지면 메뉴중에서 [Web Development] - [Scripting]- [Windows Script Tecnologies] - [VBScript] - [Reperence] - [Function] 을 차레로 산택하면 된다. 물론 VBScript의 다른 정보도 접할 수 있다.

일단 함수부분에 바로 접근할 수 있도록 링크를 걸어 두었다.

MSDN VBScript Function Reference ]

1. 변환 관련 함수

변환 관련 함수는 데이터의 형변환이나 데이터의 변환에 사용되는 함수이다.

(1) Asc

문자열에서 첫글자에 해당하는 ANSI 문자 코드를 반환한다.

형 식
Asc(string)

Dim MyNumber
MyNumber = Asc("A") ' Returns 65.
MyNumber = Asc("a") ' Returns 97.
MyNumber = Asc("Apple") ' Returns 65.

(2) AscB

문자열에서 그 문자의 첫 바이트를 반환한다.

형 식
AscB(string)

사용법은 ASC와 같다.

(3) AscW

문자열에서 그 문자의 첫 유니코드 문자 코드를 반환한다.

형 식
AscW(string)

사용법은 ASC와 같다.

(3) CBool

Boolean 하위형식의 Variant로 변환된 식을 반환

형 식
CBool(expression)

Dim A, B, Check
A = 5: B = 5 ' Initialize variables.
Check = CBool(A = B) ' Check contains True.
A = 0 ' Define variable.
Check = CBool(A) ' Check contains False.

(4) CByte

Byte 하위형식의 Variant로 변환된 식을 반환(결과는 255를 넘을 수 없다)

형 식
CByte(expression)

Dim MyDouble, MyByte
MyDouble = 125.5678 ' MyDouble is a Double.
MyByte = CByte(MyDouble) ' MyByte contains 126.

(5) CCur

Currency 하위형식의 Variant로 변환된 식을 반환한다.

형 식
CCur(expression)

Dim MyDouble, MyCurr
MyDouble = 543.214588 ' MyDouble is a Double.
MyCurr = CCur(MyDouble * 2) ' Convert result of MyDouble * 2 (1086.429176) to a Currency (1086.4292).

(6) CDate

Date 하위형식의 Variant로 변환된 식을 반환한다.

형 식
CDate(date)

MyDate = "2005-05-27" ' Define date.
MyShortDate = CDate(MyDate) ' #2005-05-27#

(7) CDbl

Double 하위형식의 Variant로 변환된 식을 반환한다.

형 식
CDbl(expression)

Dim MyCurr, MyDouble
MyCurr = CCur(234.456784) ' MyCurr is a Currency (234.4567).
MyDouble = CDbl(MyCurr * 8.2 * 0.01) ' Convert result to a Double (19.2254576).

(8) CInt

Integer 하위형식의 Variant로 변환된 식을 반환한다. (반올림한다)

형 식
CInt(expression)

Dim MyDouble, MyInt
MyDouble = 2345.5678 ' MyDouble is a Double.
MyInt = CInt(MyDouble) ' MyInt contains 2346.

(9) Chr(charcode)

지정한 ANSI 문자 코드와 연관된 문자를 반환한다.

형 식
Chr(charcode)

Dim MyChar
MyChar = Chr(65) ' Returns A.
MyChar = Chr(97) ' Returns a.
MyChar = Chr(62) ' Returns >.
MyChar = Chr(37) ' Returns %.

(10) ChrB

chr 함수와 같으나 문자열의 바이트를 지정해서 사용한다. 항상 싱글바이트로 반환한다.

형 식
ChrB(charcode)

(11) ChrW

chr 함수와 같으나 유니코드 데이터를 지정해 사용한다.

형 식
ChrW(charcode)

(12) CLng

Long 하위형식의 Variant로 변환된 식을 반환한다. (실수데이터인경우 반올림한다)

형 식
ChrW(charcode)

MyVal1 = 25427.45: MyVal2 = 25427.55 ' MyVal1, MyVal2 are Doubles.
MyLong1 = CLng(MyVal1) ' MyLong1 contains 25427.
MyLong2 = CLng(MyVal2) ' MyLong2 contains 25428.

(13) CSng

Single 하위형식의 Variant로 변환된 식을 반환한다.(반올림처리)

형 식
CSng(expression)

' MyDouble1, MyDouble2 are Doubles.
MyDouble1 = 75.3421115: MyDouble2 = 75.3421555
MySingle1 = CSng(MyDouble1) ' MySingle1 contains 75.34211.
MySingle2 = CSng(MyDouble2) ' MySingle2 contains 75.34216.

(14) CStr

String 하위형식의 Variant로 변환된 식을 반환한다.

형 식
CStr(expression)

Dim MyDouble, MyString
MyDouble = 437.324 ' MyDouble is a Double.
MyString = CStr(MyDouble) ' MyString contains "437.324".

(15) Fix

숫자의 정수부분만을 반환한다. 
Sgn(number) * Int(Abs(number))의 결과와 같은 함수이다.

형 식
Fix(expression)

MyDouble = -437.324 ' MyDouble is a Double.
MyFix = Fix(MyDouble) ' MyFix contains "-437".

(16) Hex

숫자의 16진수를 나타내는 문자열로 반환한다.

형 식
Hex(number)

Dim MyHex
MyHex = Hex(5) ' Returns 5.
MyHex = Hex(10) ' Returns A.
MyHex = Hex(459) ' Returns 1CB.

(17) Int

지정된 숫자의 값보다 크지 않은 최대의 정수를 반환한다.

형 식
Int(number)

MyNumber = Int(99.8) ' Returns 99.
MyNumber = Fix(99.2) ' Returns 99.
MyNumber = Int(-99.8) ' Returns -100.
MyNumber = Fix(-99.8) ' Returns -99.
MyNumber = Int(-99.2) ' Returns -100.
MyNumber = Fix(-99.2) ' Returns -99.

(18) Oct

숫자의 8진수 값을 반환한다.

형 식
Oct(number)

Dim MyOct
MyOct = Oct(4) ' Returns 4.
MyOct = Oct(8) ' Returns 10.
MyOct = Oct(459) ' Returns 713.

(19) Round

지정한 소수점 자리에서 반올림한 수를 반환한다.

형 식
Round(expression[, numdecimalplaces])

pi = 3.14159
MyVar1 = Round(pi) ' MyVar1 contains 3.
MyVar2 = Round(pi, 2) ' MyVar2 contains 3.14. 
var1 = Round(1.5) ' var1 contains 2
var2 = Round(2.5) ' var2 contains 2
var3 = Round(3.5) ' var3 contains 4
var4 = Round(0.985, 2) ' var4 contains 0.98
var5 = Round(0.995, 2) ' var5 contains 1.00

(20) Sgn

수의 부호를 반환한다. (음수이면 -1, 아니면 0)

형 식
Sgn(number)

Dim MyVar1, MyVar2, MyVar3, MySign
MyVar1 = 12: MyVar2 = -2.4: MyVar3 = 0
MySign = Sgn(MyVar1) ' Returns 1.
MySign = Sgn(MyVar2) ' Returns -1.
MySign = Sgn(MyVar3) ' Returns 0.


2. 날짜/시간 함수

날짜와 시간에 관련된 함수들이다. 날짜데이터는 1989년 12월31일을 기준으로 하여 카운팅하여 사용한다.

(1) Date

현재 시스템의 날짜

형 식
Date

Dim MyDate
MyDate = Date

(2) DateAdd

지정된 시간간격을 추가한 날짜를 반환한다.

형 식
DateAdd(interval, number, date)

interval의 세팅값은 다음과 같다.

SettingDescription
yyyy 
Year

Quarter
mMonth
yDay of year
dDay
wWeekday
wwWeek of year


NewDate = DateAdd("m", 1, "2005-05-13") '2005-06-13 
NewDate = DateAdd("d", 10, "2005-05-13") '2005-05-23
NewDate = DateAdd("d", -10, "2005-05-13") '2005-05-03

(3) DateDiff

두 날짜 사이의 날짜 간격수를 반환한다.

형 식
DateDiff(interval, date1, date2 [,firstdayofweek [,firstweekofyear]])

interval의 세팅값은 DateAddd와 기본적으로 같다.

SettingDescription
yyyy 
Year

Quarter
mMonth
yDay of year
dDay
wWeekday
wwWeek of year
hHour
nMinute
sSecond

Date 데이타 형식은 # 과 " 둘다 사용가능하다.

DateDiff("d", Now, #2005-12-25#) '208 
DateDiff("d", Now, "2004-12-25") '-157

(4) DatePart

주어진 날짜의 지정된 부분을 반환한다.

형 식
DatePart(interval, date[, firstdayofweek[, firstweekofyear]])

interval의 세팅값은 DateDiff와 기본적으로 같다.

a =DatePart("q", "2005-07-13") '3 , 즉 3/4분기에 속한다는 것이다.

(5) DateSerial

지정된 년, 월, 일의Date 하위형식인 Variant를 반환한다.

형 식
DateSerial(year, month, day)

MyDate1 = DateSerial(1970, 1, 1) ' 1970-01-01

(6) DateValue

Date 하위형식인 Variant를 반환한다. (#Date#)

형 식
DateValue(date)

a =DateValue("2005-05-13") ' 2005-05-13

(7) Day

날짜/시간 형식의 데이터로 부터 날짜를 반환한다.(1~31)

형 식
Day(date)

MyDay = Day("2005-05-19") ' MyDay contains 19.

(8) Hour

날짜/시간 형식의 데이터로 부터 시간를 반환한다.(0~23)

형 식
Hour(time)

MyHour = Hour(now) '현재시간의 시를 출력

(9) Minute

날짜/시간 형식의 데이터로 부터 분을 반환한다.(0~59)

형 식
Minute(time)

Dim MyVar
MyVar = Minute(Now)

(10) Month

날짜/시간 형식의 데이터로 부터 월을 반환한다.(1~12)

형 식
Month(date)

Dim MyVar
MyVar = Month(Now) ' 현재 날짜에서 월데이터를 가져온다.

(11) MonthName

지정한월을 나타내는 문자열을 반환한다.abbreviate의 기본값은 false이다.

형 식
MonthName(month[, abbreviate])

Dim MyVar
MyVar = MonthName(10, True) ' 10
MyVar = MonthName(10) ' 10월

(12) Now

현재 컴퓨터의 시스템 날짜와 시간을 반환한다

형 식
Now

MyVar = Now

(13) Second

날짜/시간 형식의 데이터로 부터 초를 반환한다.(0~59)

형 식
Second(time)

MySec = Second(Now) ' 현재시간에서 초 데이터를 가져온다.

(14) Time

현재 시스템 시간을 나타내는 Date 하위형식의 Variant를 반환한다.

형 식
Time

MyTime = Time ' 현재시간을 반환한다.

(15) TimeSerial

지정된 년, 월, 일의Date 하위형식인 Variant를 반환한다.

형 식
TimeSerial(hour, minute, second)

hour : Number between 0 (12:00 A.M.) and 23 (11:00 P.M.), inclusive, or a numeric expression.

minute : Any numeric expression.

second : Any numeric expression.

MyTime1 = TimeSerial(12 - 6, -15, 0)

(16) TimeValue

시간을 포함하는 Date 하위형식인 Variant를 반환한다.

형 식
TimeValue(time)

MyTime = TimeValue("4:35:17 PM") '오후 4:35:17

(17) Weekday

요일을 나타내는 정수를 반환한다.

형 식
Weekday(date, [firstdayofweek])

리턴되는 값은 1~7 의 정수이며 일요일부터 토요일까지의 순서를 의미한다.

Constant 
Value
Description
vbSunday
1
Sunday
vbMonday
2
Monday
vbTuesday 
3
Tuesday
vbWednesday
4
Wednesday
vbThursday
5
Thursday
vbFriday
6
Friday
vbSaturday
7
Saturday

MyWeekDay = Weekday(now)

(18) WeekdayName

지정된 요일을 나타내는 문자열을 반환한다.

형 식
WeekdayName(weekday, abbreviate, firstdayofweek)

Constant 
Value
Description
vbSunday
1
Sunday
vbMonday
2
Monday
vbTuesday 
3
Tuesday
vbWednesday
4
Wednesday
vbThursday
5
Thursday
vbFriday
6
Friday
vbSaturday
7
Saturday

MyDate = WeekDayName(6, True) ' 금

MyDate = WeekDayName(6) '금요일

(19)Year

날짜/시간 형식의 데이터로 부터 년도를 반환한다.

형 식
Year(date)

MyYear = Year(now) '현재날짜의 년도 데이터를 가져온다.


데이터 타입

Cbool - Boolean  
Cbyte - Byte  
Ccur - Currency  
Cdate - Date  
CDbl - Double 
Cint -  Integer  
CLng - Long  
CSng - Single  
CStr - String 
Cvar - Variant  
CVErr - Error  


 Connection 객체

 
Connection 객체는 ODBC 데이타 소스와 연결할 때 사용한다.
 
프로퍼티설명
Attributes객체에 대한 하나이상의 특성을 나타낸다.
CommandTimeout명령이 실행되는 최대 시간을 지정한다. 만약 시간이 경과되면 오류를 발행한다.
ConnectionString데이타 소스와 연결할 때 사용하는 연결정보를 저장한다.
ConnectionTimeout데이타 소스와 연결할 때 최대 대기 시간을 지정한다.
DefaultDatabaseConnection 객체에 대한 기본 데이타베이스를 지정한다.
IsolationLevelConnection 객체에 대한 격리 레벨을 지정한다.
ModeConnection 객체에서 데이타의 변경에 대한 권한을 지정한다.
ProviderConnection 객체의 Provider 이름을 나타낸다.
VersionADO의 버젼을 나타낸다.

메소드설명
BeginTrans새로운 트랜젝션을 시작한다.
CommitTrans현재 트랜젝션에서 일어난 변경사항을 저장하고 트랙젝션을 닫는다.
그리고 새로운 트랜젝션을 다시 시작한다.
RollbackTrans현재 트랜젝션에서 일어난 변경사항을 취소하고 트랙젝션을 닫는다.
그리고 새로운 트랜젝션을 다시 시작한다.
여기서 트랜젝션은 데이타베이스에 가하는 일련의 작업 집합을 말한다.
Open데이타 소스에 연결한다.
Close데이타 소스로의 연결을 종료한다.
Execute지정된 쿼리, SQL 문장 또는 Stored Procedure를 실행한다.
 

 Error 객체

 
ADO의 명령수행중에 발생한 오류에 대한 정보를 담고 있다.
 
프로퍼티설명
Number오류 번호
Description오류에 대한 설명
Source오류를 발생시킨 객체의 이름을 나타낸다.
HelpFile오류와 관련된 도움말 파일의 이름을 나타낸다.
HelpContext오류와 관련된 도움말의 컨텍스트 ID를 나타낸다.
SQLStatusSQL 상태를 나타내는 길이가 5인 문자열을 리턴한다.
NativeError데이타베이스에서 정의한 오류 번호를 리턴한다.
 

 Command 객체

 
Command 객체는 데이타 소스로 부터 실행할 명령을 정의한다.
 
프로퍼티설명
ActiveConnection데이타 소스에 연결된 Connection객체로 Command 객체는 이 연결객체를 통해서 명령을 실행한다.
CommandText실행할 SQL 문장이나 테이블 이름, 또는 스토어드 프로시져
CommandTimeout명령이 실행되는데 걸리는 최대 대기 시간을 나타낸다.
CommandTypeCommand 객체의 종류를 지정한다.
Prepared명령을 실행하기 전에 준비된 문장을 생성할 것인지를 지정한다.

메소드설명
CreateParameter새로운 파라메터 객체를 생성한다.
ExecuteCommandText에서 지정한 쿼리, SQL 문장, 또는 스토어드 프로시듀어를 실행한다.
 

 Parameter 객체

 
파라메터 객체는 파라메터를 가지는 쿼리나 스토어드 프로시듀어를 담고있는 커멘드 객체와 함께 사용된다.
 
프로퍼티설명
Attributes파라메터의 속성을 나타내며, adParamSigned, adParamNullable, adParamLong과 같은 값들을 혼합하여 지정할 수 있다.
Direction파라메터가 입력 파라메터인지 출력 파라메터인지 등을 지정한다.
Name파라메터 객체의 이름을 나타낸다.
NumericScale숫자형 파라메터에서 소수점 뒷자리수를 결정한다.
Precision숫자형 파라메터에서 최대 자리수를 결정한다.
Size파라메터 값의 바이트 수 또는 문자열 수를 지정한다.
Type파라메터 값의 데이터 형을 지정한다.
Value파라메터의 값을 나타낸다.

메소드설명
AppendChunk긴 문자열이나 바이너리 타입의 파라메터 객체에 데이터를 추가한다.
 

 Recordset 객체

 
프로퍼티설명
AbsolutePage레코드의 절대 페이지를 나타낸다.
만약 여기에 새로운 값을 지정하면, 현재 레코드의 위치가 해당 페이지의 첫 레코드로 이동한다.
페이지란 순차적으로 일정 개수만큼 레코드들을 묶어놓은 단위이다.
페이지는 기본 값으로 10개의 레코드를 가진다.
AbsolutePosition현재 레코드의 절대 위치를 나타낸다.
첫 레코드의 AbsolutePosition은 1이다.
ActiveConnection현재 레코드셋이 연결된 Connection 객체를 나타낸다.
BOF, EOFBOF는 현재 레코드가 첫 레코드의 이전에 있는지를 나타낸다.
EOF는 현재 레코드가 마지막 레코드의 다음에 있는지를 나타낸다.
Bookmark레코드셋에서 현재 레코드의 위치를 저장하고 언제라도 그 위치로 이동할 수 있다.
CacheSize로컬 메모리에 저장할 레코드의 개수를 지정한다.
CacheSize의 기본값은 ForwardOnly 커서를 가진 레코드 셋의 경우 1이고, 그 외의 경우에는 모두 10의 값을 갖는다.
CursorType레코드 셋에서 사용할 커서의 유형을 정한다.
커서란 레코드 셋에서 현재 레코드를 가리키는 포인터를 말하고, 커서의 유형은 아래와 같은 유형이 있으며 각각 다른 특성을 가진다.
커서 유형지원 기능
AdOpenForwardOnlyNone
AdOpenKeysetadBookmark, adHoldRecords, adMovePrevious, adResync
AdOpenDynamicadMovePrevious
AdOpenStaticadBookmark, adHoldRecords, adMovePrevious, adResync
EditMode현재 레코드의 편집 상태를 나타낸다.
Filter레코드셋 객체 안에서 선택적으로 레코드들을 화면에 표시할 때 사용한다.
LockType레코드를 편집하는 동안 설정할 락 유형을 결정한다.
MaxRecords쿼리 실행후에 리턴될 최대 레코드 수를 지정한다.
PageCount레코드셋이 포함하고 있는 페이지 수를 지정한다.
PageSize페이지당 레코드 수를 결정한다.
RecordCount레코드셋 객체의 총 레코드 수를 리턴한다.
Source레코드셋 안의 데이터가 어디로부터 왔는지를 나타낸다.
Status순차적 업데이트또는 기타 작업에 대한 현재 레코드의 상태를 나타낸다.

메소드설명
AddNew레코드셋에 새로운 레코드를 생성한다.
CancelBatch진행중인 순차 업데이트를 취소한다.
CancelUpdateAddNew나 Edit로 변경한 레코드의 업데이트를 취소한다.
Clone존재하는 레코드셋의 복사하여 새로운 레코드셋을 생성한다.
Close열려진 레코드셋을 닫는다.
Delete레코드셋에서 현재 레코드를 삭제한다.
GetRows레코드셋에서 여러 개의 레코드를 읽어서 배열에 저장한다.
Move레코드셋에서 현재 레코드를 이동시킨다.
MoveFirst현재 레코드를 첫 레코드로 이동시킨다.
MoveLast현재 레코드를 마지막 레코드로 이동시킨다.
MoveNext현재 레코드를 다음 레코드로 이동시킨다.
MovePrevious현재 레코드를 이전 레코드로 이동시킨다.
NextRecordset현재 레코드셋을 종료하고 다음 레코드셋을 리턴한다.
Open쿼리나 SQL의 실행한 결과를 가져온다.
Requery쿼리를 다시 실행하여 레코드셋을 최신 정보로 고친다.
Resync데이터베이스로부터 현재 레코드셋의 데이터를 최신 정보로 갱신한다.
Supports레코드셋이 특정 기능을 지원하는지를 결정한다.
Update현재 레코드의 변경사항을 레코드셋 객체에 저장한다.
UpdateBatch진행중인 모든 순차 업데이트 작업을 디스크로 저장한다.
 

 Field 객체

 
필드 객체는 레코드셋 객체의 각 필드를 표현하는 객체이다.
레코드셋은 필드 객체들의 모임인 Fields 컬렉션을 가진다.
필드 객체는 레코드셋에 저장되어 있는 실질적인 값들에 접근할 수 있는 방법을 제공한다.
필드 객체에 대한 문법은 아래와 같이 다양한다.

Recordset.Fields.Item(0)
Recordset.Fields.Item("Name")
Recordset.Fields(0)
Recordset.Fields("Name")
Recordset(0)
Recordset("Name")
Recordset![Name]
 
프로퍼티설명
ActualSize필드 값의 실제 길이를 나타낸다.
Attributes필드 객체의 속성을 나타낸다.
DefinedSize필드 객체의 정의된 길이를 나타낸다.
Name필드의 이름을 나타낸다.
NumericScale숫자형 필드의 소수점 이하 자리수를 나타낸다.
OriginalValue필드의 값이 변하기 전에 원래의 값을 나타낸다.
Precision숫자형 필드의 최대 자리수를 나타낸다.
Type필드 객체의 데이터 타입을 나타낸다.
UnderlyingValue데이터베이스 내의 현재 필드의 값을 나타낸다.
Value필드의 값을 나타낸다.

메소드설명
AppendChunk데이터를 긴 문자열이나 바이너리 타입의 필드 객체에 추가한다.
GetChunk긴 문자열이나 바이너리 타입의 필드 객체에서 전부 또는 일부 내용을 리턴한다.
 

 Property 객체

 
프로퍼티설명
Attributes프로퍼티 객체의 속성을 나타낸다.
Name프로퍼티의 이름을 나타낸다.
Type프로퍼티의 데이터 타입을 나타낸다.
Value프로퍼티의 값을 나타낸다.



출처 : http://msdn.microsoft.com/ko-kr/library/ms972323.aspx

소개

ASP 페이지를 작성할 때 개발자는 실제로 ASP에 의해 제공되는 Response 개체를 통해 웹 클라이언트에 기록되는 형식의 텍스트 스트림을 만듭니다. 개발자는 여러 다른 방법으로 이러한 텍스트 스트림을 작성할 수 있으며 어떤 방법을 선택했는지에 따라 웹 응용 프로그램의 성능과 확장성에 큰 영향을 줄 수 있습니다. 필자는 다양한 상황에서 웹 응용 프로그램의 성능을 조정하려는 고객에게 도움을 제공한 바 있으며, 이 과정에서 성공을 거두기 위한 한 가지 방법이 HTML 스트림의 작성 방식을 변경하는 것이라는 사실을 알게 되었습니다. 이 기사에서는 몇 가지 일반적인 기술을 살펴보고 이러한 기술이 간단한 ASP 페이지의 성능에 어떤 영향을 주는지 테스트하도록 하겠습니다.

ASP 디자인

대부분의 ASP 개발자는 적절한 소프트웨어 엔지니어링 원칙을 따르면서 가능한 한 해당 코드를 모듈화합니다. 일반적으로 이 디자인은 별개의 특정 페이지 섹션을 모델링하는 함수가 들어 있는 여러 포함 파일의 형태를 가집니다. 대개 HTML 테이블 코드인 이러한 함수의 문자열 출력은 완전한 페이지를 작성하기 위한 다양한 조합으로 사용될 수 있습니다. 일부 개발자는 더 나아가 이러한 HTML 함수를 Visual Basic COM 구성 요소로 이동함으로써 컴파일된 코드가 제공할 수 있는 추가 성능 혜택을 얻고자 합니다.

이러한 디자인 방식이 분명 적절하기는 하지만 별도의 HTML 코드 구성 요소를 이루는 문자열을 작성하는 데 사용되는 방법은 실제 작업이 ASP 포함 파일 내에서 수행되는지 아니면 Visual Basic COM 구성 요소 내에서 수행되는지 여부에 관계없이 웹 사이트의 성능과 확장성에 상당한 영향을 줄 수 있습니다.

문자열 연결

WriteHTML이라는 함수에서 다음 코드 단편을 가져왔다고 가정해 보십시오. Data라는 매개 변수는 단순히 테이블 구조로 형식을 지정해야 할 일부 데이터(예: 데이터베이스에서 반환된 데이터)를 포함하는 문자열 배열입니다.

Function WriteHTML( Data )

Dim nRep

For 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>"
Next

WriteHTML = sHTML

End Function

대부분의 ASP 및 Visual Basic 개발자는 이 방법으로 HTML 코드를 작성합니다. sHTML 변수에 포함된 텍스트는 호출 코드로 반환된 다음 Response.Write를 통해 클라이언트에 기록됩니다. 물론 이것은 WriteHTML 함수의 간접 참조 없이 페이지 내에 직접 포함되는 유사한 코드로 표현될 수 있습니다. 그러나 이 코드는 ASP와 Visual Basic, BSTR 또는 Basic String이 사용하는 문자열 데이터 형식이 실제로 길이를 변경할 수 없다는 점에 문제가 있습니다. 이것은 문자열의 길이가 바뀔 때마다 메모리의 원래 문자열 표시가 파괴되고 새 문자열 데이터를 포함하는 새 표시가 만들어지며, 결과적으로 메모리 할당 작업과 메모리 할당 취소 작업이 수행된다는 것을 의미합니다. 물론 ASP와 Visual Basic에서는 이러한 작업이 모두 자동으로 처리되기 때문에 이러한 비용이 즉각 드러나지는 않습니다. 메모리를 할당 및 할당 취소하려면 단독 잠금을 확보하는 기본 런타임 코드가 필요하기 때문에 비용이 많이 들 수 있습니다. 이것은 대규모 문자열 연결 도중에 발생하는 것처럼 많은 양의 메모리 블록을 가진 문자열이 빠른 속도로 연속하여 할당 및 할당 취소되는 경우에 특히 분명하게 나타납니다. 이러한 현상은 단일 사용자 환경에서 큰 문제가 되지 않을 수 있지만 웹 서버에서 실행되는 ASP 응용 프로그램과 같은 서버 환경에서 사용될 때는 심각한 성능 및 확장성 문제를 일으킬 수 있습니다.

그렇다면 위 코드 단편에서 얼마나 많은 문자열 할당이 수행되고 있습니까  정답은 16입니다. 위 코드에서 모든 '&' 연산자는 sHTML 변수가 가리킨 문자열을 파괴하고 다시 만들게 합니다. 필자는 문자열 할당에 많은 비용이 들고 문자열이 커질수록 이러한 현상이 더욱 가중된다는 것을 앞서 언급한 바 있습니다. 아래에서는 위 코드를 개선하여 이러한 문제를 해결할 수 있는 방법에 대해 알아보겠습니다.

빠르고 쉬운 해결 방법

문자열 연결의 영향을 줄이는 방법에는 두 가지가 있습니다. 첫 번째 방법은 조작하는 문자열의 크기를 줄이는 것이고 두 번째 방법은 수행되는 문자열 할당 작업의 개수를 줄이는 것입니다. 아래의 WriteHTML 코드는 수정된 버전입니다.

Function WriteHTML( Data )

Dim nRep

For 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>" )
Next

WriteHTML = sHTML

End Function

언뜻 보면 이전 샘플과 이 코드 간에 차이점을 구별하기가 쉽지 않을 수 있습니다. 이 코드는 단순히 sHTML = sHTML & 뒤에 오는 전체 내용을 묶기 위해 괄호가 추가되었습니다. 이렇게 하면 우선 순위가 변경됨으로써 대부분의 문자열 연결 작업에서 조작되는 문자열의 크기가 줄어듭니다. 원본 코드 샘플에서는 ASP 컴파일러가 등호 오른쪽에 식이 있는지 확인하여 단순히 왼쪽에서 오른쪽으로 식을 평가합니다. 이 경우에는 계속 증가하는 sHTML이 포함된 반복 횟수 당 16개의 연결 작업이 수행됩니다. 반면, 새 버전에서는 작업을 수행해야 하는 순서를 변경함으로써 컴파일러에 힌트를 제공합니다. 이제 컴파일러는 식을 왼쪽에서 오른쪽으로 평가하며 괄호 안의 내용에서 밖에 있는 내용 순으로 평가합니다. 이 기술을 사용하면 증가하지 않는 더 작은 문자열이 포함된 반복 횟수 당 15개의 연결 작업과 증가하는 큰 sHTML이 포함된 하나의 연결 작업이 수행됩니다. 그림 1은 이러한 최적화된 연결의 메모리 사용 패턴이 표준 연결 방법과 비교하여 어떤 효과를 가지는지 보여 줍니다.

그림 1   표준 연결과 괄호로 묶인 연결 간의 메모리 사용 패턴 비교

이 기사의 뒷부분에 설명되어 있는 것처럼 괄호를 사용하면 특정 상황에서 성능과 확장성이 크게 달라질 수 있습니다.

StringBuilder

앞에서는 문자열 연결 문제에 대한 빠르고 쉬운 해결 방법을 살펴보았는데, 대부분의 경우 이 해결 방법을 통해 성능과 구현 노력 간의 가장 적절한 조화를 이룰 수 있습니다. 그러나 큰 문자열을 작성하는 작업의 성능을 개선하는 것이 중요시되는 경우에는 문자열 할당 작업 수를 줄이는 다른 방법을 취해야 하며 이를 위해서는 StringBuilder가 필요합니다. 이 클래스는 구성 가능한 문자열 버퍼를 유지 관리하고 해당 버퍼로의 새 텍스트 삽입을 관리하여 텍스트 길이가 문자열 버퍼의 길이를 초과할 경우에만 문자열 재할당을 수행하게 합니다. Microsoft .NET Framework에서는 해당 환경의 모든 문자열 연결 작업에서 권장되는 이러한 클래스(System.Text.StringBuilder)를 무료로 제공합니다. ASP 및 기존 Visual Basic 영역에서는 이 클래스를 액세스할 수 없으므로 직접 작성해야 합니다. 다음은 Visual Basic 6.0을 사용하여 만든 샘플 StringBuilder 클래스입니다(간단하게 하기 위해 여기서는 오류 처리 코드를 생략함).

Option Explicit

' 버퍼의 기본 초기 크기 및 증가 인수
Private Const DEF_INITIALSIZE As Long = 1000
Private Const DEF_GROWTH As Long = 1000

' 버퍼 크기 및 증가
Private m_nInitialSize As Long
Private m_nGrowth As Long

' 버퍼 및 버퍼 카운터
Private m_sText As String
Private m_nSize As Long
Private m_nPos As Long

Private Sub Class_Initialize()
   ' 크기 및 증가 기본값 설정
   m_nInitialSize = DEF_INITIALSIZE
   m_nGrowth = DEF_GROWTH
   ' 버퍼 초기화
   InitBuffer
End 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 = Growth
End Sub

' 버퍼 초기화
Private Sub InitBuffer()
   m_nSize = -1
   m_nPos = 1
End Sub

' 버퍼 증가
Private Sub Grow(Optional MinimimGrowth As Long)
   ' 필요한 경우 버퍼 초기화
   If m_nSize = -1 Then
      m_nSize = m_nInitialSize
      m_sText = Space$(m_nInitialSize)
   Else
      ' 증가
      Dim nGrowth As Long
      nGrowth = IIf(m_nGrowth > MinimimGrowth, 
            m_nGrowth, MinimimGrowth)
      m_nSize = m_nSize + nGrowth
      m_sText = m_sText & Space$(nGrowth)
   End If
End Sub

' 버퍼를 현재 사용된 크기로 줄이기
Private Sub Shrink()
   If m_nSize > m_nPos Then
      m_nSize = m_nPos - 1
      m_sText = RTrim$(m_sText)
   End If
End Sub

' 단일 텍스트 문자열 추가
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

' 여러 텍스트 문자열 추가
Public Sub Append(ParamArray Text())
   Dim nArg As Long
   For nArg = 0 To UBound(Text)
      AppendInternal CStr(Text(nArg))
   Next nArg
End Sub
 
' 현재 문자열 데이터를 반환하고 버퍼 줄이기
Public Function ToString() As String
   If m_nPos > 0 Then
      Shrink
      ToString = m_sText
   Else
      ToString = ""
   End If
End Function

' 버퍼를 지우고 다시 초기화
Public Sub Clear()
   InitBuffer
End Sub
 

이 클래스에서 사용되는 기본 원칙은 문자열 버퍼로 작동하는 클래스 수준에서 변수(m_sText)가 유지되고 Space$ 함수를 사용하여 공백 문자로 채움으로써 이 버퍼를 특정 크기로 설정한다는 것입니다. 추가 텍스트를 기존 텍스트에 연결해야 할 경우 버퍼의 크기가 새 텍스트를 보유할 만큼 충분한지 확인한 후 Mid$ 함수를 사용하여 텍스트를 올바른 위치에 삽입합니다. ToString 함수는 버퍼에 현재 저장된 텍스트를 반환하고 버퍼의 크기를 이 텍스트의 길이만큼 줄입니다. StringBuilder를 사용하기 위한 ASP 코드는 다음과 같이 표시됩니다.

Function WriteHTML( Data )

Dim oSB
Dim nRep

Set oSB = Server.CreateObject( "StringBuilderVB.StringBuilder" )
' 크기 및 증가 인수를 사용하여 버퍼 초기화
oSB.Init 15000, 7500

For 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>"
Next

WriteHTML = oSB.ToString()
Set oSB = Nothing

End Function 

StringBuilder는 매번 사용할 때마다 인스턴스를 만들어야 하고 이를 포함하는 DLL을 첫 번째 클래스 인스턴스 작성 시 로드해야 하므로 이 클래스를 사용하는 것에 대한 일정한 오버헤드가 존재합니다. 또한 StringBuilder 인스턴스에 대한 추가 메서드 호출을 하는 것과 관련해서도 오버헤드가 존재합니다. StringBuilder가 괄호로 묶인 '&'에 대해 수행되는 방법은 연결 수, 작성되는 문자열의 크기, StringBuilder 문자열 버퍼에 대한 초기화 매개 변수를 제대로 선택했는지 등의 여러 요소에 따라 달라집니다. 대부분의 경우 버퍼에서 필요한 공간을 예상보다 많이 잡아두는 것이 자주 공간을 늘리는 것보다 훨씬 더 나은 방법입니다.

기본 제공 방법

ASP에서는 단순히 Response.Write를 여러 번 호출하여 HTML 코드를 매우 신속하게 작성할 수 있는 방법이 포함되어 있습니다. 내부적으로 Write 함수는 매우 뛰어난 성능 특성을 제공하는 최적화된 문자열 버퍼를 사용합니다. 수정된WriteHTML 코드는 다음과 같이 표시됩니다.

Function WriteHTML( Data )

Dim nRep

For 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>"
Next

End Function 

이 코드가 최상의 성능과 확장성을 제공할 수 있지만 Response 스트림에 직접 기록되는 함수 안에 코드가 있고 이에 따라 호출 코드의 제어 수준이 저하되기 때문에 캡슐화가 다소 손상되었습니다. 또한 사용 가능한 Response 스트림에 함수가 종속되기 때문에 이 코드를 이동(예를 들어 COM 구성 요소로 이동)하는 것이 더 어려워집니다.

테스트

위에 제공된 네 가지 방법은 문자열의 더미 배열에서 제공된 단일 테이블이 있는 간단한 ASP 페이지를 사용하여 각각에 대해 테스트되었습니다. 테스트를 수행하기 위해 100MB/초 네트워크 상에서 단일 서버(Windows 2000 Advanced Server, 이중 PIII-1000MHz, 256MB RAM)에 대해 단일 클라이언트(Windows XP Professional, PIII-850MHz, 512MB RAM)의 ACT(Application Center Test)가 사용되었습니다. ACT는 웹 사이트에 연결되는 사용자 5명의 로드를 시뮬레이트하기 위해 5개의 스레드를 사용하도록 구성되었습니다. 각 테스트는 20초의 준비 시간과 가능한 한 많은 요청이 이루어지도록 100초의 로드 시간으로 구성되었습니다.

WriteHTML 함수에 대한 코드 단편에 나온 것처럼 기본 테이블 루프에서 반복 횟수를 다양하게 함으로써 다양한 수의 연결 작업에 대해 테스트 실행을 반복했습니다. 각 테스트 실행은 지금까지 설명된 모든 연결 방법을 사용하여 수행했습니다.

결과

아래에 나온 일련의 차트는 각 방법이 응용 프로그램의 처리량에 미치는 영향과 ASP 페이지의 응답 시간을 보여 줍니다. 이러한 차트는 응용 프로그램이 지원할 수 있는 요청 수와 사용자가 페이지를 브라우저로 다운로드하는 데 걸리는 시간에 대한 몇 가지 정보를 제공합니다.

표 1   사용된 연결 방법의 약어

방법 약어 설명
RESP 기본으로 제공되는 Response.Write 방법
CAT 표준 연결('&') 방법
PCAT 괄호로 묶인 연결('&') 방법
BLDR StringBuilder 방법


이 테스트가 일반 ASP 응용 프로그램의 작업 부하를 시뮬레이트하는 것과 관련하여 실제 상황과 다소 차이가 있지만 표 2에 나온 것처럼 420번의 반복에서도 페이지가 그렇게 크지 않다는 것을 분명하게 알 수 있습니다. 실제로는 이러한 수치의 높은 범위에 속하거나 이 테스트 범위의 제한을 초과할 수 있는 복잡한 ASP 페이지가 많이 존재합니다.

표 2   테스트 샘플의 페이지 크기 및 연결 수

반복 횟수 연결 수 페이지 크기(바이트)
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

그림 2   처리량 결과를 보여 주는 차트

그림 2에 나온 차트는 테스트된 전체 반복 범위에서 여러 Response.Write 방법(RESP)이 예상대로 최상의 처리량을 제공한다는 것을 보여 줍니다. 무엇보다도 놀라운 것은 표준 문자열 연결 방법(CAT)의 성능이 빠른 속도로 저하되고 괄호로 묶인 버전(PCAT)이 300번 이상의 반복에서 훨씬 더 나은 성능을 보인다는 것입니다. 약 220번의 반복에서 문자열 버퍼링으로 인해 StringBuilder 방법(BLDR)의 성능 향상이 이 방법의 고유한 오버헤드를 능가하기 시작하며, 따라서 이 지점 이상부터는 해당 ASP 페이지에서 StringBuilder를 사용하기 위한 추가 노력을 기울일만한 가치가 있을 것입니다.

그림 3   응답 시간 결과를 보여 주는 차트

그림 4   CAT가 생략된 응답 시간 결과를 보여 주는 차트

그림 3과 4의 차트는 TTFB(Time-To-First-Byte)로 측정된 밀리초 단위의 응답 시간을 보여 줍니다. 표준 문자열 연결 방법(CAT)의 응답 시간은 매우 빠른 속도로 증가하므로 그림 4에서는 이 방법을 포함하지 않고 차트를 반복함으로써 다른 방법 간의 차이점을 확인할 수 있게 했습니다. 표준 연결 방법(CAT)과 괄호로 묶인 연결 방법(PCAT)이 특정 임계값을 지난 후에 매우 빠른 속도로 증가하는 반면 여러 Response.Write 방법(RESP)과 StringBuilder 방법(BLDR)은 반복이 증가함에 따라 선형 수열의 형태를 가진다는 것은 흥미로운 일입니다.

결론

이 기사에서는 여러 다른 문자열 작성 기술을 ASP 환경 내에서 적용하는 방법을 중점적으로 살펴보았지만 이러한 방법이 수동으로 XML 문서를 만드는 경우처럼 Visual Basic 코드에서 큰 문자열을 만드는 모든 시나리오에 적용된다는 것을 잊어서는 안 됩니다. 다음 지침은 각 상황에서 어떤 방법이 가장 적합한지 결정하는 데 도움이 됩니다.

  • 특히 기존 코드를 다룰 경우에는 괄호로 묶인 '&' 방법을 우선적으로 사용합니다. 이렇게 하면 코드 구조가 거의 영향을 받지 않으며 기대 이상으로 응용 프로그램의 성능이 향상된다는 것을 확인할 수 있습니다.

  • 필요한 캡슐화 수준을 손상시키지 않는 것이 가능하다면 Response.Write를 사용합니다. 이렇게 하면 불필요한 메모리 내의 문자열 조작을 방지함으로써 항상 최상의 성능을 얻을 수 있습니다.

  • 매우 크거나 연결을 많이 사용하는 문자열을 작성하려면 StringBuilder를 사용합니다.

이 기사에 나온 것과 정확하게 같은 종류의 성능 향상을 개발자가 경험하지 못할 수 있지만 필자는 지금까지 이러한 기술을 실제 ASP 웹 응용 프로그램에서 사용하여 아주 적은 노력으로 성능 및 확장성 모두에서 상당한 향상을 거둔 바 있습니다.



출처 : http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=56&MAEULNO=22&no=135814&ref=135814 

Visual Studio 2008 Classic ASP(Active Server Page)
개발 환경 설정.

작성자김민삼

작성일: 2009-11-23

1.     웹사이트 프로젝트에서 새 항목 추가하기 메뉴에서 asp템플릿 추가하기.

1.1 C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\ItemTemplates\Web
      - \VisualBasic\1042 
폴더에 ASPPage.Zip 파일 복사
.
      - \CSharp\1042 
폴더에 ASPPage.Zip 파일 복사
.
1.2 
시작 > 프로그램
 > Microsoft Visual Studio 2008 > Visual Studio Tools
   > Visual Studio 2008 
명령프롬프트 실행
.
1.3 devenv /setup
 - 
명령프롬프트가 다시 생길 때 까지 대기
.

기존의 프로젝트에서 새 항목 추가하기에서 Active Server Page 항목이 추가되었는지 확인.

 

2.     파일 > 새 파일에서 asp템플릿 추가하기.

2.1   C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\NewFileItems
ASPPage.zip
파일의 압축을 풀고 ASPPage.asp를 복사.

2.2   ASPPage.asp ASP Page.asp로 파일이름 변경

2.3   1.2, 1.3번 수행.

visual Studio를 열고 파일 > 새 파일 > 범주의 일반 탭에서 ASP Page항목이 추가되었는지 확인.

* ASP관련 인텔리센스가 동작되지만 Include 시킨 파일의 전역 변수 및 메소드(Sub, Function)
 
정보는 나오지 않음.

 

 

3.     기존 웹사이트를 Visual Studio로 열기.
(로컬 IIS에 이미 설정되었는 가정하에 설명.)

3.1.  파일 > 새 프로젝트 > 프로젝트 형식의 기타 프로젝트 형식 > Visual Studio 솔루션 >
빈 솔루션 선택 후 솔루션 파일을 만들 디렉토리 설정.

3.2.  생성된 솔루션 선택 후 새 솔루션 폴더 생성

3.3.  생성된 폴더 선택 후 기존 웹사이트 열기
로컬IIS선택 후 불러올 웹사이트 선택하여 열기.
* IIS
설정의 .NET설정이 1.1버전으로 구성되어 있을 시 2.0으로 사이트를 구성하겠냐는

메시지가 나오면 예를 선택.(큰 의미는 없으나 Visual Studio 2008의 구성이 .net 2.0 이상의 버전으로 되어 있기에 일단 구성함.)
다음 메시지 창 ? .NET Framework 2.0 웹사이트 발견 이 나오지만 예를 선택
.
만약 Web.config가 생성되었을 시 삭제.

4.     디버깅하기.

4.1.  디버깅하고자 하는 페이지에 중단점 설정 후 브라우저 실행하여 해당 페이지 호출.

4.2.  Visual Studio 의 디버그 > 프로세스에 연결

4.3.  연결대상 영역의 선택버튼 클릭.

4.4.  다음 코드 형식 디버깅 선택.

4.5.  스크립트, T-SQL 선택 후 확인

4.6.  w3sp.exe 선택 후 연결.

 

ASPPage.zip파일 다운로드 경로
http://www.arkhipov.com/blog/ASPPage.zip

 

참조site

* template 관련 url (이 곳에서 asppage.zip를 다운로드 받을 수 있음.)

http://blogs.msdn.com/mikhailarkhipov/archive/2005/06/26/432852.aspx

 

디버깅 관련

http://www.codeproject.com/KB/debug/DebugVBScriptVS2008.aspx

 

기타 디버깅 방법

http://blogs.msdn.com/greggm/archive/2006/03/15/552108.aspx

Data Type

ADO CreateParameter Type

BigInt

adBigInt

Binary

adBinary

TimeStamp

adBinary

Bit

adBoolean

Char

adChar

Money

adCurrency

SmallMoney

adCurrency

DateTime

adDate

SmallDateTime

adDBTimeStamp

Float

adDouble

UniqueIdentifier

adGUID

Identity

adInteger

Int

adInteger

Image

adLongVarBinary

Text

adLongVarChar

Ntext

adLongVarWChar

Decimal

adNumeric

Numeric

adNumeric

Real

adSingle

SmallInt

adSmallInt

TinyInt

adUnsignedTinyInt

VarBinary

adVarBinary

VarChar

adVarChar

Sql_Variant

adVariant

NVarChar

adVarWChar

Nchar

adWChar






출처 : http://blog.naver.com/forioso/10093592150

ASP 에서 XML 파싱하는 클래스인데 상당히 깔끔한 클래스다. 주석에 달려있는 이수환님 감사합니다.
<%
'------------------------------------------------
'  XML  Parse 용 클래스
'  필요한 핵심부분만 만듬   2010. 06.18  이수환
'------------------------------------------------

Class XMLDOMParse
   
   Private m_DOM ' XMLDOM 객체

   ' ---------------------- 생성자 -----------------------
   Private Sub Class_Initialize()
      Set m_DOM = Server.CreateObject("Microsoft.XMLDOM")
   End Sub
   
   ' ---------------------- 소멸자 -----------------------
   Private Sub Class_Terminate()
      Set m_DOM = Nothing
   End Sub

   ' ------------------- Property Get --------------------
   Public Property Get TagText(tagName, index)
      Dim Nodes
 
      Set Nodes = m_DOM.getElementsByTagName(tagName)
      TagText = Nodes(index).Text
      Set Nodes = Nothing
   End Property


 
  ' ------------------- Property Get --------------------
   Public  Property Get AttributeText(tagName, index , item)
 AttributeText =  m_DOM.getElementsByTagName(tagName)(index).attributes.getNamedItem(item).Text
 End Property
 

 

   ' ------------------- 원격 XML 읽기 --------------------
   Public Function LoadHTTP(url)
      with m_DOM
         .async = False ' 동기식 호출
         .setProperty "ServerHTTPRequest", True ' HTTP로 XML 데이터 가져옴
  
         LoadHTTP = .Load(url)
      end with 
   End Function


   ' -------------------  XML 읽기 --------------------
   Public Function Load(strXML )
      with m_DOM
         .async = False ' 동기식 호출
         .loadXML(strXML)
      end with 
   End Function

   ' -------------------  HTML 페이지  읽기 --------------------
  Public Function  OpenHttp( PgURL) 
   Set xmlHttp = Server.CreateObject("Microsoft.XMLHTTP") 
      xmlHttp.Open "GET", PgURL, False 
        xmlHttp.Send 
  Ret =  xmlHttp.ResponseText
      Set xmlHttp = Nothing
   OpenHttp = Ret
  End Function

End Class


%>

 

 

 

1>

    Set xml = new XMLDOMParse
   xml.LoadHTTP(http://domain.com/getval.asp?pc_a=" & sPC)
   ErrState = xml.TagText("ERROR",0)

 

2>

 Set xml = new XMLDOMParse
 Data = xml.OpenHttp("http://domain.com/getcid.asp?filename=" & sFileName ) 
 xml.load(Data)
 gCID = xml.TagText("CID",0)

 

[출처] ASP XML 파싱함수|작성자 사랑굳

'Development > ASP' 카테고리의 다른 글

ADO DataType (SQL → ADO)  (0) 2012.02.04
IIS (7.0 이하 버전 기준 확장자 매핑)  (0) 2011.04.07
XML Parse  (0) 2011.03.28
윈도우 2008서버에서 ASP로 이메일 발송 - CDO.Message  (0) 2011.01.10
VBScript Functions  (0) 2010.12.13
ABC 업로드 컴포넌트 속성  (0) 2010.12.01
테스트 환경
  • Windows 2008 Server R2
  • IIS 7.5 (SMTP만 6.0)
  • ASP

웹서버를 윈도우 2003 에서 2008 로 교체하는 상황이 생겨서 교체하게 되었다.
근데 잘되던 SMTP로 메일발송하는 코드가 작동오류.
해서 개인적인 생각으로는 왠만하면 2008로 교체하며 이메일로 인한 오류는 거의 이것들 일것 같은
생각이 든다.

먼저 간단하게 함수를 만들어서 테스트를 해보았다.

Public Function eMailCDOSend(MailTag, MailTitle, Sender, Receiver)
' 2008서버에서 발송하는 환경정보 설정

Dim eMailObject, eMailConfig
Set eMailObject = Server.CreateObject("CDO.Message")
Set eMailConfig = Server.CreateObject("CDO.Configuration")
Dim SchemaPath : SchemaPath = "http://schemas.microsoft.com/cdo/configuration/"

With eMailConfig.Fields
.Item (SchemaPath & "sendusing") = 2 'CDOSendUsingPort
.Item (SchemaPath & "smtpserver") = "127.0.0.1" 'CDOSendUsingPort [ServerIP]
            .Item (SchemaPath & "smtpserver") = "localhost"    'CDOSendUsingPort
.Item (SchemaPath & "smtpserverport") = "25" 'Port
.Update
End With
eMailObject.Configuration = eMailConfig
Set eMailConfig = Nothing

With eMailObject
.From = Sender
.To = "<" & Receiver & ">"
.Subject = MailTitle
.HTMLBody = MailTag
.HTMLBodyPart.Charset = MailCharSet
.Send
End With
Set eMailObject = Nothing
End Function

Dim MailSendReturnValue
MailSendReturnValue = WVP.eMailCDOSend ("<h4>발송</h4>", "발송","www.jkun.net","jkun75@jkun.net")


결과는 정상이었다. 정상적으로 결과를 반환한다.
그런데도 메일 발송에는 실패하는 것이다.
해서 다음을 확인한다. 아 그리고 SMTP 를 IIS 6.0 으로 설치하였는데 7.5 에서는 테스트를 해보지 않았다.
일단 IIS 6.0 기준으로 릴레이 제한을 확인한다.




이렇게 해서 확인했는데도 실패하는거다. 아래와 같이..
아래 메세지는 에러객체 메세지를 찍은것이다.

서버가 하나 이상의 받는 사람 주소를 거부했습니다.
서버 응답은 다음과 같습니다. 501 5.5.4 Invalid Address 
-2147220977

문제는... 받는 사람 이메일주소에 내 이름을 썼다는 것이다. 미쳐가지고.. ㅋㅋ
다시 정상적으로 이메일주소를 입력하고 테스트하니 모두 정상.

우리 모두 필요악인 삽질을 줄이는 즐거운 현상이 많아지길. ㅋㅋ
삽질보단 고민과 생각을 늘리는 쪽으로~

그리고 댓글 달아주는 센스! ㅋㅋㅋ

'Development > ASP' 카테고리의 다른 글

IIS (7.0 이하 버전 기준 확장자 매핑)  (0) 2011.04.07
XML Parse  (0) 2011.03.28
윈도우 2008서버에서 ASP로 이메일 발송 - CDO.Message  (0) 2011.01.10
VBScript Functions  (0) 2010.12.13
ABC 업로드 컴포넌트 속성  (0) 2010.12.01
ASP 날짜 관련  (0) 2010.10.06
VBScript Function 

Abs

Array

Asc

Atn

CBool

CByte

CCur

CDate

CDbl

Chr

CInt

CLng

Conversions

Cos

CreateObject

CSng

CStr

Date

DateAdd

DateDiff

DatePart

DateSerial

DateValue

Day

Escape

Eval

Exp

Filter

FormatCurrency

FormatDateTime

FormatNumber

FormatPercent

GetLocale

GetObject

GetRef

Hex

Hour

InputBox

InStr

InStrRev

Int, Fix

IsArray

IsDate

IsEmpty

IsNull

IsNumeric

IsObject

Join

LBound

LCase

Left

Len

LoadPicture

Log

LTrim; RTrim; and Trim

Maths

Mid

Minute

Month

MonthName

MsgBox

Now

Oct

Replace

RGB

Right

Rnd

Round

ScriptEngine

ScriptEngineBuildVersion

ScriptEngineMajorVersion

ScriptEngineMinorVersion

Second

SetLocale

Sgn

Sin

Space

Split

Sqr

StrComp

String

StrReverse

Tan

Time

Timer

TimeSerial

TimeValue

TypeName

UBound

UCase

Unescape

VarType

Weekday

WeekdayName

Year

'Development > ASP' 카테고리의 다른 글

XML Parse  (0) 2011.03.28
윈도우 2008서버에서 ASP로 이메일 발송 - CDO.Message  (0) 2011.01.10
VBScript Functions  (0) 2010.12.13
ABC 업로드 컴포넌트 속성  (0) 2010.12.01
ASP 날짜 관련  (0) 2010.10.06
ASP 기본 문법과 함수  (0) 2010.10.06
ABC업로드 컴포넌트가 가진 객체, 메서드, 속성은 다음과 같다. ♥
XFORM OBJECT

XFORM객체는 multipart format 엔코딩에서 Request.Form을 대신한다.
This object is an upload capable replacement for the standard Microsoft 
Request.Form object. It handles forms encoded in multipart format as 
defined in RFC 1867.

Method Description
Read Read in raw uploaded data from a file.
Save Save the raw uploaded data.
SetUser Impersonate a different user.

Property Default Description
Item Yes A set of fields referenced by name or number.
Count No The number of field sets available.
ID No The form unique ID.
AbsolutePath No Whether to use absolute or virtual paths.
Overwrite No Whether to overwrite existing files.
MaxUploadSize No The maximum size of uploads to allow.
User No The current identity being used by ABCUpload.
Domain No The domain which the user belongs to.
CodePage No The character set codepage to use.
Multipart No Whether multipart data was submitted.
Streams No Whether to use NTFS streams.

XFIELD OBJECT

HTML FORM전송을 통해 업로드된 파일 속성을 알 수 있고, 저장할 수 있다.
This object represents the data uploaded within a particular HTML form field.
It allows you to examine the data (e.g. to determine if a file was uploaded) 
and perform operations on it (e.g. save the data to disk).


Method Description
Save Allows you to save the contents of a field. * 저장하는 메서드

Property Default Description
Name No The name of the HTML field.
Content Yes The content of the field as a string.
Length No The size of the data held in the field. * 파일사이즈
FileExists No If a file was uploaded. * 업로드되었는지
FileName No The URL safe uploaded filename.
FileType No The inferred file name extension of the file.
MIMEType No The MIME type of the uploaded file. * 마임타입
MacBinary No If the file was encoded as MacBinary.
SafeFileName No The Windows safe filename.
RawFileName No The uploaded filename. * 파일이름 구하기
RawFileType No The file name extension of the file.
RawFilePath No The uploaded filepath.
Data No The data within the uploaded file.
Resource No The resource data within the uploaded file.
RawData No The raw uploaded file data.
RawLength No The raw uploaded file length.
ImageType No The type of image file uploaded.* 이미지파일종류
ImageWidth No The width of image file uploaded.* 이미지 넓이
ImageHeight No The height of image file uploaded.* 이미지 높이

아무래도 자주사용하는 형식인데.. 짜기도 구찮고.. 외우기도 구찮고..ㅋㅋ 근데 고맙게도..

출처 : http://jupiter0410.tistory.com/20

01.<%

02.    ' 금일 날짜 표현방법
03.    Response.write Right("0000"&Year(date),4) &"-"& Right("00"&Month(date),2) &"-"&Right("00"&Day(date),2)
04. 
05.    ' 1년전 날짜 구하기
06.    Tdate = DateAdd("m", -12 DateValue(now))
07.    Response.write Tdate &"<BR>"
08. 
09. 
10.    ' 7일후 날짜 구하기
11.    Tdate = DateAdd("d", 7 DateValue(now))
12.    ' or
13.    Tdate = dateadd("d", 7, Now())
14.    Response.write Tdate &"<BR>"
15.  
16. 
17.    '순수히 날짜만 구할려면 MID 함수 사용
18.    Response.write MID(Tdate,1,10)
19. 
20. 
21.    '"-" 문자열을 제거할려면 replace 함수를 사용하면 됩니다.
22.    Response.write replace("문자열", "-", "")
23.%>

ASP 기본 문법과 함수

ASP의 기본 문법

□ 변수, 배열, 개체 선언

Dim 변수이름
Dim 배열이름(배열크기)
;
대개 일반 변수는 정의 하지 않고 사용 한다. 그러나 배열 변수는 정의를 한 후에 사용 해야 한다.

배열 크기 조정

ReDim [preserve] 배열이름(새로운 크기)
; preserve 를 붙이면 원래의 배열 내용을 유지하면서 크기가 조절된다.

개체선언

SET 개체명 = Server.CreateObject("컴포넌트이름")

□ 연산자

산술 연산자 비교 연산자 논리 연산자
설명 기호 설명 기호 설명 기호
지수 ^ 같다 = 논리적 부정 Not
단항 부정 - 같지 않다 <> 논리적 결합 And
곱셈 * 보다 작다 < 논리적 분리 Or
나눗셈 / 보다 크다 > 논리적 배타 Xor
정수 나눗셈 \ 보다 작거나 같다 <= 논리적 동등성 Eqv
나머지 연산 Mod 보다 크거나 같다 >= 논리적 함축성 Imp
덧셈 + 개체 동등성 Is    
뺄셈 -        
문자열 연결 &        
□ 논리 구문들
조건분기(IF) 예제
조건에 따라 실행을 다르게 하는 구문

IF 조건 THEN
    [
참일때 실행문]
[ELSEIF
조건 THEN
    [
참일때 실행문]]
    ...
[ELSE
    [
거짓일때 실행문]]
END IF

page = Request.QueryString("page")
if page="" then
    page=1
end if

s = Request.QueryString("s")
if s="1" then
    s = "
남자"
else
    s = "
여자"
end if
cmd = Request.QueryString("cmd")
if cmd="list" then
    ' list
처리
elseif cmd="view" then
    ' view
처리
elseif cmd="write" then
    ' write
처리
else
    '
에러 처리
end if
다중분기(SELECT CASE) 예제
elseif와 같은 여러개의 조건에 따른 처리를 한다. 

SELECT CASE
    [CASE 경우n
        [
실행문]]
    ...
    [CASE ELSE
        [
실행문]]
END SELECT

cmd = Request.QueryString("cmd")
select case cmd
    case "list"
        ' list
처리
    case "view"
        ' view
처리
    case "write"
        ' write
처리
    case else
        '
에러 처리
end select 
회수가 정해진 반복문(FOR) 예제

일정한 회수 만큼 반복하여 같은 문장을 실행 할때 사용한다.
반복 하는 도중에 EXIT FOR를 만나면 반복을 그만둔다.
증가치가 1인경우 생략 가능하다.

FOR 변수=처음값 TO 최종값 [STEP 증가치]
    [
실행문]
    [EXIT FOR]
NEXT

for i=1 to 5
    Response.Write i
next

for i=1 to 5
    for j=1 to i
        Response.Write "*"
    next
    Response.Write "<br>"
next
컬렉션 요소 만큼 반복(FOR EACH) 예제
개체나 컬렉션의 요소 수만큼 반복한다.

FOR EACH 변수명 IN 컬렉션
    [실행문]
NEXT

for each a in request.ServerVariables
    response.write a & "="
    response.write request.ServerVariables(a)
    response.write "<br>"
next
선행 조건검사 반복 예제

조건이 참인동안(while) 반복하거나, 참이 될때까지(until) 반복 한다.
exit do를 만나면 반복을 그만둔다.
조건을 먼저 검사한 후 실행문을 반복 실행 한다.

DO {WHILE | UNTIL} 조건
    [실행문]
    [Exit Do]
LOOP

a = 10
do while a<1
    Response.Write a
    a = a - 1
loop

결과는
 10987654321
이 출력 된다.
후행 조건검사 반복 예제

do while과 동일 하지만 조건을 뒤에 검사 한다.

DO
    [
실행문]
    [Exit Do]
LOOP {WHILE | UNTIL}
조건

a = 10
do
    Response.Write a
    a = a - 1
loop while a<1

결과는
 1098765432
이 출력 된다.

□ Function과 SUB 루틴

프로그램에서 같은 동작을 하는 부분이 여러번 나올때 Sub나 Function을 이용하면 전체 프로그램의 길이가 짧아 지며, 구조화 시킬 수 있다. Function은 함수형태로 사용되게 작성을 하는 것이고, Sub는 명령어 형태로 사용하게 작성 하는 것이다.

SUB(서브루틴) 정의와 사용 - 결과 값이 없고, 명령어 형태이다.

정의 측 실행 하는 방법
SUB 서브루틴이름(인수1, 인수2 ...)

 
서버루틴 내용
    [exit sub]

END SUB
서브루틴이름  인수1, 인수2 ...

Function(함수) 정의와 사용 - 결과 값이 있고, 함수 형태 이다.

정의 측 실행 하는 방법
Function 함수이름(인수1, 인수2 ...)

 
함수 내용
    [exit function]

    함수이름 = 결과값
END Function
변수 = 함수이름(인수1, 인수2 ...)

VBScript 기본 함수들

변환 함수들
함수 설명
ASC(문자열) 첫문자의 ANSI코드 값 추출
CHR(숫자) 지정됨 숫자에 해당하는 ANSI문자값
CBOOL() 값을 TRUE/FALSE형식으로 변환
BYTE() 값을 BYTE형으로 변환
CDATE() 값을 날짜형으로 변환
CDBL() 값을 DOUBLE(실수)형으로 변환
CINT() 값을 INT(정수)형으로 변환
CLNG() 값을 LONG(정수)형으로 변환
CSNG() 값을 SINGLE(실수)형으로 변환
FIX(실수) 소수점 아래를 버린다.
HEX(수치) 16진수 문자로 바꾼다.
INT(실수) 실수를 정수로 바꾼다.
SGN(수치) 수치의 부호를 -1, 0, 1의 형태로 구한다.
날짜/시간 함수들
함수/예약변수 설명
NOW 현재 서버의 날짜/시각
DATE 현재 서버의 날짜
TIME 현재 서버의 시각
YEAR(날짜값) 날짜에서 년도 추출
MONTH(날짜값) 날짜에서 월 추출
DAY(날짜값) 날짜에서 일 추출
WEEKDAY(날짜값) 날짜에서 요일 추출 1:일, 2:월, 3:화 ... 7:토요일
HOUR(날짜형) 날짜 형식에서 시간 추출
MINUTE(날짜형) 날짜 형식에서 분 추출
SECOND(날짜형) 날짜 형식에서 초 추출
DateAdd(간격, , 날짜) 날짜에서 정해진 간격으로 수만큼 더한다.
정해진 간격은 y : 1년, m : 월, d : 일, h : 시, n : 분, s : 초
수학 관련 함수들
함수 설명
RND()  0부터 1사이의 무작위 난수 발생
ATN() 아크 탄젠트
COS() 코사인
EXP(값) e(자연로그 밑수)의 인자 제곱
LOG(값) 자연로그 값
SIN(각) 사인값
TAN(각) 탄젠트
※ 각은 라디안 값인다.
문자열 관련 함수들
함수 설명
FormatCurrency(v)  통화형식으로 표시
FormatDateTime(v) 날짜형으로 표시
FormatPercent(v) %형식으로 표시(*100을 한다.)
Lcase(s) 소문자로 변환
Ucase(s) 대문자로 변환
Instr(s1, s2) s1에서 s2가 있는 위치
Left(s, v) s에서 왼쪽에서 v글자만큼 추출
Right(s, v) s에서 오른쪽에서 v글자만큼 추출
Mid(s, v1, v2) s에서 v1위치에서 v2글자만큼 추출
Trim(s) s의 좌우 공백(Vbcrlf 포함) 제거
RTrim(s) s의 오른쪽 공백 제거
LTrim(s) s의 왼쪽 공백 제거
Split(s, d) s문자열을 d문자로 나누어서 배열에 저장 한다.
StrReverse(s) s를 거꾸로 한다.
Replace(s, s1, s2) s문자열 에서 s1을 s2로 모두 바꾼다.
변수 테스트 함수들
함수 설명
IsArray(s) s가 배열인가?
IsDate(s) s가 날짜형인가?
IsEmpty(s) s가 변수로 할당 되어 있는가?
IsNull(s) s가 빈 문자열인가?
IsNumeric(s) s가 숫자인가?
IsObject(s) s가 개체인가?
VarType(s) s의 형식을 나타내는 숫자값

 


※ 테스트 환경
IIS 6.0 / Windows 2003 Server

기본적으로 ASP 는 스파게티형 코드라고도 많이 불리고 실제로도 보면 유지보수및 관리가 어렵게
시간이 지나면.. 쉽게 말해서 상당히 꼬여 있다.
그래서 원활한 서비스와 유지보수를 위하여 ASP.NET 과 같이 ASP도 UI코드와 서버사이드 코드를
분리할 수 가 있다. (엄밀히 말하면 흉내 삘이다. ㅋㅋ)
해서 완성된 분리된 코드를 보면.. (개인적으로) 상당히 깔끔하고 심플한 코드가
된다. 그러기엔 이미 많이 알고들 있는 Windows Script Component 를 이용하는 것이다.
그리고 주요 서버사이드 코드의 모듈화.
완성된 샘플코드는 다음과 같다. UI 코드는 웹표준 코드를 적용시킨 XHTML 4.01 이다.
이건 어디까지나 내가 작업할때 스타일이니 문제점을 지적해주되 비판하지는 말아주기를..
개발자가 서로 욕하면 밑도 끝도 없음.. ㅋㅋ


일단 위와 같이 되면 서버사이드 코드는 <%%> 요런 형식의 코드는 거의 보이지를 않는다.
불가항력적으로

<div class="sample"><%=컨텐츠%></div>

이런 코드는 피할 수 가 없지만..
그래도 엄청나게 이원화 시켰기 때문에 코드관리가 상당히 용이해진다.
그리고 분리된 서버사이드 코드는 각각의 변수,상수 및 클래스들이 정의되어 있다.
이런식으로 관리하니 스타일 시트및 html 코드가 변한다 하더라도 서버사이드상으로는
왠만하면 지장을 주지 않게 되었다.
개인적인 경험으로는 꽤나 UI 코드에 유연하게 대처할 수가 있었다.
그리고 보다 코드에 대한 정의들이 명확해질 수 있었고.
후에 보면 유지보수에도 상당한 시간절감 효과를 느낄 수 있었다.
그리고 발견된 문제점들은 누적된 후 버전업으로 업데이트및 패치!
또한 서버사이드 코드 변화에도 UI 에 지장을 줄일수 있었다.
어쩔때는 전혀 없던가.ㅎㅎ

이미 많은 분들이 더 좋은 방법들을 사용하고 있지만.. 개인적인 간단한 방법론(?). 아니, 스타일이니
도움이 되는 분들이 있으면 다행이고. ㅎㅎ;;
ASP (Active Server Page) . 이제는 클래식이 되어버렸지만...

아직까지도 현업에서 상당히 많이 쓰이고 신규로도 사용되어지고 있다.
그러기에 한번씩 생각을 정리하는 차원에서 포스팅을 해본거지..^^;

ASP 응용 프로그램의 문자열 처리 성능 향상

James Musson

Microsoft UK, Developer Services

2003년 3월

 

적용 대상:
   Microsoft Active Server Pages
   Microsoft Visual Basic

 

요약: 대부분의 ASP(Active Server Pages ) 응용 프로그램은 문자열 연결을 기반으로 HTML 형식 데이터를 작성한 뒤 사용자에게 표시합니다. 이 기사에서는 이러한 HTML 데이터 스트림을 만드는 여러 방법을 비교하여 특정 상황에서 어떤 방법이 다른 방법보다 우수한 성능을 제공하는지 살펴보도록 하겠습니다. 여기서는 개발자가 ASP 및 Visual Basic 프로그래밍을 잘 알고 있다고 가정합니다(11페이지/인쇄 페이지 기준).

목차

소개
ASP 디자인
문자열 연결
빠르고 쉬운 해결 방법
StringBuilder
기본 제공 방법
테스트
결과
결론

소개

ASP 페이지를 작성할 때 개발자는 실제로 ASP에 의해 제공되는 Response 개체를 통해 웹 클라이언트에 기록되는 형식의 텍스트 스트림을 만듭니다. 개발자는 여러 다른 방법으로 이러한 텍스트 스트림을 작성할 수 있으며 어떤 방법을 선택했는지에 따라 웹 응용 프로그램의 성능과 확장성에 큰 영향을 줄 수 있습니다. 필자는 다양한 상황에서 웹 응용 프로그램의 성능을 조정하려는 고객에게 도움을 제공한 바 있으며, 이 과정에서 성공을 거두기 위한 한 가지 방법이 HTML 스트림의 작성 방식을 변경하는 것이라는 사실을 알게 되었습니다. 이 기사에서는 몇 가지 일반적인 기술을 살펴보고 이러한 기술이 간단한 ASP 페이지의 성능에 어떤 영향을 주는지 테스트하도록 하겠습니다.

ASP 디자인

대부분의 ASP 개발자는 적절한 소프트웨어 엔지니어링 원칙을 따르면서 가능한 한 해당 코드를 모듈화합니다. 일반적으로 이 디자인은 별개의 특정 페이지 섹션을 모델링하는 함수가 들어 있는 여러 포함 파일의 형태를 가집니다. 대개 HTML 테이블 코드인 이러한 함수의 문자열 출력은 완전한 페이지를 작성하기 위한 다양한 조합으로 사용될 수 있습니다. 일부 개발자는 더 나아가 이러한 HTML 함수를 Visual Basic COM 구성 요소로 이동함으로써 컴파일된 코드가 제공할 수 있는 추가 성능 혜택을 얻고자 합니다.

 

이러한 디자인 방식이 분명 적절하기는 하지만 별도의 HTML 코드 구성 요소를 이루는 문자열을 작성하는 데 사용되는 방법은 실제 작업이 ASP 포함 파일 내에서 수행되는지 아니면 Visual Basic COM 구성 요소 내에서 수행되는지 여부에 관계없이 웹 사이트의 성능과 확장성에 상당한 영향을 줄 수 있습니다.

문자열 연결

WriteHTML이라는 함수에서 다음 코드 단편을 가져왔다고 가정해 보십시오. Data라는 매개 변수는 단순히 테이블 구조로 형식을 지정해야 할 일부 데이터(예: 데이터베이스에서 반환된 데이터)를 포함하는 문자열 배열입니다.

Function WriteHTML( Data )

Dim nRep

For 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>"
Next

WriteHTML = sHTML

End Function

대부분의 ASP 및 Visual Basic 개발자는 이 방법으로 HTML 코드를 작성합니다. sHTML 변수에 포함된 텍스트는 호출 코드로 반환된 다음 Response.Write를 통해 클라이언트에 기록됩니다. 물론 이것은WriteHTML 함수의 간접 참조 없이 페이지 내에 직접 포함되는 유사한 코드로 표현될 수 있습니다. 그러나 이 코드는 ASP와 Visual Basic, BSTR 또는 Basic String이 사용하는 문자열 데이터 형식이 실제로 길이를 변경할 수 없다는 점에 문제가 있습니다. 이것은 문자열의 길이가 바뀔 때마다 메모리의 원래 문자열 표시가 파괴되고 새 문자열 데이터를 포함하는 새 표시가 만들어지며, 결과적으로 메모리 할당 작업과 메모리 할당 취소 작업이 수행된다는 것을 의미합니다. 물론 ASP와 Visual Basic에서는 이러한 작업이 모두 자동으로 처리되기 때문에 이러한 비용이 즉각 드러나지는 않습니다. 메모리를 할당 및 할당 취소하려면 단독 잠금을 확보하는 기본 런타임 코드가 필요하기 때문에 비용이 많이 들 수 있습니다. 이것은 대규모 문자열 연결 도중에 발생하는 것처럼 많은 양의 메모리 블록을 가진 문자열이 빠른 속도로 연속하여 할당 및 할당 취소되는 경우에 특히 분명하게 나타납니다. 이러한 현상은 단일 사용자 환경에서 큰 문제가 되지 않을 수 있지만 웹 서버에서 실행되는 ASP 응용 프로그램과 같은 서버 환경에서 사용될 때는 심각한 성능 및 확장성 문제를 일으킬 수 있습니다.

 

그렇다면 위 코드 단편에서 얼마나 많은 문자열 할당이 수행되고 있습니까  정답은 16입니다. 위 코드에서 모든 '&' 연산자는 sHTML 변수가 가리킨 문자열을 파괴하고 다시 만들게 합니다. 필자는 문자열 할당에 많은 비용이 들고 문자열이 커질수록 이러한 현상이 더욱 가중된다는 것을 앞서 언급한 바 있습니다. 아래에서는 위 코드를 개선하여 이러한 문제를 해결할 수 있는 방법에 대해 알아보겠습니다.

빠르고 쉬운 해결 방법

문자열 연결의 영향을 줄이는 방법에는 두 가지가 있습니다. 첫 번째 방법은 조작하는 문자열의 크기를 줄이는 것이고 두 번째 방법은 수행되는 문자열 할당 작업의 개수를 줄이는 것입니다. 아래의 WriteHTML 코드는 수정된 버전입니다.

Function WriteHTML( Data )

Dim nRep

For 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>" )
Next

WriteHTML = sHTML

End Function

 

언뜻 보면 이전 샘플과 이 코드 간에 차이점을 구별하기가 쉽지 않을 수 있습니다. 이 코드는 단순히 sHTML = sHTML & 뒤에 오는 전체 내용을 묶기 위해 괄호가 추가되었습니다. 이렇게 하면 우선 순위가 변경됨으로써 대부분의 문자열 연결 작업에서 조작되는 문자열의 크기가 줄어듭니다. 원본 코드 샘플에서는 ASP 컴파일러가 등호 오른쪽에 식이 있는지 확인하여 단순히 왼쪽에서 오른쪽으로 식을 평가합니다. 이 경우에는 계속 증가하는 sHTML이 포함된 반복 횟수 당 16개의 연결 작업이 수행됩니다. 반면, 새 버전에서는 작업을 수행해야 하는 순서를 변경함으로써 컴파일러에 힌트를 제공합니다. 이제 컴파일러는 식을 왼쪽에서 오른쪽으로 평가하며 괄호 안의 내용에서 밖에 있는 내용 순으로 평가합니다. 이 기술을 사용하면 증가하지 않는 더 작은 문자열이 포함된 반복 횟수 당 15개의 연결 작업과 증가하는 큰 sHTML이 포함된 하나의 연결 작업이 수행됩니다. 그림 1은 이러한 최적화된 연결의 메모리 사용 패턴이 표준 연결 방법과 비교하여 어떤 효과를 가지는지 보여 줍니다.

 

그림 1   표준 연결과 괄호로 묶인 연결 간의 메모리 사용 패턴 비교

 

이 기사의 뒷부분에 설명되어 있는 것처럼 괄호를 사용하면 특정 상황에서 성능과 확장성이 크게 달라질 수 있습니다.

StringBuilder

앞에서는 문자열 연결 문제에 대한 빠르고 쉬운 해결 방법을 살펴보았는데, 대부분의 경우 이 해결 방법을 통해 성능과 구현 노력 간의 가장 적절한 조화를 이룰 수 있습니다. 그러나 큰 문자열을 작성하는 작업의 성능을 개선하는 것이 중요시되는 경우에는 문자열 할당 작업 수를 줄이는 다른 방법을 취해야 하며 이를 위해서는 StringBuilder가 필요합니다. 이 클래스는 구성 가능한 문자열 버퍼를 유지 관리하고 해당 버퍼로의 새 텍스트 삽입을 관리하여 텍스트 길이가 문자열 버퍼의 길이를 초과할 경우에만 문자열 재할당을 수행하게 합니다. Microsoft .NET Framework에서는 해당 환경의 모든 문자열 연결 작업에서 권장되는 이러한 클래스(System.Text.StringBuilder)를 무료로 제공합니다. ASP 및 기존 Visual Basic 영역에서는 이 클래스를 액세스할 수 없으므로 직접 작성해야 합니다. 다음은 Visual Basic 6.0을 사용하여 만든 샘플StringBuilder 클래스입니다(간단하게 하기 위해 여기서는 오류 처리 코드를 생략함).

Option Explicit

' 버퍼의 기본 초기 크기 및 증가 인수
Private Const DEF_INITIALSIZE As Long = 1000
Private Const DEF_GROWTH As Long = 1000

' 버퍼 크기 및 증가
Private m_nInitialSize As Long
Private m_nGrowth As Long

' 버퍼 및 버퍼 카운터
Private m_sText As String
Private m_nSize As Long
Private m_nPos As Long

Private Sub Class_Initialize()
   ' 크기 및 증가 기본값 설정
   m_nInitialSize = DEF_INITIALSIZE
   m_nGrowth = DEF_GROWTH
   ' 버퍼 초기화
   InitBuffer
End 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 = Growth
End Sub

' 버퍼 초기화
Private Sub InitBuffer()
   m_nSize = -1
   m_nPos = 1
End Sub

' 버퍼 증가
Private Sub Grow(Optional MinimimGrowth As Long)
   ' 필요한 경우 버퍼 초기화
   If m_nSize = -1 Then
      m_nSize = m_nInitialSize
      m_sText = Space$(m_nInitialSize)
   Else
      ' 증가
      Dim nGrowth As Long
      nGrowth = IIf(m_nGrowth > MinimimGrowth, 
            m_nGrowth, MinimimGrowth)
      m_nSize = m_nSize + nGrowth
      m_sText = m_sText & Space$(nGrowth)
   End If
End Sub

' 버퍼를 현재 사용된 크기로 줄이기
Private Sub Shrink()
   If m_nSize > m_nPos Then
      m_nSize = m_nPos - 1
      m_sText = RTrim$(m_sText)
   End If
End Sub

' 단일 텍스트 문자열 추가
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

' 여러 텍스트 문자열 추가
Public Sub Append(ParamArray Text())
   Dim nArg As Long
   For nArg = 0 To UBound(Text)
      AppendInternal CStr(Text(nArg))
   Next nArg
End Sub
 
' 현재 문자열 데이터를 반환하고 버퍼 줄이기
Public Function ToString() As String
   If m_nPos > 0 Then
      Shrink
      ToString = m_sText
   Else
      ToString = ""
   End If
End Function

' 버퍼를 지우고 다시 초기화
Public Sub Clear()
   InitBuffer
End Sub

 

이 클래스에서 사용되는 기본 원칙은 문자열 버퍼로 작동하는 클래스 수준에서 변수(m_sText)가 유지되고Space$ 함수를 사용하여 공백 문자로 채움으로써 이 버퍼를 특정 크기로 설정한다는 것입니다. 추가 텍스트를 기존 텍스트에 연결해야 할 경우 버퍼의 크기가 새 텍스트를 보유할 만큼 충분한지 확인한 후 Mid$ 함수를 사용하여 텍스트를 올바른 위치에 삽입합니다. ToString 함수는 버퍼에 현재 저장된 텍스트를 반환하고 버퍼의 크기를 이 텍스트의 길이만큼 줄입니다. StringBuilder를 사용하기 위한 ASP 코드는 다음과 같이 표시됩니다.

Function WriteHTML( Data )

Dim oSB
Dim nRep

Set oSB = Server.CreateObject( "StringBuilderVB.StringBuilder" )
' 크기 및 증가 인수를 사용하여 버퍼 초기화
oSB.Init 15000, 7500

For 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>"
Next

WriteHTML = oSB.ToString()
Set oSB = Nothing

End Function

 

StringBuilder는 매번 사용할 때마다 인스턴스를 만들어야 하고 이를 포함하는 DLL을 첫 번째 클래스 인스턴스 작성 시 로드해야 하므로 이 클래스를 사용하는 것에 대한 일정한 오버헤드가 존재합니다. 또한StringBuilder 인스턴스에 대한 추가 메서드 호출을 하는 것과 관련해서도 오버헤드가 존재합니다.StringBuilder가 괄호로 묶인 '&'에 대해 수행되는 방법은 연결 수, 작성되는 문자열의 크기, StringBuilder 문자열 버퍼에 대한 초기화 매개 변수를 제대로 선택했는지 등의 여러 요소에 따라 달라집니다. 대부분의 경우 버퍼에서 필요한 공간을 예상보다 많이 잡아두는 것이 자주 공간을 늘리는 것보다 훨씬 더 나은 방법입니다.

기본 제공 방법

ASP에서는 단순히 Response.Write를 여러 번 호출하여 HTML 코드를 매우 신속하게 작성할 수 있는 방법이 포함되어 있습니다. 내부적으로 Write 함수는 매우 뛰어난 성능 특성을 제공하는 최적화된 문자열 버퍼를 사용합니다. 수정된 WriteHTML 코드는 다음과 같이 표시됩니다.

Function WriteHTML( Data )

Dim nRep

For 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>"
Next

End Function

 

이 코드가 최상의 성능과 확장성을 제공할 수 있지만 Response 스트림에 직접 기록되는 함수 안에 코드가 있고 이에 따라 호출 코드의 제어 수준이 저하되기 때문에 캡슐화가 다소 손상되었습니다. 또한 사용 가능한Response 스트림에 함수가 종속되기 때문에 이 코드를 이동(예를 들어 COM 구성 요소로 이동)하는 것이 더 어려워집니다.

테스트

위에 제공된 네 가지 방법은 문자열의 더미 배열에서 제공된 단일 테이블이 있는 간단한 ASP 페이지를 사용하여 각각에 대해 테스트되었습니다. 테스트를 수행하기 위해 100MB/초 네트워크 상에서 단일 서버(Windows 2000 Advanced Server, 이중 PIII-1000MHz, 256MB RAM)에 대해 단일 클라이언트(Windows XP Professional, PIII-850MHz, 512MB RAM)의 ACT(Application Center Test)가 사용되었습니다. ACT는 웹 사이트에 연결되는 사용자 5명의 로드를 시뮬레이트하기 위해 5개의 스레드를 사용하도록 구성되었습니다. 각 테스트는 20초의 준비 시간과 가능한 한 많은 요청이 이루어지도록 100초의 로드 시간으로 구성되었습니다.

 

WriteHTML 함수에 대한 코드 단편에 나온 것처럼 기본 테이블 루프에서 반복 횟수를 다양하게 함으로써 다양한 수의 연결 작업에 대해 테스트 실행을 반복했습니다. 각 테스트 실행은 지금까지 설명된 모든 연결 방법을 사용하여 수행했습니다.

결과

아래에 나온 일련의 차트는 각 방법이 응용 프로그램의 처리량에 미치는 영향과 ASP 페이지의 응답 시간을 보여 줍니다. 이러한 차트는 응용 프로그램이 지원할 수 있는 요청 수와 사용자가 페이지를 브라우저로 다운로드하는 데 걸리는 시간에 대한 몇 가지 정보를 제공합니다.

 

표 1   사용된 연결 방법의 약어

방법 약어설명
RESP 기본으로 제공되는 Response.Write 방법
CAT 표준 연결('&') 방법
PCAT 괄호로 묶인 연결('&') 방법
BLDR StringBuilder 방법

 

이 테스트가 일반 ASP 응용 프로그램의 작업 부하를 시뮬레이트하는 것과 관련하여 실제 상황과 다소 차이가 있지만 표 2에 나온 것처럼 420번의 반복에서도 페이지가 그렇게 크지 않다는 것을 분명하게 알 수 있습니다. 실제로는 이러한 수치의 높은 범위에 속하거나 이 테스트 범위의 제한을 초과할 수 있는 복잡한 ASP 페이지가 많이 존재합니다.

 

표 2   테스트 샘플의 페이지 크기 및 연결 수

반복 횟수 연결 수 페이지 크기(바이트)
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

그림 2   처리량 결과를 보여 주는 차트

 

그림 2에 나온 차트는 테스트된 전체 반복 범위에서 여러 Response.Write 방법(RESP)이 예상대로 최상의 처리량을 제공한다는 것을 보여 줍니다. 무엇보다도 놀라운 것은 표준 문자열 연결 방법(CAT)의 성능이 빠른 속도로 저하되고 괄호로 묶인 버전(PCAT)이 300번 이상의 반복에서 훨씬 더 나은 성능을 보인다는 것입니다. 약 220번의 반복에서 문자열 버퍼링으로 인해 StringBuilder 방법(BLDR)의 성능 향상이 이 방법의 고유한 오버헤드를 능가하기 시작하며, 따라서 이 지점 이상부터는 해당 ASP 페이지에서 StringBuilder를 사용하기 위한 추가 노력을 기울일만한 가치가 있을 것입니다.

 

그림 3   응답 시간 결과를 보여 주는 차트

 

그림 4   CAT가 생략된 응답 시간 결과를 보여 주는 차트

 

그림 3과 4의 차트는 TTFB(Time-To-First-Byte)로 측정된 밀리초 단위의 응답 시간을 보여 줍니다. 표준 문자열 연결 방법(CAT)의 응답 시간은 매우 빠른 속도로 증가하므로 그림 4에서는 이 방법을 포함하지 않고 차트를 반복함으로써 다른 방법 간의 차이점을 확인할 수 있게 했습니다. 표준 연결 방법(CAT)과 괄호로 묶인 연결 방법(PCAT)이 특정 임계값을 지난 후에 매우 빠른 속도로 증가하는 반면 여러 Response.Write방법(RESP)과 StringBuilder 방법(BLDR)은 반복이 증가함에 따라 선형 수열의 형태를 가진다는 것은 흥미로운 일입니다.

결론

이 기사에서는 여러 다른 문자열 작성 기술을 ASP 환경 내에서 적용하는 방법을 중점적으로 살펴보았지만 이러한 방법이 수동으로 XML 문서를 만드는 경우처럼 Visual Basic 코드에서 큰 문자열을 만드는 모든 시나리오에 적용된다는 것을 잊어서는 안 됩니다. 다음 지침은 각 상황에서 어떤 방법이 가장 적합한지 결정하는 데 도움이 됩니다.

  • 특히 기존 코드를 다룰 경우에는 괄호로 묶인 '&' 방법을 우선적으로 사용합니다. 이렇게 하면 코드 구조가 거의 영향을 받지 않으며 기대 이상으로 응용 프로그램의 성능이 향상된다는 것을 확인할 수 있습니다.
  • 필요한 캡슐화 수준을 손상시키지 않는 것이 가능하다면 Response.Write를 사용합니다. 이렇게 하면 불필요한 메모리 내의 문자열 조작을 방지함으로써 항상 최상의 성능을 얻을 수 있습니다.
  • 매우 크거나 연결을 많이 사용하는 문자열을 작성하려면 StringBuilder를 사용합니다.

이 기사에 나온 것과 정확하게 같은 종류의 성능 향상을 개발자가 경험하지 못할 수 있지만 필자는 지금까지 이러한 기술을 실제 ASP 웹 응용 프로그램에서 사용하여 아주 적은 노력으로 성능 및 확장성 모두에서 상당한 향상을 거둔 바 있습니다.

성능 및 스타일 향상에 도움이 되는 28가지 ASP 팁

Len Cardinal, 선임 컨설턴트, Microsoft Consulting Services
George V. Reilly, Microsoft IIS Performance Lead

Nancy Cluts가 작성한 기사에서 발췌
개발자 기술 엔지니어
Microsoft Corporation

업데이트 날짜: 2000년 4월

요약: 이 기사에서는 ASP 응용 프로그램 및 VBScript의 최적화를 위한 팁을 제공합니다.

목차

  1. 자주 사용되는 데이터는 웹 서버에 캐시하십시오.
  2. 자주 사용되는 데이터는 응용 프로그램이나 세션 개체에 캐시하십시오.
  3. 데이터 및 HTML은 웹 서버 디스크에 캐시하십시오.
  4. 비 agile 구성 요소는 응용 프로그램이나 세션 개체에 캐시하지 마십시오.
  5. 데이터베이스 연결은 응용 프로그램이나 세션 개체에 캐시하지 마십시오.
  6. 세션 개체를 올바르게 사용하십시오.
  7. 코드를 COM 개체에 캡슐화하십시오.
  8. 최신의 리소스를 얻어 신속하게 릴리스하십시오.
  9. 독립 프로세스 실행을 통해 성능과 안정성을 적절히 안배하십시오.
  10. Option Explicit를 사용하십시오.
  11. 로컬 변수를 하위 루틴 및 함수에 사용하십시오.
  12. 자주 사용되는 데이터를 스크립트 변수에 복사하십시오.
  13. 배열 크기 재정의를 피하십시오.
  14. 응답 버퍼링을 사용하십시오.
  15. 인라인 스크립트 및 Response.Write 명령문을 일괄 처리하십시오.
  16. 실행 시간이 긴 페이지를 만들 때 Response.IsClientConnected를 사용하십시오.
  17. 태그를 사용하여 개체를 초기화하십시오.
  18. TypeLib 바인딩을 ADO 및 기타 구성 요소에 사용하십시오.
  19. 브라우저의 유효성 검사 기능을 활용하십시오.
  20. 루프 형식의 문자열 연결을 피하십시오.
  21. 브라우저 및 프록시 캐싱을 사용하십시오.
  22. 가능하면 Response.Redirect가 아닌 Server.TRansfer를 사용하십시오.
  23. 디렉터리 URL에 후행 슬래시를 사용하십시오.
  24. 서버 변수 사용을 피하십시오.
  25. 최신 구성 요소로 업그레이드하십시오.
  26. 웹 서버를 조정하십시오.
  27. 성능 테스트를 수행하십시오.
  28. 관련 리소스 링크를 읽어보십시오.

소개

성능은 일종의 기능입니다. 성능은 장래 환경에 맞게 설계해야 하며, 그렇지 않으면 나중에 응용 프로그램을 다시 작성해야 하는 일이 생길 수 있습니다. 즉, 'Active Server Pages(ASP) 응용 프로그램의 성능을 최적화하려면 어떤 전략이 좋지?'와 같은 의문이 발생하게 됩니다.

이 기사에서는 ASP 응용 프로그램과 Visual Basic® Scripting Edition(VBScript)을 최적화하는데 도움이 되는 팁을 제공하며 수많은 위험과 곤란한 문제에 대해서도 논의합니다. 이 기사에 나열된 제안 사항들은 http://www.microsoft.com 및 그외 다른 사이트에서 테스트를 거쳤으며 올바르게 작동합니다. 이 기사에서는 VBScript 및/또는 JScript, ASP 응용 프로그램, ASP 세션, 기타 ASP 고유 개체(요청, 응답서버) 등을 포함하여 ASP 개발에 대한 기본 사항들을 이해하고 있다고 가정합니다.

ASP 코드 자체 이외의 다른 요소들에 의해 ASP 성능이 달라지는 경우가 간혹 있습니다. 이 기사에서 미처 다루지 못한 사항들에 대해서는 뒷부분의 성능 관련 리소스를 참조하십시오. 뒷부분에 나열된 링크에서는 ActiveX® Data Objects(ADO), Component Object Model(COM), 데이터베이스 및 Internet Information Server(IIS) 구성 등을 포함하여 ASP와 비 ASP 항목에 대해 설명합니다. 이러한 링크들은 Microsoft가 즐겨 찾는 링크들이므로 반드시 참조하시기 바랍니다.

팁 1: 자주 사용되는 데이터는 웹 서버에 캐시하십시오

일반적인 ASP 페이지는 백엔드 데이터 저장소에 있는 데이터를 검색한 후 그 결과를 HTML(Hypertext Markup Language) 형식으로 표시합니다. 데이터베이스 속도에 상관없이, 메모리에 있는 데이터를 검색하는 속도는 백엔드 데이터 저장소에 있는 데이터를 검색하는 속도보다 훨씬 빠릅니다. 또한 로컬 하드 디스크에 있는 데이터를 읽는 속도도 데이터베이스에 있는 데이터를 검색하는 속도보다 빠른 것이 보통입니다. 따라서 데이터를 웹 서버의 메모리나 디스크에 캐시하면 일반적으로 성능이 향상됩니다.

캐싱은 전형적으로 속도 향상을 위해 공간을 희생시키는 작업입니다. 캐시 기능을 올바르게 사용하면 성능이 놀랄 만큼 향상되는 것을 볼 수 있습니다. 효과적인 캐시를 위해서는 자주 사용되는 데이터이면서 다시 연산하기에는 부담이 큰 데이터만 캐시에 보관해야 합니다. 사용 빈도가 낮은 데이터로 캐시를 가득 채우면 메모리가 낭비되는 결과를 낳게 됩니다.

자주 변경되지 않는 데이터는 시간이 지나더라도 데이터베이스에 동기화할 필요가 없으므로 캐시하는 것이 좋습니다. 콤보 상자 목록, 참조 테이블, DHTML 스크랩, XML(Extensible Markup Language) 문자열, 메뉴 항목과 데이터 원본 이름(DSN), 인터넷 프로토콜(IP) 주소 및 웹 경로를 포함하는 사이트 구성 변수 등은 캐시하는 것이 좋습니다. 데이터 자체를 캐시하는 대신에 데이터에 대한 표현을 캐시할 수도 있다는 점에 주목하십시오. 전체 제품 카탈로그와 같이 ASP 페이지가 자주 변경되고 캐시하기에 부담이 큰 경우에는 요청이 발생할 때마다 해당 ASP 페이지를 다시 표시하는 것이 아니라 미리 HTML을 생성하는 방법을 고려해 보십시오.

데이터는 어디에 캐시되어야 하며 캐싱 전략에는 어떠한 것들이 있습니까? 데이터는 간혹 웹 서버의 메모리 또는 디스크에 캐시됩니다. 다음 두 가지 팁에서는 이러한 옵션들에 대해 설명합니다.

팁 2: 자주 사용되는 데이터는 응용 프로그램이나 세션 개체에 캐시하십시오

ASP 응용 프로그램세션 개체는 데이터를 메모리에 캐시하는 편리한 컨테이너를 제공합니다. 데이터는 응용 프로그램세션 개체에 모두 지정될 수 있으며 이렇게 지정된 데이터는 새로운 HTTP 호출이 발생할 때까지 메모리에 그대로 남아 있습니다. 세션 데이터는 각 사용자별로 저장되지만 응용 프로그램 데이터는 모든 사용자들 사이에서 공유됩니다.

데이터는 응용 프로그램이나 세션에 언제 로드됩니까? 데이터는 간혹 응용 프로그램이나 세션이 시작될 때 로드됩니다. 응용 프로그램이나 세션을 시작하면서 데이터를 로드하려면 적당한 코드를 Application_OnStart() 또는 Session_OnStart()에 각각 추가하십시오. 이러한 함수들은 Global.asa에 들어 있으며, 그렇지 않다면 이러한 함수들을 직접 추가할 수 있습니다. 또한 처음 데이터를 필요로 할 때 해당 데이터를 로드할 수도 있습니다. 이렇게 하려면 데이터가 있는지 검사하여 데이터가 없으면 데이터를 로드하는 일부 코드를 ASP 페이지에 추가하거나 재사용 가능한 스크립트 함수를 만드십시오. 다음은 지연 평가(Lazy Evaluation)라는 고전적인 성능 기술에 대한 예로, 필요할 때만 이를 사용하십시오.

<%
Function GetEmploymentStatusList
Dim d
d = Application(?EmploymentStatusList?)
If d = ??Then
' FetchEmploymentStatusList function (not shown)
' fetches data from DB, returns an Array
d = FetchEmploymentStatusList()
Application(?EmploymentStatusList?)= d
End If
GetEmploymentStatusList = d
End Function
%>

각각의 필요한 데이터에 대해 이와 유사한 함수를 작성할 수 있습니다.

데이터는 어떤 형식으로 저장됩니까? 모든 스크립트 변수는 변형이기 때문에, 모든 변형 유형이 저장 가능합니다. 예를 들어, 문자열, 정수 또는 배열을 저장할 수 있습니다. 간혹 ADO 레코드 집합의 내용을 이러한 변형 유형들 중 하나로 저장할 수 있습니다. ADO 레코드 집합의 데이터를 꺼내기 위해 데이터를 VBScript 변수에 한 번에 하나의 필드씩 수동으로 복사할 수 있습니다. ADO 레코드 집합 지속성 함수인 GeTRows(), GetSTRing() 또는 Save()(ADO 2.5) 중 하나를 사용하면 복사가 더 빠르고 편리해집니다. 이 기사에서는 자세한 세부 정보는 제공하지 않습니다. 다음은 GeTRows()를 사용하여 레코드 집합 데이터 배열을 반환하는 함수의 예입니다.

' Get Recordset, return as an Array
Function FetchEmploymentStatusList
Dim rs
Set rs = CreateObject(?ADODB.Recordset?)
rs.Open ?select StatusName, StatusID from EmployeeStatus?, _
?dsn=employees;uid=sa;pwd=;?
FetchEmploymentStatusList = rs.GeTRows() ?Return data as an Array
rs.Close
Set rs = Nothing
End Function

배열이 아닌, 목록에 대한 HTML을 캐시하도록 위 예제를 변경할 수도 있습니다. 다음은 그에 대한 간단한 예입니다.

' Get Recordset, return as HTML Option list
Function FetchEmploymentStatusList
Dim rs, fldName, s
Set rs = CreateObject(?ADODB.Recordset?)
rs.Open ?select StatusName, StatusID from EmployeeStatus?, _
?dsn=employees;uid=sa;pwd=;?
s = ?<select name=??EmploymentStatus??>?& vbCrLf
Set fldName = rs.Fields(?StatusName?)' ADO Field Binding
Do Until rs.EOF
' Next line violates Don't Do STRing Concats,
' but it's OK because we are building a cache
s = s & ? <option>?& fldName & ?</option>?& vbCrLf
rs.MoveNext
Loop
s = s & ?</select>?& vbCrLf
rs.Close
Set rs = Nothing ' See Release Early
FetchEmploymentStatusList = s ' Return data as a STRing
End Function

올바른 조건 하에서는 ADO 레코드 집합 자체를 응용 프로그램이나 세션 범위에 캐시할 수 있습니다. 이 때 다음 두 가지를 고려해야 합니다.

  • ADO는 빈 스레드로 표시되어야 합니다.
  • 연결이 끊긴 레코드 집합을 사용해야 합니다.

이 두 가지 요구 사항이 충족된다고 보증할 수 없으면 ADO 레코드 집합을 캐시하지 마십시오. 아래의 팁 4(비 Agile 구성 요소는 응용 프로그램이나 세션 개체에 캐시하지 마십시오)와 팁 5(데이터베이스 연결은 응용 프로그램이나 세션 개체에 캐시하지 마십시오)에서는 COM 개체를 응용 프로그램이나 세션 범위에 저장할 때 발생할 수 있는 위험에 대해 설명합니다.

데이터를 응용 프로그램이나 세션 범위에 저장하면, 프로그램을 통해 변경되거나 세션이 만료되거나 웹 응용 프로그램이 다시 시작될 때까지 데이터가 그대로 남아 있습니다. 데이터를 업데이트해야 할 경우에는 어떻게 할까요? 응용 프로그램 데이터의 업데이트를 강제로 수행하도록 지정하려면 데이터를 업데이트하는 관리자 액세스 전용 ASP 페이지로 호출할 수 있습니다. 또한 함수를 사용하여 정기적으로 데이터를 자동으로 새로 고치는 방법도 사용할 수 있습니다. 다음 예에서는 캐시된 데이터와 함께 시간 스탬프를 저장하고 일정 기간이 경과한 후 데이터를 새로 고칩니다.

<%
' error handing not shown...
Const UPDATE_INTERVAL = 300 ' Refresh interval, in seconds

' Function to return the employment status list
Function GetEmploymentStatusList
UpdateEmploymentStatus
GetEmploymentStatusList = Application(?EmploymentStatusList?)
End Function

' Periodically update the cached data
Sub UpdateEmploymentStatusList
Dim d, sTRLastUpdate
sTRLastUpdate = Application(?LastUpdate?)
If (sTRLastUpdate = ??)Or _
(UPDATE_INTERVAL < DateDiff(?s?, sTRLastUpdate, Now)) Then

' Note: two or more calls might get in here.This is okay and will simply
' result in a few unnecessary fetches (there is a workaround for this)

' FetchEmploymentStatusList function (not shown)
' fetches data from DB, returns an Array
d = FetchEmploymentStatusList()

' Update the Application object.Use Application.Lock()
' to ensure consistent data
Application.Lock
Application(?EmploymentStatusList?) = Events
Application(?LastUpdate?) = CSTR(Now)
Application.Unlock
End If
End Sub

다른 예를 보려면 World's Fastest ListBox with Application Data를 참조하십시오.

세션 또는 응용 프로그램 개체에 큰 배열을 캐싱하는 것은 좋지 않습니다. 스크립트 언어의 기능(Semantics)을 사용하려면 배열 요소에 액세스하기 전에 전체 배열을 임시로 복사해야 합니다. 예를 들어, 100,000개의 요소를 가지고 있으며 미국 우편 번호를 지방 기상청으로 매핑하는 문자열 배열을 응용 프로그램 개체에 캐시하는 경우, ASP는 그 중 하나의 문자열을 추출하기 전에 먼저 100,000개의 모든 기상청을 임시 배열에 복사합니다. 이 경우, 사용자 정의 메서드를 통해 사용자 정의 구성 요소를 작성하여 기상청을 저장하는 것이 보다 나은 방법입니다. 그렇지 않으면 딕셔너리 구성 요소들 중 하나를 사용하십시오.

주의를 상기시키는 의미에서 한 가지 더 언급하자면, 배열은 메모리 내에서 서로 인접해 있는 키 데이터 쌍에 대한 빠른 조회 및 저장 성능을 제공한다는 점을 고려해야 합니다. 딕셔너리 인덱싱 속도는 배열 인덱싱 속도보다 느립니다. 자신의 환경에 맞게 최적의 성능을 제공하는 데이터 구조를 선택해야 합니다.

팁 3: 데이터 및 HTML은 웹 서버 디스크에 캐시하십시오

간혹 데이터가 너무 많아서 메모리에 캐시할 수 없는 경우가 생길 수도 있습니다. "데이터가 너무 많다"는 의미는 상황에 따라, 즉 사용할 메모리의 양과 캐시할 항목의 수 및 그 검색 빈도에 따라 다를 수 있습니다. 메모리에 캐시할 데이터가 너무 많은 경우에는 데이터를 텍스트 또는 XML 파일 형식으로 웹 서버의 하드 디스크에 캐시하는 방법을 고려해 보십시오. 디스크 캐시 및 메모리 캐시를 결합하여 사이트에 맞는 최적의 데이터 캐싱 전략을 세울 수 있습니다.

단일 ASP 페이지의 성능을 평가할 때, 디스크에 있는 데이터를 검색하는 속도가 항상 데이터베이스에 있는 데이터를 검색하는 속도보다 빠른 것은 아니라는 점에 주의하십시오. 하지만 캐싱을 수행하면 데이터베이스와 네트워크에 걸리는 로드가 줄어듭니다. 로드가 큰 경우, 캐싱을 수행하면 전체 처리량을 크게 개선할 수 있습니다. 다중 테이블 조인 또는 복잡한 저장 프로시저 등과 같이 부담이 큰 쿼리의 결과를 캐시하거나 대규모 결과 집합을 캐시하는 경우에는 캐싱이 매우 효과적입니다. 여느 때와 마찬가지로 여러 가지 가능성을 테스트해 보십시오.

ASP 및 COM은 디스크 기반 캐싱 구성표를 작성하는 다양한 도구를 제공합니다. ADO 레코드 집합인 Save()Open() 함수는 레코드 집합을 디스크에 저장하고 디스크에 있는 레코드 집합을 로드합니다. 이러한 메서드를 사용하면 앞부분의 응용 프로그램 데이터 캐싱 팁에 있는 코드 예제를 다시 작성함으로써 Save()응용 프로그램 개체로 기록하는 코드용 파일로 대체할 수 있습니다.

다음은 파일에 사용되는 몇 가지 다른 구성 요소들입니다.

  • Scripting.FileSystemObject를 사용하면 파일을 작성하거나 읽거나 기록할 수 있습니다.
  • Internet Explorer와 함께 제공되는 Microsoft® XML 파서인 MSXML은 XML 문서의 저장 및 로딩을 지원합니다.
  • MSN에서 사용되는 샘플인 LookupTable 개체는 디스크로부터 간단한 목록을 로드하는데 유용합니다.

끝으로, 데이터 자체가 아니라 디스크 상의 데이터에 대한 표현을 캐시하는 것도 고려해 보십시오. 미리 렌더링된 HTML은 .htm 또는 .asp 파일 형식으로 디스크에 저장될 수 있으며 하이퍼링크를 통해 해당 파일들을 직접 가리킬 수 있습니다. Xbuilder 또는 Microsoft® SQL Server™ 인터넷 게시 기능 등과 같은 상용 도구를 사용하여 HTML 생성 프로세스를 자동화할 수 있으며, 그 대신 HTML 내용 일부를 .asp 파일에 포함시킬 수도 있습니다. 또한 FileSystemObject를 사용하여 디스크에 있는 HTML 파일을 읽거나 초기 렌더링 과정에서 XML을 사용하는 것 역시 가능합니다.

팁 4: 비 Agile 구성 요소는 응용 프로그램이나 세션 개체에 캐시하지 마십시오

데이터를 응용 프로그램 또는 세션 개체에 캐시하는 것은 좋은 방법이지만, COM 개체응용 프로그램 또는 세션 개체에 캐시하면 곤란한 문제들이 유발될 수 있습니다. 간혹 자주 사용되는 COM 개체를 응용 프로그램 또는 세션 개체에 캐시해야 하는 경우가 발생합니다. 불행하게도, Visual Basic 6.0 이하에서 작성된 개체를 포함한 많은 수의 COM 개체들의 경우 응용 프로그램 또는 세션 개체에 저장하려고 하면 심각한 병목 현상이 생길 수 있습니다.

특히, 비 agile 구성 요소인 경우에는 세션 또는 응용 프로그램 개체에 캐시할 때 성능 병목 현상이 발생하게 됩니다. agile 구성 요소는 FTM(Free-Threaded Marshaler)을 집계하는 ThreadingModel=Both로 표시된 구성 요소이거나 ThreadingModel=NeuTRal로 표시된 구성 요소입니다. NeuTRal 모델은 Windows® 2000 및 COM+의 새로운 모델입니다. 다음은 비 agile 구성 요소입니다.

  • FTM을 집계하지 않는 빈 스레드 구성 요소
  • 공동(Apartment) 스레드 구성 요소
  • 단일 스레드 구성 요소

중립 스레드가 아닌 한, Microsoft TRansaction Server(MTS)/COM+ 라이브러리 및 서버 패키지/응용 프로그램 등과 같은 구성된 구성 요소들은 비 agile입니다. 공동(Apartment) 스레드 구성 요소와 기타 비 agile 구성 요소들은 페이지 범위에서 가장 잘 작동합니다. 즉, 단일 ASP 페이지에서 만들어지고 제거됩니다.

IIS 4.0의 경우 ThreadingModel=Both로 표시된 구성 요소는 agile로 간주되지만, IIS 5.0에서는 그렇지 않습니다. 이러한 구성 요소들은 Both로 표시되어야 하며 FTM도 집계해야 합니다. agility 기사에서는 Active Template Library로 작성된 C++ 구성 요소들이 FTM을 집계하는 방법에 대해 설명합니다. 구성 요소가 인터페이스 포인터를 캐시하는 경우에는 이러한 포인터는 그 자체가 agile이어야 하거나 COM GIT(Global Interface Table)에 저장되어야 합니다. FTM을 집계하도록 Both 스레드 구성 요소를 다시 컴파일할 수 없는 경우에는 그 구성 요소를 ThreadingModel=NeuTRal로 표시할 수 있습니다. 또한 IIS가 agility 검사를 수행하지 않기를 원해서 비 agile 구성 요소를 응용 프로그램이나 세션 범위에 저장하려고 할 경우에는 메타베이스에서 AspTRackThreadingModelTRue로 설정할 수 있습니다. AspTRackThreadingModel을 변경하면 안됩니다.

IIS 5.0에서는 Server.CreateObject를 사용해서 만든 비 agile 구성 요소를 응용 프로그램 개체에 저장하려고 하면 오류 메시지가 나타납니다. Global.asa에서 <object runat=server scope=application ...>을 사용하면 이러한 문제를 해결할 수 있지만, 이 방법은 아래에 설명된 바와 같이 마샬링 및 순차화를 유발하므로 사용하지 않는 것이 좋습니다.

비 agile 구성 요소를 캐시하면 어떻게 될까요? 세션 개체에 캐시된 비 agile 구성 요소는 ASP 작업자 스레드에 대한 세션을 "잠급니다". ASP는 요청을 처리하는 작업자 스레드의 풀을 유지 관리합니다. 일반적으로 새 요청은 최초 사용 가능한 작업자 스레드에 의해 처리됩니다. 스레드에 대한 세션이 잠기는 경우, 해당 요청은 자신이 연결된 스레드를 사용할 수 있을 때까지 기다려야 합니다. 다음은 이를 이해하는데 도움이 될만한 유사한 사례입니다. 즉, 슈퍼마켓에 가서 몇 가지 식료품을 고른 후 3번 계산대에서 그 대금을 지불합니다. 그런 다음부터는 그 슈퍼마켓에서 산 식료품의 대금은 항상 3번 계산대에서 지불해야 합니다. 다른 계산대에서 기다리는 손님이 적거나 심지어 없는 경우에도 마찬가지입니다.

비 agile 구성 요소들을 응용 프로그램 범위에 저장하면 성능에 최악의 영향을 미치게 됩니다. ASP는 별도의 스레드를 만들어서 비 agile 응용 프로그램 범위 구성 요소들을 실행해야 합니다. 결과적으로, 모든 호출이 이 스레드에 대해 마셜링되어야 하거나 모든 호출이 순차화되어야 합니다. 마셜링은 매개 변수들이 메모리 공유 영역에 저장되어야 함을 의미합니다. 즉, 부담이 큰 컨텍스트 스위치가 별도의 스레드에 대해 만들어지고 구성 요소의 메서드가 실행되며, 그 결과가 공유 영역으로 마셜링되고 다른 부담이 큰 컨텍스트 스위치는 제어 권한을 원래의 스레드로 되돌려야 합니다. 순차화는 모드 메서드가 한 번에 하나씩 실행되어야 함을 의미합니다. 따라서 서로 다른 두 개의 ASP 작업자 스레드가 공유 구성 요소에서 메서드를 동시에 실행할 수 없으므로 동시성이 사라지게 되는데, 특히 다중 프로세서 컴퓨터에서 이러한 현상이 더 두드러집니다. 더군다나, 모든 비 agile 응용 프로그램으로 범위가 한정된 구성 요소들이 한 개의 스레드("Host STA")를 공유하므로 순차화의 영향이 더욱 커지게 됩니다.

이해가 잘 안되면 아래의 몇 가지 일반 규칙들을 살펴보십시오. Visual Basic 6.0 이전 버전을 사용해서 개체를 작성하고 있는 경우에는 그 개체를 응용 프로그램 또는 세션 개체에 캐시하면 안됩니다. 개체의 스레드 모델을 모른다면 그 개체를 캐시하면 안됩니다. 비 agile 개체는 캐시하지 말고 각각의 페이지에서 만든 후 릴리스하십시오. 개체는 마셜링 또는 순차화가 발생하지 않도록 ASP 작업자 스레드에서 직접 실행해야 합니다. IIS 상자에서 COM 개체를 실행하고 있는 경우와 그 COM 개체를 시작하거나 종료하는데 많은 시간이 걸리지 않는 경우에는 적절한 성능을 얻을 수 있습니다. 단, 단일 스레드 개체는 이와 동일한 방식으로 사용되지 않아야 한다는 점에 주의하십시오. VB는 단일 스레드 개체를 만들 수 있으므로 조심하십시오! Microsoft Excel 스프레드시트 등과 같은 단일 스레드 개체를 이와 동일한 방식으로 사용해야 하는 경우에는 많은 처리량을 기대할 수 없습니다.

ADO 레코드 집합은 ADO가 빈 스레드로 표시되어 있을 때 안전하게 캐시할 수 있습니다. ADO를 빈 스레드로 표시하려면 보통 \\Program Files\Common\System\ADO에 있는 Makfre15.bat 파일을 사용하면 됩니다.

경고 Microsoft Access를 데이터베이스로 사용하고 있는 경우에는 ADO를 빈 스레드로 표시하지 마십시오. 또한 ADO 레코드 집합에 대한 연결이 끊어져 있어야 합니다. 일반적으로, 자기 자신만의 고유한 구성을 관리하는 고객들에게 웹 응용 프로그램을 판매하는 독립 소프트웨어 공급업체[ISV]처럼 사이트에서 ADO 구성을 제어할 수 없는 경우에는 레코드 집합을 캐시하지 않는 것이 좋습니다.

또한 딕셔너리 구성 요소는 agile 개체입니다. LookupTable은 데이터 파일로부터 데이터를 로드하며 구성 정보 뿐만 아니라 콤보 상자 데이터에서도 유용하게 사용됩니다. Duwamish Books에 있는 PageCache 개체는 Caprock Dictionary와 마찬가지로 딕셔너리 기능(semantics)을 제공합니다. 이러한 개체들과 그 파생물들은 효과적인 캐싱 전략의 토대로 사용될 수 있습니다. Scripting.Dictionary 개체는 비 agile이므로 응용 프로그램이나 세션 범위에 저장될 수 없다는 점에 주의하십시오.

팁 5: 데이터베이스 연결은 응용 프로그램이나 세션 개체에 캐시하지 마십시오

보통 ADO 연결은 캐시하지 않는 것이 좋습니다. 하나의 연결 개체를 응용 프로그램 개체에 저장하여 모든 페이지에서 이를 사용하는 경우에는 모든 페이지가 이 연결을 사용하기 위해 경쟁하게 됩니다. 연결 개체가 ASP 세션 개체에 저장되어 있으면 모든 사용자들에 대해 데이터베이스 연결이 설정됩니다. 따라서 연결 풀링을 통해 얻을 수 있는 장점들이 줄어들며 웹 서버와 데이터베이스 모두에서 불필요하게 많은 로드가 발생하게 됩니다.

데이터베이스 연결을 캐시하지 말고 ADO를 사용하는 모든 ASP 페이지에서 ADO 개체를 만들거나 제거하십시오. 이렇게 하면 IIS가 자체적으로 데이터베이스 연결 풀링을 보유하게 되므로 효과적입니다. 더 정확히 말해서, IIS가 OLEDB 및 ODBC 연결 풀링을 자동으로 사용하게 되므로 각 페이지에서 연결을 효과적으로 만들거나 제거할 수 있게 됩니다.

연결된 레코드 집합은 데이터베이스 연결에 대한 참조를 저장하므로, 연결된 레코드 집합을 응용 프로그램 또는 세션 개체에 저장하면 안됩니다. 단, 연결이 끊긴 레코드 집합은 데이터 연결에 대한 참조를 저장하지 않으므로 안전하게 캐시할 수 있습니다. 레코드 집합의 연결을 끊으려면 다음과 같은 두 단계를 수행하십시오.

Set rs = Server.CreateObject(?ADODB.RecordSet?)
rs.CursorLocation = adUseClient ' step 1

' Populate the recordset with data
rs.Open sTRQuery, sTRProv

' Now disconnect the recordset from the data provider and data source
rs.ActiveConnection = Nothing ' step 2

연결 풀링에 대한 자세한 내용은 ADO 및 SQL Server 설명서에 나와 있습니다.

팁 6: 세션 개체를 올바르게 사용하십시오

지금까지 데이터를 응용 프로그램 및 세션 개체에 캐시함으로써 얻을 수 있는 장점들에 대해 얘기했으며, 이제는 세션 개체를 사용하지 말라는 제안을 하려고 합니다. 세션 개체는 아래에 설명된 바와 같이 사용량이 많은 사이트에서 사용할 때 발생하는 수많은 곤란한 문제들을 가지고 있습니다. 여기서 사용량이 많은 사이트는 일반적으로 1초 당 사용되는 페이지 수가 수 백개에 달하거나 동시에 접속하는 사용자 수가 수 천명에 달하는 사이트를 의미합니다. 수평으로 확장해야 하는 사이트, 즉 여러 대의 서버를 사용하여 로드를 분산시키거나 내결함성을 구현하는 사이트에서는 이 팁이 더욱 중요합니다. 인트라넷 사이트와 같이 소규모 사이트인 경우에는 세션 사용으로 인한 편리함이 크기 때문에 오버헤드가 생기는 단점을 보상할 수 있습니다.

재생을 위해 ASP는 웹 서버에 접속하는 모든 사용자에 대해 세션을 자동으로 만듭니다. 각각의 세션은 10KB 정도의 메모리 오버헤드를 가지며 모든 요청을 약간씩 느려지게 만드는데, 이 때 오버헤드는 종류에 상관없이 데이터가 세션에 저장될 때마다 항상 맨 위에 놓여집니다. 세션은 구성 가능한 초과 시간이 경과할 때까지 계속 사용되며 그 초과 시간은 보통 20분입니다.

세션에 관련된 가장 큰 문제는 성능이 아닌 확장성에 관련된 문제입니다. 세션은 웹 서버를 스팬하지 않습니다. 즉, 일단 세션이 한 대의 서버에서 만들어진 이후에는 그 데이터가 그대로 보존됩니다. 따라서 웹 그룹에서 세션을 사용하고 있다면, 사용자의 세션이 있는 서버로 향하도록 각 사용자의 요청을 처리하기 위한 전략을 세워야 합니다. 이러한 전략을 세우는 작업은 웹 서버에 대한 사용자 "Sticking"이라고 합니다. "Sticky Session"이라는 용어는 바로 여기에서 유래된 것입니다. 세션은 디스크에 영구적으로 저장되지 않기 때문에, "sticky 상태의" 사용자는 웹 서버의 작동이 중단되면 자신의 세션 상태를 잃게 됩니다.

Sticky Session을 구현하기 위한 전략에는 하드웨어 및 소프트웨어 솔루션이 포함됩니다. Windows 2000 Advanced Server의 네트워크 로드 균형 조정 및 Cisco사의 Local Director 등과 같은 솔루션을 사용하면 약간의 확장만으로도 Sticky Session을 구현할 수 있습니다. 이러한 솔루션들은 완벽하지가 않습니다. 이 시점에서는 자기만의 소프트웨어 솔루션은 사용하지 않는 것이 좋습니다. Microsoft에서는 ISAPI 필터와 URL 맹글링(mangling) 등을 사용했습니다.

응용 프로그램 개체는 서버를 스팬하지 않기 때문에, 웹 그룹에 걸쳐 응용 프로그램 데이터를 공유하고 업데이트해야 할 경우에는 백엔드 데이터베이스를 사용해야 합니다. 단, 읽기 전용 응용 프로그램 데이터는 웹 그룹에서 그대로 사용할 수 있습니다.

업무상 중요한 대부분의 사이트에서는 가동 시간을 늘리려는 이유가 아닌 다른 이유, 즉 장애 조치 및 서버 유지 관리를 처리하기 위해 두 대 이상의 웹 서버를 구축하려고 할 것입니다. 따라서 업무상 중요한 응용 프로그램을 설계할 때, "Sticky Session"을 구현하거나 그렇지 못하면 세션 사용을 피해야 합니다. 또한 사용자 상태를 개별 웹 서버에 저장하는 다른 상태 관리 기술들도 사용해야 합니다.

세션을 사용하고 있지 않으면 세션 기능을 반드시 해제해야 합니다. 인터넷 서비스 관리자를 통해 응용 프로그램의 세션 기능을 해제할 수 있습니다. 자세한 내용은 ISM 설명서를 참조하십시오. 세션을 사용하는 경우에는 다양한 방법으로 세션이 성능에 미치는 영향을 최소화할 수 있습니다.

도움말 화면, 방문자 영역 등과 같이 세션에 필요하지 않은 내용은 세션 기능이 해제되어 있는 별도의 ASP 응용 프로그램으로 옮길 수 있습니다. 각 페이지 단위로 해당 페이지에서 세션 개체를 필요로 하지 않는 ASP에게 힌트를 제공할 수 있습니다. 다음과 같은 지시어를 ASP 페이지의 맨 위에 넣으십시오.

<% @EnableSessionState=False %>

위와 같은 지시어를 사용해야 하는 중요한 이유는 세션으로 인해 프레임셋 관련 문제가 생길 수 있기 때문입니다. ASP를 사용하면 세션으로부터 발생하는 요청이 한 번에 하나씩만 실행되도록 만들 수 있습니다. 따라서 브라우저가 한 명의 사용자에 대해 여러 개의 페이지를 요청하더라도 한 번에 한 개의 ASP 요청만 세션을 사용하게 되므로, 세션 개체에 액세스할 때 다중 스레드 문제가 유발되지 않습니다. 결과적으로 볼 때, 프레임셋에 있는 모든 페이지는 동시에 표시되는 것이 아니라 순차적으로 한 번에 하나씩 표시됩니다. 모든 프레임이 표시될 때까지 사용자가 장시간 기다려야 할 경우도 있습니다. 참고: 특정 프레임셋 페이지가 세션에 대한 신뢰를 가지고 있지 않은 경우에는 @EnableSessionState=False 지시어를 사용하여 반드시 ASP에게 알려야 합니다.

세션 개체를 사용하는 대신, 세션 상태 관리용으로 제공되는 많은 수의 옵션들을 사용할 수도 있습니다. 상태의 크기가 4KB 미만으로 작은 경우에는 일반적으로 쿠키, QuerySTRing 변수 및 숨겨진 서식 변수를 사용하는 것이 좋습니다. 쇼핑 카트와 같이 데이터 크기가 큰 경우에는 백엔드 데이터베이스를 사용하는 것이 가장 좋습니다. 웹 서버 그룹에는 상태 관리 기술에 대한 많은 정보들이 들어 있습니다. 자세한 내용은 세션 상태 설명서를 참조하십시오.

팁 7: 코드를 COM 개체에 캡슐화하십시오

VBScript 또는 JScript가 매우 많은 경우, 간혹 그 코드를 컴파일된 COM 개체로 옮기면 성능을 개선할 수 있습니다. 컴파일된 코드의 실행 속도는 보통, 해석된 코드의 실행 속도보다 빠릅니다. 컴파일된 COM 개체는 스크립트에 사용된 "후기 바인딩"이 아니라, 보다 효과적으로 COM 개체 메서드를 불러오는 "초기 바인딩"을 통해 다른 COM 개체에 액세스할 수 있습니다.

성능 측면 뿐만 아니라, 코드를 COM 개체에 캡슐화하면 다음과 같은 장점도 얻을 수 있습니다.

  • COM 개체는 비즈니스 로직으로부터 표현 로직을 분리하는 성능이 매우 우수합니다.
  • COM 개체는 코드 재사용을 가능케 합니다.
  • 대부분의 개발자들은 VB, C++ 또는 Visual J++로 작성된 코드가 ASP로 작성된 코드보다 디버깅하기 쉽다는 점을 알고 있습니다.

COM 개체는 초기 개발 기간이 길고 다양한 프로그래밍 기술을 필요로 한다는 단점들을 가지고 있습니다. 작은 양의 ASP를 캡슐화하면 성능상 얻을 수 있는 장점보다는 단점이 많을 수 있다는 점에 주의하십시오. 일반적으로 이러한 상황은 작은 양의 ASP 코드가 COM 개체에 포함될 때 발생합니다. 이러한 경우에는 컴파일된 코드를 통해 얻을 수 있는 장점보다 COM 개체를 만들어 불러오는데 걸리는 오버헤드로 인한 단점이 더 많습니다. 어떤 방식으로 ASP 스크립트와 COM 개체 코드를 결합할 때 최적의 성능을 얻을 수 있는지를 판별하려면 여러 번의 시행 착오를 거쳐야 합니다. Microsoft는 Windows NT® 4.0/IIS 4.0에 비해 Windows 2000/IIS 5.0의 스크립트와 ADO 성능을 다양하게 개선했습니다. 따라서 ASP 코드에 비해 컴파일된 코드를 통해 얻을 수 있는 성능상의 장점들은 IIS 5.0의 도입과 함께 줄어들었습니다.

COM 개체를 ASP에 사용함으로써 발생하는 장단점에 대한 자세한 내용은 ASP Component Guidelines and Programming DisTRibuted Applications with COM and Microsoft Visual Basic 6.0을 참조하십시오. COM 구성 요소를 구축하는 경우에는 반드시 스트레스 테스트를 수행해야 합니다. 실제로 모든 ASP 응용 프로그램들은 당연히 스트레스 테스트를 거쳐야 합니다.

팁 8: 최신의 리소스를 얻어 신속하게 릴리스하십시오

일반적으로 최신의 리소스를 얻어 신속하게 릴리스하는 것이 좋습니다. 이러한 팁은 파일 핸들 및 기타 리소스 뿐만 아니라 COM 개체에도 적용됩니다.

ADO 연결 및 레코드 집합이 이러한 최적화에 가장 적합합니다. 레코드 집합을 사용하는 경우, 그 데이터를 사용하여 테이블을 채운 후 페이지 끝에 도달할 때까지 기다리지 말고 즉시 릴리스하십시오. VBScript 변수는 Nothing으로 설정하는 것이 가장 좋습니다. 레코드 집합이 범위를 벗어나지 않게 하십시오. 또한 관련된 모든 명령 또는 연결 개체를 릴리스하십시오. = Nothing으로 설정하기 전에 레코드 집합 또는 연결에 대해 Close()를 호출하는 것을 잊지 마십시오. 그러면 데이터베이스에서 리소스를 저글링하는 기간이 단축되며 데이터베이스 연결이 최대한 빠르게 연결 풀에 릴리스됩니다.

팁 9: 독립 프로세스 실행을 통해 성능과 안정성을 적절히 안배하십시오

ASP와 MTS/COM+에는 모두 성능과 안정성이 적절히 안배되도록 조정할 수 있는 구성 옵션들이 있습니다. 응용 프로그램을 만들고 구축할 때 그 장단점을 이해하고 있어야 합니다.

ASP 옵션

세 가지 방법들 중 하나로 실행되도록 ASP 응용 프로그램을 구성할 수 있습니다. IIS 5.0에서는 이러한 옵션들에 대해 설명할 목적으로 "격리 수준(isolation level)"이라는 용어를 도입했습니다. 격리 수준 값에는 낮음, 보통높음의 세 가지가 있습니다.

  • 낮음 격리. 모든 IIS 버전에서 지원되며 속도가 가장 빠릅니다. 낮음 격리는 Inetinfo.exe로 ASP를 실행하는데, 이는 기본 IIS 프로세스입니다. ASP 응용 프로그램의 작동이 중단되면 IIS의 작동도 중단됩니다. IIS 4.0의 경우, IIS를 다시 시작하려면 웹 마스터가 InetMon 등과 같은 도구들을 사용하여 사이트를 모니터하고 서버 오류가 발생한 경우 배치 파일을 실행하여 서버를 다시 시작해야 합니다. IIS 5.0에서는 오류가 발생한 서버를 자동으로 다시 시작하는 안정적인 재시작 기능을 도입했습니다.
  • 보통 격리. IIS 5.0에서 새로 도입된 이러한 보통 격리 수준은 ASP가 IIS 프로세스와는 별도로 실행되므로 독립 프로세스라고도 불립니다. 보통 격리에서 보통으로 실행되도록 구성된 모든 ASP 응용 프로그램은 하나의 프로세스 공간을 공유합니다. 따라서 한 개의 상자에서 여러 개의 독립 프로세스 ASP 응용 프로그램을 실행하는데 필요한 프로세스의 수가 줄어듭니다. 보통은 IIS 5.0의 기본 격리 수준입니다.
  • 높음 격리. IIS 4.0 및 IIS 5.0에서 지원되는 높음 격리도 역시 독립 프로세스입니다. ASP 작동이 중단되더라도 웹 서버 작동은 중단되지 않습니다. 다음 번 ASP 요청이 발생하면 ASP 응용 프로그램이 자동으로 다시 시작됩니다. 높음 격리를 사용하면, 높음으로 실행되도록 구성된 각각의 ASP 응용 프로그램은 자체 프로세스 공간에서 실행됩니다. 따라서 ASP 응용 프로그램들이 상호 보호됩니다. 하지만 각각의 ASP 응용 프로그램마다 별도의 프로세스를 필요로 한다는 단점이 있습니다. 이러한 단점 때문에, 하나의 컴퓨터에 많은 수의 응용 프로그램들을 호스트해야 할 경우에는 엄청난 오버헤드가 생길 수 있습니다.

최상의 옵션은 무엇입니까? IIS 4.0에는 독립 프로세스를 실행하기에 좋지 않은 성능상의 단점들이 있습니다. IIS 5.0에서는 ASP 응용 프로그램을 독립 프로세스로 실행하는데 드는 비용을 최소화하기 위한 많은 작업들이 수행되었습니다. 실제로 대부분의 테스트를 거친 결과, IIS 5.0의 ASP 독립 프로세스 응용 프로그램이 IIS 4.0의 종속 프로세스 응용 프로그램보다 빠르게 실행되었습니다. 그럼에도 불구하고 종속 프로세스(낮음 격리 수준)는 두 플랫폼 모두에서 여전히 최상의 성능을 제공합니다. 그러나 상대적으로 방문 횟수가 적거나 최대 처리량이 낮은 경우에는 낮음 격리 수준을 통해 얻을 수 있는 장점들이 그다지 많지 않습니다. 따라서 각각의 웹 서버에서 1초에 수 백개 또는 수 천개의 페이지를 필요로 할 때까지는 낮음 격리 수준으로 설정할 필요성을 느끼지 못할 것입니다. 또한 다양한 구성들을 사용하여 테스트를 수행하고 그 장단점을 판별해야 합니다.

참고 ASP 응용 프로그램을 독립 프로세스(보통 또는 높음 격리)로 실행하면 ASP 응용 프로그램은 Windows NT4의 경우 MTS에서 실행되고 Windows의 경우 COM+에서 실행됩니다. 즉, Windows NT4의 경우 Mtx.exe로 실행되고 Windows 2000의 경우 DllHost.exe로 실행됩니다. 작업 관리자를 살펴보면 이러한 프로세스의 실행 여부를 알 수 있습니다. 또한 IIS가 MTS 패키지 또는 COM+ 응용 프로그램을 ASP 독립 프로세스 응용 프로그램용으로 구성하는 방법도 알 수 있습니다.

COM 옵션

ASP 옵션과 완전히 유사하지는 않지만, COM 구성 요소도 세 가지 구성 옵션들을 가지고 있습니다. COM 구성 요소는 "구성되지 않은" 구성 요소이거나 라이브러리 응용 프로그램으로서 구성된 구성 요소이거나 서버 응용 프로그램으로서 구성된 구성 요소입니다. 구성되지 않은 구성 요소는 COM+에 등록되지 않은 구성 요소를 의미합니다. 이러한 구성 요소는 호출자의 프로세스 공간에서 실행되므로 "종속 프로세스"입니다. 라이브러리 응용 프로그램도 종속 프로세스이지만 보안, 트랜잭션 및 컨텍스트 지원 등을 포함하여 COM+ 서비스의 장점을 활용합니다. 서버 응용 프로그램은 자체 프로세스 공간에서 실행되도록 구성됩니다.

라이브러리 응용 프로그램에 비해 구성되지 않은 구성 요소를 사용하여 얻을 수 있는 장점이 약간 더 많다는 사실을 알 수 있습니다. 또한 서버 응용 프로그램에 비해 라이브러리 응용 프로그램을 사용하여 얻을 수 있는 성능상의 장점이 훨씬 많다는 사실도 알 수 있습니다. 그 이유는 라이브러리 응용 프로그램이 ASP와 동일한 프로세스에서 실행되는 반면에 서버 응용 프로그램은 자체 프로세스에서 실행되기 때문입니다. 프로세스간 호출은 종속 프로세스 호출보다 더 부담이 큽니다. 또한 레코드 집합 등과 같은 데이터가 프로세스 사이에서 전달될 때에는 모든 데이터가 두 프로세스 사이에서 복사되어야 합니다.

주의! COM 서버 응용 프로그램을 사용할 때, ASP와 COM 사이에서 개체를 전달하는 경우에는 개체가 "값에 따른 마셜링" 또는 MBV를 구현해야 합니다. MBV를 구현하는 개체들은 하나의 프로세스에서 다른 프로세스로 자동 복사됩니다. 이러한 방식은 개체가 작성자의 프로세스에 그대로 남아 있으며 다른 프로세스가 개체를 사용하기 위해 작성 프로세스에 반복적으로 호출되는 방식보다 낫습니다. 연결이 끊긴 ADO 레코드 집합은 값에 따라 마셜링되지만, 연결된 레코드 집합은 그렇지 않습니다. Scripting.Dictionary는 MBV를 구현하지 않으며 프로세스 사이에서 전달되지 않습니다. 끝으로, VB 프로그래머는 MBV가 ByVal 매개 변수의 전달을 통해 구현되는 것이 아니라, 원래의 구성 요소 작성자에 의해 구현된다는 점에 주의해야 합니다.

수행할 사항

성능과 안정성이 적절히 조정된 구성을 설정하려면 다음과 같은 권장 사항들을 수행해야 합니다.

  • IIS 4.0에서는 ASP의 낮음 격리 수준을 사용하고 MTS 서버 패키지를 사용하십시오.
  • IIS 5.0에서는 ASP의 보통 격리 수준을 사용하고 COM+ 라이브러리 응용 프로그램을 사용하십시오.

이 권장 사항들은 매우 일반적인 지침들입니다. 기업 호스팅에서는 일반적으로 ASP가 보통 또는 높음 격리 수준에서 실행되는 반면에 단일 용도의 웹 서버는 낮음 격리 수준에서 실행될 수 있습니다. 그 장단점을 평가하여 어떤 구성이 자신의 환경에 맞는지를 스스로 판별하십시오.

팁 10: Option Explicit를 사용하십시오

.asp 파일에 있는 Option Explicit를 사용하십시오. .asp 파일의 맨 위에 있는 이 지시어는 사용할 변수를 모두 선언하도록 개발자에게 강요합니다. 응용 프로그램을 디버깅할 때 이 지시어를 사용하면 MyXMLSTRing= 대신에 MyXLMSTRing=가 발생하는 경우처럼 변수 이름의 입력 오타가 생기거나 원치 않는 변수가 만들어질 가능성을 봉쇄하기 때문에, 대부분의 프로그래머들은 이 지시어가 매우 유용하다는 것을 알고 있습니다.

보다 중요한 점은 선언된 변수가 선언되지 않은 변수보다 빠르게 실행된다는 것입니다. 스크립팅 실행 시간은 선언되지 않은 변수가 사용될 때마다 자동으로 변수 이름별로 그 선언되지 않은 변수를 참조합니다. 반면, 선언된 변수는 컴파일 시간 또는 실행 시간에서 서수를 할당받습니다. 결과적으로 볼 때, 선언된 변수는 이 서수에서 참조합니다. Option Explicit를 사용하면 변수를 선언하도록 강제 지정하므로, 모든 변수가 선언되어 빠른 액세스를 가능하게 합니다.

팁 11: 로컬 변수를 하위 루틴 및 함수에 사용하십시오

로컬 변수는 하위 루틴 및 함수 내에서 선언된 변수입니다. 함수 또는 하위 루틴 내에서 선언된 로컬 변수는 글로벌 변수보다 빠르게 액세스됩니다. 또한 로컬 변수를 사용하면 코드가 보다 명확해지므로, 가능하면 항상 로컬 변수를 사용하십시오.

팁 12: 자주 사용되는 데이터를 스크립트 변수에 복사하십시오

ASP에 있는 COM 개체에 액세스할 때는 자주 사용되는 데이터를 스크립트 변수에 복사해야 합니다. 이렇게 복사하면 스크립트 변수에 액세스하는 것에 비해 상대적으로 부담이 큰 COM 메서드 호출의 수가 줄어듭니다. 컬렉션딕셔너리 개체에 액세스할 때에도 이 기술을 사용하면 부담이 큰 조회의 수를 줄일 수 있습니다.

일반적으로 두 번 이상 개체 데이터에 액세스할 경우에는 해당 데이터를 스크립트 변수에 복사하십시오. 이러한 최적화의 주요 대상은 Request 변수(Form 및 QuerySTRing 변수)입니다. 예를 들어, QuerySTRing 변수로 호출되는 UserID가 반복적으로 분배되는 사이트에서 이 UserID가 특정 페이지에 12회 참조된다고 가정해 보십시오. Request(?UserID?)를 12회 호출하지 말고 ASP 페이지의 맨 위에 있는 변수에 UserID를 할당하십시오. 그러면 페이지 전체에 걸쳐 그 변수가 사용됩니다. 따라서 11회의 COM 메서드 호출이 줄어듭니다.

실제로 COM 속성 또는 메서드에 대한 액세스는 매우 부담이 큰 작업입니다. 다음은 자주 사용되는 구문 코드를 보여주는 예입니다.

Foo.bar.blah.baz = Foo.bar.blah.qaz(1)
If Foo.bar.blah.zaq = Foo.bar.blah.abc Then ' ...

이 코드는 다음과 같이 실행됩니다.

  1. Foo 변수가 글로벌 개체로 확인됩니다.
  2. bar 변수가 Foo의 구성원으로 확인됩니다. 결과적으로 COM 메서드 호출이 발생합니다.
  3. blah 변수가 Foo.bar의 구성원으로 확인됩니다. 결과적으로 COM 메서드 호출이 다시 발생합니다.
  4. qaz 변수가 foo.bar.blah의 구성원으로 확인됩니다. 결과적으로 COM 메서드 호출이 다시 발생합니다.
  5. Foo.bar.blah.quaz(1)를 불러옵니다. COM 메서드 호출이 다시 발생합니다. 여기까지 이해가 되었습니까?
  6. 1-3 단계를 다시 수행하여 baz를 확인합니다. 시스템은 qaz 호출이 개체 모델을 변경했는지 여부를 알지 못하므로, 1-3 단계를 다시 수행하여 baz를 확인해야 합니다.
  7. bazFoo.bar.blah의 구성원으로 확인합니다. 속성을 설정합니다.
  8. 1-3 단계를 다시 수행하여 zaq를 확인합니다.
  9. 1-3 단계를 다시 수행하여 abc를 확인합니다.

이처럼, 이 코드는 매우 비효율적이며 작성에 많은 시간이 걸립니다. VBScript에서 이 코드를 가장 빠르게 작성하는 방법은 다음과 같습니다.

Set myobj = Foo.bar.blah ' do the resolution of blah ONCE
Myobj.baz = myobj.qaz(1)
If Myobj.zaq = Myobj.abc Then '...

VBScript 5.0 이상을 사용하고 있는 경우에는 With 명령문을 사용하여 이 코드를 작성할 수 있습니다.

With Foo.bar.blah
.baz = .qaz(1)
If .zaq = .abc Then '...
...
End With

이 팁은 VB 프로그래밍에도 적용된다는 점을 기억하십시오.

팁 13: 배열 크기 재정의를 피하십시오

배열의 크기 재정의(Redim)는 가능한 한 피하십시오. 실제 메모리 크기에 의해 성능이 제한되는 컴퓨터의 경우에는 최악의 경우에 대비하여 초기 배열 크기를 설정하거나, 그 크기를 최적으로 설정하고 필요할 때마다 배열 크기를 재정의하십시오. 단, 필요하지 않은 경우에도 수 MB나 되는 메모리를 할당해야 한다는 것은 아닙니다.

다음 코드는 DimRedim 사용 예입니다.

<%
Dim MyArray()
Redim MyArray(2)
MyArray(0) = ?hello?
MyArray(1) = ?good-bye?
MyArray(2) = ?farewell?
...
' some other code where you end up needing more space happens, then ...
Redim Preserve MyArray(5)
MyArray(3) = ?more stuff?
MyArray(4) = ?even more stuff?
MyArray(5) = ?yet more stuff?
%>

배열의 크기 재정의(Redim)를 수행하여 그 크기를 늘리는 것보다는 초기에 올바른 크기까지 배열의 크기 정의(Dim)를 수행(위 코드의 경우 5)하는 것이 좋습니다. 모든 요소들을 끝까지 사용하지 않으면 약간의 메모리 낭비가 있게 되지만 속도가 빨라지는 이점이 있습니다.

팁 14: 응답 버퍼링을 사용하십시오

"응답 버퍼링" 기능을 설정함으로써 전체 출력 페이지 만큼을 버퍼링할 수 있습니다. 이렇게 하면 브라우저에 기록되는 양이 최소화되어 전체 성능이 향상됩니다. 기록할 때마다 IIS 및 회선을 통해 보내지는 데이터 크기로 인한 오버헤드가 아주 크기 때문에, 기록 횟수가 줄어들수록 성능이 향상됩니다. TCP/IP는 느리게 시작되며 Nagling 알고리즘을 통해 네트워크 혼잡을 최소화하므로, 작은 블록을 여러 개 보낼 때보다 큰 데이터 블록을 한 개 보낼 때 더욱 효율적으로 작동합니다.

응답 버퍼링 기능을 설정하는 방법은 두 가지가 있습니다. 첫번째 방법은 인터넷 서비스 관리자를 사용하여 전체 응용 프로그램의 응답 버퍼링 기능을 설정하는 것입니다. 이는 권장되는 방법이며 기본적으로 IIS 4.0 및 IIS 5.0에서 새로 사용되는 ASP 응용 프로그램의 응답 버퍼링 기능을 설정합니다. 두번째 방법은 다음과 같은 코드 행을 ASP 페이지의 맨 위쪽에 넣음으로써 응답 버퍼링 기능을 페이지 단위로 설정하는 것입니다.

<% Response.Buffer = TRue %>

이 코드 행은 응답 데이터가 브라우저에 기록되기 이전에 미리 실행되어야 합니다. 즉, HTML이 ASP 스크립트에 나타나기 이전과 Response.Cookies 컬렉션을 사용하여 쿠키가 설정되기 이전에 미리 실행되어야 합니다. 일반적으로 전체 응용 프로그램에 대해 응답 버퍼링 기능을 설정하는 것이 좋습니다. 이렇게 하면 각 페이지마다 이 코드 행을 사용하지 않아도 됩니다.

Response.Flush

응답 버퍼링에 관한 일반적인 불만 사항들 중 하나는 전체 페이지가 생성된 후에야 비로소 그 내용을 볼 수 있기 때문에 전체 응답 시간이 향상되었음에도 불구하고 사용자들이 ASP 페이지의 응답이 다소 느리다고 느낀다는 점입니다. 페이지를 장시간 실행하는 경우에는 Response.Buffer = False를 설정함으로써 응답 버퍼링 기능을 해제할 수 있습니다. 그러나 Response.Flush 메서드를 활용하는 것이 더 낫습니다. 이 메서드를 사용하면 ASP가 브라우저에 표시한 모든 HTML이 플러시됩니다. 예를 들어, 1,000개의 행으로 구성된 테이블에서 100개의 행을 표시한 후 ASP는 Response.Flush를 호출하여 표시된 결과를 브라우저에 강제 지정할 수 있습니다. 이렇게 하면 나머지 행이 표시되기 전에 사용자는 처음 표시된 100개의 행을 볼 수 있습니다. 이 기술을 사용하면 데이터를 브라우저에 점차적으로 표시함과 동시에 응답 버퍼링 기능도 사용할 수 있는 최상의 환경을 만들 수 있습니다.

1,000개의 행으로 구성된 테이블을 사용하는 위의 예에서 종료 </table> 태그가 나타날 때까지는 대부분의 브라우저에서 테이블 표시를 시작할 수 없다는 점에 주의하십시오. 대상 브라우저가 지원되는지 확인하십시오. 이 문제를 해결하려면 행 수가 적은 여러 개의 테이블로 나누고 각각의 작은 테이블 다음에서 Response.Flush를 호출하십시오. 최신 버전의 Internet Explorer에서는 전체 내용을 다운로드하기 전에 테이블을 표시하며, 테이블 열 너비가 지정되어 있으면 Internet Explorer가 모든 셀 내용의 너비를 측정함으로써 열 너비를 계산하지 않기 때문에 훨씬 빠르게 표시됩니다.

응답 버퍼링에 관한 또 다른 일반적인 불만 사항은 큰 페이지를 생성할 때 매우 많은 서버 메모리가 사용될 수 있다는 점입니다. 큰 페이지 생성을 조정하는 것이 아니라, Response.Flush를 적절히 사용하면 이 문제 역시 해결할 수 있습니다.

팁 15: 인라인 스크립트 및 Response.Write 명령문을 일괄 처리하십시오

VBScript 구문 <% = 표현식 %>을 사용하면 "표현식" 값이 ASP 출력 스트림에 기록됩니다. 응답 버퍼링 기능이 해제되어 있는 경우, 이러한 각각의 명령문을 사용하면 데이터가 네트워크를 통해 여러 개의 작은 패킷 형태로 브라우저에 기록됩니다. 이 기록은 아주 느리게 진행됩니다. 또한 작은 양의 스크립트와 HTML을 보내면 스크립트 엔진과 HTML간 전환이 발생하여 결과적으로 성능이 저하됩니다. 이 경우에는 여러 개의 인접한 인라인 표현식들을 한 번의 Response.Write 호출로 바꾸십시오. 예를 들어, 아래의 예에서는 응답 스트림 쓰기 동작이 각각의 행에 있는 각 필드에 대해 한 번 발생하며 VBScript와 HTML간 전환이 각각의 행에 대해 여러 번 발생합니다.

<table>
<% For Each fld in rs.Fields %>
<th><% = fld.Name %></th>
<%
Next
While Not rs.EOF
%>
<TR>
<% For Each fld in rs.Fields %>
<TD><% = fld.Value %></TD>
<% Next
</TR>
<% rs.MoveNext
Wend %>
</table>

보다 효율적인 아래의 코드에서는 응답 스트림 쓰기 동작이 각각의 행에 대해 한 번 발생합니다. 모든 코드는 한 개의 VBScript 블록 안에 포함됩니다.

<table>
<%
For each fld in rs.Fields
Response.Write (?<th>?& fld.Name & ?</th>?& vbCrLf)
Next
While Not rs.EOF
Response.Write (?<TR>?)
For Each fld in rs.Fields %>
Response.Write(?<TD>?& fld.Value & ?</TD>?& vbCrLf)
Next
Response.Write ?</TR>?
Wend
%>
</table>

이 팁은 응답 버퍼링 기능이 해제되어 있을 때 더욱 효율적입니다. 응답 버퍼링 기능을 설정한 후 Response.Write를 일괄 처리하여 성능이 향상되는지를 확인해 보는 것이 가장 좋습니다.

위의 예에서 테이블 본문을 구성하는 중첩된 루프(While Not rs.EOF...)는 제대로 구성된 GetSTRing 호출로 바꿀 수 있습니다.

팁 16: 실행 시간이 긴 페이지를 만들 때 Response.IsClientConnected를 사용하십시오

참을성이 없는 사용자라면 자신의 요청을 실행하기도 전에 미리 ASP 페이지를 포기해 버릴 수도 있습니다. 이러한 사용자들이 새로 고침을 누르거나 서버의 다른 페이지로 이동하면 새 요청이 ASP 요청 대기열의 맨 끝부분에 넣어지고 연결이 끊긴 요청이 대기열의 중간 부분에 넣어집니다. 이러한 상황은 서버에 과도한 로드가 걸려 있을 때 간혹 발생하는데, 이 경우 요청 대기열이 길어져서 더 많은 응답 시간이 소요되므로 문제가 더욱 악화됩니다. 사용자의 연결이 끊어지면 ASP 페이지를 실행할 지점이 없어집니다. 특히, 속도가 느리고 그 내용이 많은 ASP 페이지인 경우에는 더욱 그렇습니다. Response.IsClientConnected 속성을 사용하면 이러한 상황이 발생했는지를 검사할 수 있습니다. False가 반환되면 Response.End를 호출하여 나머지 페이지를 포기해야 합니다. 실제로 IIS 5.0에서는 이러한 절차를 코드화했습니다. 즉, 새 요청을 실행하려고 할 때마다 ASP는 해당 요청이 대기열에 있었던 기간을 검사합니다. 그 기간이 3초를 초과하는 경우, ASP는 클라이언트가 아직도 연결되어 있는지를 검사하여 클라이언트 연결이 끊어져 있으면 그 즉시 해당 요청을 종료합니다. 메타베이스에 있는 AspQueueConnectionTestTime 설정을 사용하면 이러한 시간 초과 값(3초)을 변경할 수 있습니다.

매우 긴 실행 시간을 필요로 하는 페이지가 있는 경우에는 간혹 Response.IsClientConnected를 검사해야 합니다. 응답 버퍼링 기능이 설정되어 있는 경우에는 가끔 Response.Flush를 실행하여 무슨 일이 진행되고 있는지를 사용자에게 알리는 것이 좋습니다.

참고 IIS 4.0에서는 Response.Write를 먼저 실행하지 않으면 Response.IsClientConnected가 제대로 작동하지 않습니다. 또한 버퍼링 기능이 설정되어 있으면 Response.Flush도 실행해야 합니다. IIS 5.0에서는 이들을 실행하지 않더라도 Response.IsClientConnected가 제대로 작동합니다. Response.IsClientConnected를 실행하는데 어느 정도의 대가가 따를 수도 있으므로, Response.IsClientConnected는 500밀리초 이상이 소요되는 작업을 수행하기 전에만 사용해야 합니다. 1초에 수 십개의 페이지를 계속 처리해야 한다는 점에서 보면 500밀리초는 매우 긴 시간입니다. 일반적으로 20개 또는 50개의 테이블 행에 도달할 때마다 테이블 행을 표시하는 경우처럼, 간격이 짧은 루프가 반복될 때 이 속성을 호출하면 안됩니다.

팁 17: <OBJECT> 태그를 사용하여 개체를 초기화하십시오

모든 코드 경로, 특히 서버 또는 응용 프로그램 범위 개체에 사용되지 않는 개체를 참조해야 할 경우에는 Server.CreateObject 메서드를 사용하지 말고 Global.asa에서 <object runat=server id=objname> 태그를 사용하여 선언하십시오. Server.CreateObject는 즉시 개체를 만들기 때문에, 나중에 그 개체를 사용하지 않을 경우에는 리소스를 낭비하는 결과를 초래합니다. <object id=objname> 태그는 개체 이름(objname)을 선언하지만, 그 개체 이름은 해당 메서드나 속성들 중 하나가 처음으로 사용된 후 비로소 만들어집니다.

이것은 지연 평가(Lazy Evaluation)의 다른 예입니다.

팁 18: TypeLib 선언을 ADO 및 그 밖의 다른 구성 요소에 사용하십시오

ADO를 사용할 때, 개발자가 ADO의 다양한 상수들에 액세스할 목적으로 adovbs.txt를 포함시키는 경우가 간혹 있습니다. 이 파일은 상수가 사용될 모든 페이지에 포함되어야 합니다. 이 상수 파일의 크기는 매우 크기 때문에, 모든 ASP 페이지의 컴파일 시간 및 스크립트 크기에 엄청난 오버헤드가 추가됩니다.

IIS 5.0에는 구성 요소의 유형 라이브러리에 대한 바인드 기능이 새로 추가되었습니다. 이 기능을 사용하면 일단 유형 라이브러리를 참조한 이후에 모든 ASP 페이지에서 이를 다시 사용할 수 있습니다. 페이지마다 상수 파일을 컴파일할 필요는 없으므로, 구성 요소 개발자는 ASP에서 사용할 VBScript #include 파일을 만들 필요가 없습니다.

ADO TypeLib에 액세스하려면 다음 명령문들 중 하나를 Global.asa에 넣으십시오.

<!-- METADATA NAME=?Microsoft ActiveX Data Objects 2.5 Library?
TYPE=?TypeLib?UUID=?{00000205-0000-0010-8000-00AA006D2EA4}? -->

또는

<!-- METADATA TYPE=?TypeLib?
FILE=?C:\Program Files\Common Files\system\ado\msado15.dll? -->

팁 19: 브라우저의 유효성 검사 기능을 활용하십시오

최근에 개발되는 브라우저에서는 XML, DHTML, Java 애플릿 및 원격 데이터 서비스 등과 같은 기능들에 대한 고급 지원 기능을 제공합니다. 가능하면 항상 이러한 기능들을 사용하십시오. 이러한 모든 기술들은 데이터 캐싱 뿐만 아니라 클라이언트측 유효성 검사를 수행하므로 웹 서버에 대한 왕복 이동 시간을 줄여줍니다. 스마트 브라우저를 실행하고 있는 경우, 그 브라우저에서는 약간의 유효성 검사를 수행할 수 있습니다. 예를 들어, POST를 실행하기 전에 신용 카드에 유효한 검사값이 들어 있는지를 검사합니다. 다시 말해서, 가능하면 항상 이러한 기능들을 사용하십시오. 클라이언트 대 서버간 왕복 이동 시간이 줄어들면 서버가 액세스하는 백엔드 리소스 뿐만 아니라 웹 서버에 걸리는 스트레스와 네트워크 트래픽도 줄어듭니다. 단, 브라우저에서 수신하는 초기 페이지의 크기는 더 커집니다. 또한 사용자가 새 페이지를 그다지 자주 페치할 필요가 없으므로 성능이 훨씬 나아집니다. 그렇지만 서버측 유효성 검사를 수행하지 않아도 되는 것은 아닙니다. 서버측 유효성 검사는 항상 수행해야 합니다. 서버측 유효성 검사를 수행하면 브라우저가 클라이언트측 유효성 검사 루틴을 실행하지 않더라도 클라이언트로부터 해킹과 같은 나쁜 데이터가 들어오는 것이 방지됩니다.

"모든 브라우저에서 실행되는" HTML을 작성할 때 보통 이러한 기능이 사용됩니다. 이는 간혹 성능상의 장점을 제공하는 자주 사용되는 브라우저 기능을 이용하려는 개발자의 의욕을 꺾는 결과를 초래합니다. 따라서 "사용 가능한" 브라우저 종류를 고려해야 하는 고성능 사이트에서 유용한 전략은 가장 자주 사용되는 브라우저에 맞게 페이지를 최적화하는 것입니다. 브라우저 기능 구성 요소를 사용하는 ASP에서는 브라우저 기능들을 간편하게 검색할 수 있습니다. Microsoft FrontPage와 같은 도구를 사용하면 원하는 HTML 버전과 브라우저에서 작동하는 코드를 설계하는데 도움이 됩니다. 자세한 내용은 When is Better Worse? Weighing the Technology TRade-Offs를 참조하십시오.

팁 20: 루프 형식의 문자열 연결을 피하십시오

대부분의 개발자들은 다음과 같은 루프 형식의 문자열을 사용합니다.

s = ?<table>?& vbCrLf
For Each fld in rs.Fields
s = s & ? <th>?& fld.Name & ?</th> ?
Next

While Not rs.EOF
s = s & vbCrLf & ? <TR>?
For Each fld in rs.Fields
s = s & ? <TD>?& fld.Value & ?</TD> ?
Next
s = s & ? </TR>?
rs.MoveNext
Wend

s = s & vbCrLf & ?</table>?& vbCrLf
Response.Write s

이러한 접근 방법에는 몇 가지 문제가 있습니다. 첫번째 문제는 반복적인 문자열 연결로 인해 제곱 배의 시간이 소요된다는 점입니다. 공식적인 수치는 아니지만, 이러한 루프를 실행하는데 소요되는 시간은 레코드 수와 필드 수를 곱한 값의 제곱에 비례합니다. 이는 아래의 간단한 예를 살펴보면 더욱 분명해집니다.

s = ??
For i = Asc(?A?) to Asc(?Z?)
s = s & Chr(i)
Next

첫번째 반복에서 한 개의 문자로 구성된 문자열(?A?)이 얻어집니다. 두번째 반복에서 VBScript는 문자열을 다시 할당하고 두 개의 문자(?AB?)를 s에 복사해야 합니다. 세번째 반복에서 VBScript는 다시 s를 할당하고 세 개의 문자를 s에 복사해야 합니다. N번째(26번째) 반복에서 VBScript는 s를 다시 할당하고 N개의 문자를 s에 복사해야 합니다. 따라서 그 복사 합계는 1+2+3+...+N, 즉 N*(N+1)/2입니다.

위의 레코드 집합 예에서 레코드 수가 100개이고 필드 수가 5개인 경우에는 100*5 = 500회의 내부 루프가 실행되어야 하며, 모든 복사 및 재할당에 소요되는 시간은 500*500 = 250,000입니다. 이러한 수치는 보통 크기의 레코드 집합인 경우에는 아주 큰 값입니다.

이 예에서 문자열 연결을 Response.Write()로 바꾸거나 인라인 스크립트(<% = fld.Value %>)로 바꾸면 코드 성능이 향상될 수 있습니다. 응답 버퍼링 기능이 설정되어 있으면 Response.Write가 데이터를 응답 버퍼의 끝에 추가하므로 그 속도가 더욱 빨라집니다. 또한 재할당 동작이 발생하지 않으므로 아주 효율적입니다.

ADO 레코드 집합을 HTML 테이블로 변환해야 하는 특별한 경우에는 GeTRows 또는 GetSTRing을 사용해 보십시오.

문자열을 JScript에 연결하는 경우에는 반드시 += operator; that is, use s += ?some sTRing?, not s = s + ?some sTRing?을 사용하십시오.

팁 21: 브라우저 및 프록시 캐싱을 사용하십시오

기본적으로 ASP는 브라우저 및 프록시 캐싱 기능을 사용하지 않습니다. 그 이유는 ASP 페이지의 경우 잠재적으로 시간이 중요시되는 정보를 갖는 동적 페이지의 속성을 가지고 있기 때문입니다. 그러나 볼 때마다 새로 고칠 필요가 없는 페이지에서는 브라우저 및 프록시 캐싱 기능을 사용해야 합니다. 이렇게 하면 브라우저 및 프록시에서 일정 기간 동안 "캐시된" 페이지 복사본을 사용할 수 있으며, 그 기간은 사용자가 조절할 수 있습니다. 또한 서버에 걸리는 로드가 크게 줄어들며 성능이 훨씬 나아집니다.

어떤 종류의 동적 페이지를 캐시할 수 있습니까? 다음은 캐시 가능한 페이지의 예입니다.

  • 날씨가 5분마다 업데이트되는 날씨 페이지
  • 신문 기사나 보도 자료를 나열하고 하루에 두 번 업데이트되는 홈 페이지
  • 뮤추얼 펀드 실적을 나열하고 기초 통계 자료가 서너 시간마다 업데이트되는 페이지

브라우저 또는 프록시 캐싱 기능을 사용하면 웹 서버에 기록되는 방문 횟수가 줄어든다는 점에 주의하십시오. 모든 페이지 화면이나 게시 알림 횟수를 정확하게 측정하기 위해 브라우저 및 프록시 캐싱 기능을 해제해야 할 수도 있습니다.

브라우저 캐싱 기능은 웹 서버로부터 브라우저로 보내지는 HTTP의 "Expires" 헤더에서 제어됩니다. ASP에서는 두 가지 간단한 메커니즘을 통해 이 헤더를 전송합니다. 첫번째 메커니즘은 향후 일정 시간(분 단위)이 경과한 후 페이지를 만료하도록 Response.Expires 속성을 설정하는 것입니다. 다음은 10분이 경과한 후 내용을 만료하도록 브라우저에게 지시하는 예입니다.

<% Response.Expires = 10 %>

Response.Expires를 음수나 0으로 설정하면 캐싱 기능이 사용되지 않습니다. 서버 시계와 브라우저 사이의 불일치 문제를 해결하려면 -1000 등과 같이 하루보다 약간 적은 시간을 의미하는 음수를 사용해야 합니다. 두번째 메커니즘은 Response.ExpiresAbsolute를 사용하여 해당 내용을 만료할 시간을 설정하는 것입니다.

<% Response.ExpiresAbsolute = #May 31,2001 13:30:15# %>

Response 개체를 사용하여 만료 날짜를 설정하는 대신에 <META> 태그를 HTML에 사용할 수도 있습니다. 이 태그는 일반적으로 HTML 파일의 <HEAD> 섹션에 놓입니다. 아래의 지시어는 일부 브라우저에서는 인식되지만 프록시에서는 인식되지 않습니다.

<META HTTP-EQUIV=?Expires?VALUE=?May 31,2001 13:30:15?>

끝으로, Response.CacheConTRol 속성을 사용하여 HTTP 프록시에서 해당 내용을 캐시할 수 있는지 여부를 나타낼 수 있습니다. 이 속성을 "Public"으로 설정하면 프록시는 해당 내용을 캐시합니다.

<% Response.CacheConTRol = ?Public? %>

기본적으로 이 속성은 "Private"로 설정됩니다. 사용자 고유의 데이터를 보여주는 페이지인 경우에는 프록시가 다른 사용자의 페이지를 제공할 수도 있으므로 프록시 캐싱 기능을 사용하면 안됩니다.

팁 22: 가능하면 Response.Redirect가 아닌 Server.TRansfer를 사용하십시오

Response.Redirect는 다른 페이지를 요청하도록 브라우저에게 지시합니다. 이 함수는 사용자를 로그온이나 오류 페이지로 리디렉션하는데 간혹 사용됩니다. 리디렉션은 새 페이지 요청을 강제로 수행하기 때문에, 결과적으로 볼 때 브라우저가 웹 서버에 두 번 왕복 이동해야 하며 웹 서버가 추가 요청을 처리해야 합니다. IIS 5.0에서는 동일한 서버에 있는 다른 ASP 페이지에게 실행을 전송하는 Server.TRansfer 함수를 새로 도입했습니다. 이 함수를 사용하면 브라우저 대 웹 서버 왕복 이동이 추가로 발생하지 않기 때문에, 결과적으로 볼 때 사용자의 응답 시간이 빨라지며 전체 시스템 성능도 향상됩니다. 자세한 내용은 Server.TRansferServer.Execute에 대해 설명하는 New Directions in Redirection을 참조하십시오.

또한 IIS 5.0 및 ASP 3.0의 새 기능에 대한 자세한 목록은 Leveraging ASP in IIS 5.0을 참조하십시오.

팁 23: 디렉터리 URL에 후행 슬래시를 사용하십시오

여기에 관련된 팁은 디렉터리를 나타내는 후행 슬래시(/)를 URL에 사용해야 한다는 것입니다. 후행 슬래시가 생략된 경우, 브라우저는 서버에게 디렉터리를 요청합니다. 그런 다음 브라우저가 슬래시를 URL에 추가하여 두번째 요청을 보내면 서버가 해당 디렉터리의 기본 문서로 응답하거나, 기본 문서가 없어서 디렉터리 찾아보기가 사용된 경우 디렉터리 목록으로 응답합니다. 슬래시를 추가하면 불필요한 첫번째 왕복 이동 동작이 발생하지 않습니다. 사용자가 쉽게 읽을 수 있도록, 표시되는 이름에서 후행 슬래시를 생략할 수도 있습니다.

예를 들면, 다음과 같습니다.

<a href=?http://msdn.microsoft.com/workshop/? title=?MSDN Web
Workshop?>http://msdn.microsoft.com/workshop</a>

이 팁은 웹 사이트의 홈 페이지를 가리키는 URL에도 적용됩니다.<a href=?http://msdn.microsoft.com?>이 아닌 <a href=?http://msdn.microsoft.com/?>을 사용해 보십시오.

팁 24: 서버 변수 사용을 피하십시오

서버 변수에 액세스하면 웹 사이트가 서버에게 특수한 요청을 보내어 요청한 변수 뿐만 아니라 모든 서버 변수들을 모으게 됩니다. 이는 불필요한 파일들을 넣어둔 창고에 있는 폴더에서 특정 항목을 찾는 경우와 비슷한데, 여기서 한 개의 필요한 항목을 찾으려면 원하는 항목에 액세스하기 전에 먼저 창고에 들어가서 해당 폴더를 찾아야 합니다. 이러한 상황은 서버 변수를 요청할 때 발생하는 상황과 동일합니다. 방문 횟수(performance hit)는 맨 처음 서버 변수를 요청할 때 추가됩니다. 나중에 다른 서버 변수를 얻기 위해 보내지는 요청은 방문 횟수(performance hit)에 추가되지 않습니다.

Request("Data")와 같이 정식 Request 개체가 아닌 개체에 액세스하면 안됩니다. Request.Cookies, Request.Form, Request.QuerySTRing 또는 Request.ClientCertificate에 들어 있지 않은 항목에 대해서는 Request.ServerVariables에 대한 암시적 호출이 발생합니다. Request.ServerVariables 컬렉션 속도는 다른 컬렉션 속도보다 매우 느립니다.

팁 25: 최신 구성 요소로 업그레이드하십시오

시스템 구성 요소들은 자주 변경되므로 최신 구성 요소로 업그레이드해야 합니다. 가장 좋은 방법은 Windows 2000으로 업그레이드하고 IIS 5.0, ADO 2.5, MSXML 2.5, Internet Explorer 5.0, VBScript 5.1 및 JScript 5.1로 업그레이드하는 것입니다. IIS 5.0 및 ADO 2.5는 다중 프로세스 컴퓨터에서 놀랄만한 성능을 제공합니다. Windows 2000에서는 ASP가 네 개 이상의 프로세서로 완벽하게 확장되지만, IIS 4.0에서는 ASP가 두 개 이상의 프로세서로 제대로 확장되지 않았습니다. 응용 프로그램에 사용된 스크립트 코드와 ADO가 많을수록 Windows 2000으로 업그레이드한 후 얻게 될 성능상의 장점이 많아집니다.

Windows 2000으로 업그레이드할 수 없는 경우에는 SQL Server, ADO, VBScript 및 JScript, MSXML, Internet Explorer, Windows NT 4 서비스 팩의 최신 릴리스로 업그레이드할 수 있습니다. 이렇게 하면 안정성이 향상되는 동시에 성능도 좋아집니다.

팁 26: 웹 서버를 조정하십시오

사이트 성능을 개선할 수 있는 다양한 IIS 조정 매개 변수들이 제공됩니다. 예를 들어, IIS 4.0에서 ASP ProcessorThreadMax 매개 변수(IIS 설명서 참조)의 값을 늘리면 성능이 크게 향상된다는 점이 밝혀졌습니다. 특히, 데이터베이스와 같은 백엔드 리소스나 스크린 스크래퍼와 같은 기타 미들웨어 제품에서 대기하는 경향이 있는 사이트에서는 더욱 그렇습니다. IIS 5.0에서 현재 알려진 것처럼 최적의 AspProcessorThreadMax 설정을 찾는 것보다는 ASP Thread Gating을 조정하는 것이 보다 효율적입니다.

이 기사의 뒷부분에 있는 IIS 조정 부분에 참고 자료가 나와 있습니다.

최적의 구성 설정은 다른 요소들보다는 응용 프로그램 코드, 응용 프로그램 코드를 통해 실행되는 하드웨어 및 클라이언트 작업 부하에 의해 결정됩니다. 최상의 설정을 찾는 유일한 방법은 성능 테스트를 수행하는 것입니다.

팁 27: 성능 테스트를 수행하십시오

앞에서 언급한 바와 같이, 성능은 일종의 기능입니다. 사이트 성능을 개선하려면 일단 성능 목표를 설정한 후 그 목표에 도달할 때까지 점차적으로 개선 작업을 수행하십시오. 성능 테스트를 프로젝트 마지막 단계로 미루지 마십시오. 프로젝트 마지막 단계에서 아키텍처 변경을 하기란 너무 늦기 때문에 고객을 실망시키는 경우가 종종 발생합니다. 성능 테스트는 일상적인 테스트의 일부로서 수행하십시오. 성능 테스트는 ASP 페이지나 COM 개체 등과 같은 개별 구성 요소에서 별도로 수행하거나 전체 사이트에 걸쳐 한꺼번에 수행할 수 있습니다.

대부분의 관리자들은 한 개의 브라우저에서 페이지를 요청함으로써 웹 사이트의 성능을 테스트합니다. 이렇게 테스트하면 사이트의 응답 성능은 제대로 파악할 수 있지만, 일정한 로드 하에서 사이트가 제대로 작동하는지는 파악할 수 없습니다.

일반적으로 성능을 정확하게 측정하려면 테스트 전용 환경이 필요합니다. 이러한 테스트 전용 환경에는 프로세서 속도, 프로세서 수, 메모리, 디스크, 네트워크 구성 등의 측면에서 프로덕션 하드웨어와 거의 유사한 기능을 갖는 하드웨어를 설치해야 합니다. 그런 다음에는 동시 사용자 수, 사용자의 요청 빈도, 사용자가 방문하는 페이지의 유형 등과 같은 클라이언트 작업 부하를 정의해야 합니다. 사이트로부터 실제 사용량 데이터를 얻을 수 없으면 적당한 값을 추측해야 합니다. 끝으로, 예상되는 클라이언트 작업 부하를 시뮬레이트할 수 있는 도구가 필요합니다. 이러한 도구들을 사용하면 "N 명의 동시 사용자가 있는 경우에는 몇 대의 서버가 필요한가요?"와 같은 질문에 답할 수 있으며 병목 현상을 찾아내서 최적화를 위해 이를 해결할 수 있습니다.

훌륭한 웹 스트레스 테스트 도구들 중 몇 가지가 이 기사의 뒷부분에 나와 있지만, Microsoft WAS(Web Application STRess) 도구 키트를 사용할 것을 권장합니다. WAS에서는 테스트 스크립트를 작성하여 웹 서버를 방문하는 사용자들을 수 백명 또는 수 천명까지 시뮬레이트할 수 있습니다. WAS는 초당 요청수, 응답 시간 배포, 오류 카운트 등을 포함하여 매우 많은 수의 통계를 보고합니다. WAS에는 다양한 클라이언트 인터페이스와 웹 기반 인터페이스가 포함되어 있으며, 웹 인터페이스를 사용하면 테스트를 원격으로 수행할 수 있습니다.

반드시 IIS 5.0 조정 가이드를 읽어보십시오.

팁 28: 관련 리소스 링크를 읽어보십시오

다음은 몇 가지 아주 유용한 성능 관련 리소스 링크들입니다. Developing Scalable Web Applications은 반드시 읽어보는 것이 좋습니다.

리소스

ASP 스크립트 최적화
IIS 조정
ADO 및 SQL Server
ASP 구성 요소 및 스레딩 모델
딕셔너리 구성 요소
세션 상태
성능 및 확장성
도구
문서
ASP 웹 사이트
ASP 스타일
XML

ASP 스크립트 최적화

Developing Scalable Web Applications

Got Any Cache? 저자: Nancy Winnick Cluts

Maximizing the Performance of Your Active Server Pages 저자: Nancy Winnick Cluts

15 Seconds: Performance Section

Enhancing Performance in ASP - Part I 저자: Wayne Plourde

When is Better Worse? Weighing the Technology TRade-Offs 저자: Nancy Winnick Cluts

Speed and Optimization Resources 저자: Charles Carroll

IIS 조정

The Art and Science of Web Server Tuning with Internet Information Services 5.0

Leveraging ASP in IIS 5.0 저자: J.D. Meier

Tuning IIS 4.0 for High Volume Sites 저자: Michael Stephenson

Tuning Internet Information Server Performance 저자: Mike Moore

Navigating the Maze of Settings for Web Server Performance Optimization 저자: Todd Wanke

Managing Internet Information Server 4.0 for Performance 저자: Hans Hugli

ADO 및 SQL Server

Top Ten Tips: Accessing SQL Through ADO and ASP 저자: J.D. Meier

Improve the Performance of your MDAC Application 저자: Suresh Kannan

Pooling in the Microsoft Data Access Components 저자: Leland Ahlbeck 및 Don Willits

SQL Server: Performance Benchmarks and Guides

Improving the Performance of Data Access Components with IIS 4.0 저자: Leland Ahlbeck

Microsoft Data Access Components (MDAC) and ActiveX Data Objects (ADO) Performance Tips 저자: Leland Ahlbeck

Microsoft SQL Server 7.0 Practical Performance Tuning and Optimization - The Server Perspective 저자: Damien Lindauer

Microsoft SQL Server 7.0 Practical Performance Tuning and Optimization - The Application Perspective 저자: Damien Lindauer

Accessing Recordsets over the Internet 저자: Dino Esposito

ASP 구성 요소 및 스레딩 모델

ASP Component Guidelines 저자: J.D. Meier

Q243548: INFO: Design Guidelines for VB Components under ASP

Threading Models Explained 저자: Nancy Winnick Cluts

So Happy Together? Using ActiveX components with Active Server Pages 저자: Nancy Winnick Cluts

Developing Active Server Components with ATL 저자: George Reilly

Agility in Server Components 저자: Neil Allain

Building High-Performance Middle-Tier Components with C++ 저자: Jon Flanders

Active Server Pages and COM Apartments 저자: Don Box

House of COM: Active Server Pages 저자: Don Box

House of COM: Contexts 저자: Don Box

House of COM: Performance TRade-offs of the Windows 2000 Component Execution Environment 저자: Don Box

Building COM Components That Take Full Advantage of Visual Basic and Scripting 저자: Ivo Salmre

Component Design Principles for MTS

딕셔너리 구성 요소

Creating a Page Cache Object 저자: Robert Coleridge

Abridging the Dictionary Object: The ASP Team Creates a Lookup-Table Object 저자: Robert Carter

Caprock Dictionary

Site Server Commerce Edition에는 딕셔너리 구성 요소가 들어 있습니다.

세션 상태

Q175167: HOWTO: Persisting Values Without Sessions

Q157906: HOWTO: How To Maintain State Across Pages with VBScript

XML-based Persistence Behaviors Fix Web Farm Headaches 저자: Aaron Skonnard

House of COM: Stateless Programming 저자: Don Box

성능 및 확장성

Blueprint for Building Web Sites Using the Microsoft Windows DNA Platform

Server Performance and Scalability Killers 저자: George Reilly

Microsoft Visual Studio Scalability Center

Fitch & Mather Stocks 2000

Tuning the FMStocks Application

High-Performance Visual Basic Apps 저자: Ken Spencer

Duwamish Books, Phase 4

Top Windows DNA Performance Mistakes and How to Prevent Them 저자: Gary Geiger 및 Jon Pulsipher

Building from Static HTML to High-Performance Web-Farms 저자: Shawn Bice

도구

Microsoft Web Application STRess Tool

I Can't STRess It Enough -- Load Test Your ASP Application 저자: J.D. Meier

Windows DNA Performance Kit

Monitoring Events in DisTRibuted Applications Using Visual Studio Analyzer 저자: Mai-lan Tomsen

문서

Professional Active Server Pages 3.0, Wrox Press. (특히, Chapter 26:Optimizing ASP Performance, 저자: George Reilly 및 Matthew Gibbs 참조)

Microsoft Internet Information Services 5.0 Resource Guide(Windows 2000 Server Resource Kit와 함께 제공됨), Microsoft Press.

Microsoft Internet Information Server Resource Kit (for IIS 4.0), Microsoft Press.

Programming DisTRibuted Applications with COM and Microsoft Visual Basic 6.0 저자: Ted Pattison, Microsoft Press.

Effective COM 저자: Don Box, Keith Brown, Tim Ewald, Chris Sells 및 Addison-Wesley.

Developing Web Usability: The Practice of Simplicity 저자: Jakob Nielsen, New Riders.

ASP 웹 사이트

Microsoft TechNet for IIS

LearnASP.com

4GuysFromRolla.com

15Seconds.com

AspToday.com

Asp101.com

AspLists.com. 여기에는 다음과 같은 특수 메일 목록이 들어 있습니다.

  • Fast Code!
  • ASP Advanced
  • Not NewbieState Management
  • Scalability
  • Visual Basic Components
  • XML
  • C++/ATL Component Building

UseIt.com: Web Usability

ASP 스타일

ASP Best Practices 저자: George Reilly

ASP Quick Lessons 저자: Charles Carroll

Planning for ASP 저자: John Meade

ASP Guidelines 저자: J.D. Meier

XML

Inside XML Performance 저자: Chris Lovett

Inside MSXML3 Performance 저자: Chris Lovett


+ Recent posts