본문 바로가기

프로그램&DB/ASP

ASP 성능향상을 위한 15계명

ASP 성능향상을 위한 15계명

written by Microsoft
translated by Microsoft

1. 애플리케이션 레벨의 파일에 대해서는 GLOBAL.ASA을 이용하라.

파일에서 데이터를 읽기 위해서 일반적인 ASP파일시스템 개체를 이용하지 않고, GLOBAL.ASA를 이용하십시오. GLOBAL.ASA란 이벤트 처리 스크립트나 세션을 가지는 개체들에 대한 정보를 저장하는 옵션 파일입니다. 즉, 애플리케이션 전반에 걸친 이벤트에 대한 정보나 개체를 저장할 수 있는 것으로 사용자에게는 직접적으로 보여지지 않는 일종의 시스템 개체를 말합니다. 그리고 ASP파일시스템 개체 대신 이를 이용하여 데이터를 읽는 방법입니다. GLOBAL.ASA는 시스템 개체이므로 데이터가 일단 이 개체에 저장되었다면 사용자가 데이터를 필요로 할 때마다 해당 파일을 다시 읽을 필요가 없습니다. 최초로 데이터를 읽고자 할 때 파일 읽기는 한 번만 이루어지면 되기 때문입니다. 그리고 GLOVAL.ASA에 있는 정보를 수정 또는 변경하는 것은 별도의 .ASP 파일을 실행함으로써 처리할 수 있습니다. 또한 사전 개체를 사용할 수도 있습니다(팁9참조). 이 방법은 매우 효과적으로 속도 개선을 원한다면 반드시 고려해볼 만합니다.

글쎄 아직은 헷갈린다구요?

스크립트를 사용할 경우, 파일을 배열 혹은 사전 개체로 읽기 위해서는 파일시스템 개체를 이용해야 합니다. GLOBAL.ASA과 파일시스템 개체의 차이는 파일을 최초로 읽을 당시에는 차이가 없습니다. 그러나 배열이나 사전 개체로 읽어드린 파일에 대한 사용에서 그 차이가 있습니다. 사용자 입장에서는 이를 통해 필요한 정보를 검색할 때마다 파일을 새로 읽을 필요없이 GLOBAL.ASA에 있는 배열이나 사전개체를 통해 해당 정보를 얻을 수 있습니다. 이에 대해서 이렇게 질문할 수도 있습니다. "하지만, 캐쉬된 컨텐트를 갱신해야 할 경우에는 어떻게 합니까? 이런 경우에도 적용이 가능합니까?." 그러나 그 대답은 "아니요. 마찬가지로 사용할 수 있습니다."입니다. 만일 캐쉬된 정보의 내용을 변경해야 할 경우, 별도의 관리자용 ASP파일을 통해 처리하는 것입니다. 관리자용.ASP 파일은 Application. Lock 명령을 사용해 갱신될 개체에 대한 다른 애플리케이션의 접근을 방지하고, 필요한 정보를 갱신하고 나서 최종적으로 Application.Unlock 명령을 실행하는 스크립트로 구성됩니다.

2. 최종 코드에서 HTML 주석을 제거하라.

프로그램을 어렵게 작성하면 당연히 이해하기도 어렵습니다. 그래서 보통 프로그램 소스 안에 주석을 달아서 이 문제를 처리합니다. 그러나 항상 주석을 다는 것이 좋은 것은 아닙니다. 속도를 떨어뜨리는 문제가 있기 때문입니다. 모든 HTML 주석(스크립트 주석은 괜찮다)을 제거한다면, 클라이언트에서 읽을 수 있는 HTML텍스트 부분이 줄어들고 당연히 이를 통해 스크립트를 IIS 3.0(IIS 4.0 하에서는 HTML 주석이 더 이상 성능 저하를 유발하지 않는다) 상에서 더욱 빨리 실행할 수 있습니다. 물론, 여러분 자신을 위해(또한 코드 유지보수의 어려움을 들기 위해) 작업 내용과 그 이유를 기록한 특별한 README 파일을 그대로 남겨두고 싶을 수 있습니다. 혹은 코드가 '분명치 않은' 모든 곳의 주석은 그대로 남겨두고 싶어할 수도 있습니다. 이럴 때는 주석이 담긴 소스 코드의 복사본을 보관할 수 있습니다. 혹은 작성용 별도 복사본의 주석을 제거할 수도 있습니다. 이러한 방법으로 실행해야 할 필요가 있는 HTML 소스 내에 있는 주석문은 제거하면서도 속도를 향상시키는 방법이 있습니다. C 혹은 C++ 코드를 이용한 애플리케이션의 작성 시 개발자들은 일반적으로 디버그 버전과 배포용 버전으로 컴파일할 수 있는 소스코드를 유지하고 있습니다. 마이크로소프트 비주얼 C++ 과 같은 C++를 이용해 애플리케이션을 개발하는 대부분의 툴은 이러한 성능을 기본적으로 제공하고 있습니다. 물론 이러한 기능을 가지는 HTML 툴이 있다면 좋겠지만.

3. 일괄적인 Response. Write 문장을 사용하라.

만일 작성한 코드의 이곳저곳에 산발적으로 구문을 이용할 경우에는 하나의 Response. Write 문으로 이를 대체하여 일괄 처리하는 방법을 고려해 보는 것이 좋습니다. 우선은, 코드안에 스크립트와 HTML 코드가 어떻게 자리잡고 있는지에 대해서 살펴봐야합니다. HTML 및 스크립트가 서로 여기저기 뒤섞이지 않고 가능한 스크립트 부분과 HTML 부분이 분리될 수 있도록 하는 것입니다. 다시 말하면 HTML와 스크립트를 블록화하는 방법입니다.

4. 오브젝트 사용시에태그를 사용하라.

Server.CreateObject를 사용하면 개체가 바로 생성됩니다. 그러나 실제로 사용되지 않는 개체가 이를 통해서 생성된다면 불필요한 자원의 낭비를 초래합니다. 따라서 이러한 개체를 사용할 때는 태그를 이용하여 사용되지 않는 개체의 생성으로 인한 불필요한 자원의 낭비를 막을 수 있습니다.

5. 가능한한 지역 변수를 쓴다.

지역 변수는 서브루틴 및 함수 내에서만 사용되는 변수입니다(이를 로컬 스코프이라고도 합니다). 이러한 변수는 수치 참조 테이블에 저장되고. 로컬 변수 참조는 컴파일시에 그 값을 알 수 있습니다. 그러나 전역 변수는 런타임시에 그 값을 결정할 수 있습니다. 따라서 미리 그 값이 결정되는 지역변수보다 실행하면서 값을 결정해야 하는 전역변수에 대한 참조는 실행속도를 저하시킵니다. 또한, 크기가 결정되지 않은 전역 변수는 모든 변수 중에서 가장 느립니다 - 크기가 결정되지 않은 전역 변수가 처음으로 이용될 경우에는 전체 개체 모델은 새로운 변수가 생성되기 전에 지정된 속성을 가진 개체를 검색하게 됩니다.

다음이 일부 공개 코드의 예입니다.


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



이러한 코드를 실행시키면 다음과 같은 사항이 나타납니다.

1.변수 Foo는 글로벌 오브젝트로서 결정됩니다.
2.변수 바는 Foo의 일부로서 전체적으로 결정됩니다.
3.변수 blah는 Foo.bar의 일부로서 전체적으로 결정됩니다.
4.변수 gaz는 Foo.bar.blah의 일부로서 전체적으로 결정됩니다.
5.Foo.bar.blah.quaz(1)를 실행합니다.
6.1부터 3까지의 단계를 반복합니다. 시스템은 gaz 요청이 오브젝트 모델을 변형해야 할 것인지에 대해 판단하지 못합니다. 따라서 1부터 3까지의 단계는 baz를 결정하기 위해 다시 실행되어야 합니다.
7.baz를 Foo.bar.blah의 일부로 결정됩니다. 속성을 부여합니다.
8.1부터 3까지를 반복해 resolve zaq를 결정합니다.
9.다시 한번 1부터 3까지를 반복해 abc를 결정합니다.

이미 알고 있는 것처럼, 이것은 극히 비효율적입니다. Visual Basic Scripting Edition (VBScript!)에서 이 코드를 작성하는 가장 빠른 방법은 다음과 같습니다.


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



6. 실행중에 배열의 크기를 재지정하지 마라.

Dim을 이용한 배열의 정의의 경우에는 가급적 Re-diming을 통한 배열의 크기의 재지정을 피해야 합니다. 배열 크기를 재지정하기 위해서는Redim을 사용합니다. 만약 물리적인 메모리의 크기가 제한된 시스템이라면, 성능에 대한 최악의 사례 시나리오에 대비해서 초기 배열의 크기를 설정하는 것이 바람직합니다. 아니면 최적의 경우에 해당되는 크기를 설정하고 이후에 redim으로 크기를 재지정하도록 합니다. 이것은 항상 필요 이상의 메모리를 미리 할당해야 합니다는 것을 의미하지는 않습니다.

아래의 코드에서 불필요한 Dim 및 Re-diming의 이용을 보여주고 있습니다.

처음부터 정확한 크기(이 경우에는 5)로 배열의 크기를 지정(Dim)하고(이 경우에는 5), 그 다음 배열을 확장하기 위해 크기를 재지정(Redim)합니다. 약간의 메모리 손실은 있지만(만일 모든 요소를 활용하지 않는다면) 더욱 속도가 빨라질 것이기 때문입니다.

7. 'Public' 변수의 사용은 피해라.

Public으로 정의된 변수를 사용하지 마라. VBScript!를 작성하거나 ActiveX 컨트롤 혹은 자바 애플릿 내에서 여러 변수에 액세스하는 경우라도, Public 변수를 사용하지 않는 것이 좋습니다. Public 키워드 자체는 아직도 연구되고 있는 부분입니다. 따라서 이를 사용함으로써 얻을 수 있는 잇점이 없기 때문에 Dim을 사용하여 필요한 변수를 정의해서 사용합니다.

8. 문자열 경로를 사용하라.

가능하다면, MapPath는 사용하지 않는 것이 좋습니다. 알 수 있다면, 문자열 경로를 이용하는 것이 좋습니다. MapPath를 이용하기 위해 IIS는 현재의 서버 경로를 알아야 합니다. 이를 위해 IIS는 많은 작업을 해야 되고 이로 인해서 성능이 저하됩니다.

9. 사전 개체를 이용하라.

VBScript!에서 제공되는 사전 개체는 인덱스(키-데이터)에 대한 저장공간을 제공하고 이를 통해 빠른 검색 기능을 제공합니다. 사전 개체는 인덱스를 이용해 배열의 항목을 액세스 하기 ?문에 메모리내에서 인접하지 않은 데이터들에서 효율적인 검색을 제공합니다(왜냐하면 일반적인 배열에서 처럼 원하는 데이터가 있는 순서를 알 필요가 없이 인덱스에 있는 키값만을 통해서 바로 데이터의 위치를 찾을 수 있기 때문이다.). 만일 검색할 데이터들 비선형적인 인덱스(키-데이터)를 보유하고 있다면, 사전 개체를 이용하는 것이 더욱 빠를 것입니다.

하지만 배열은 메모리내에서 서로 순차적인 인덱스(키-데이터)를 가지는 데이터들에 대해서 효율적인 검색과 저장 공간으로 사용될 수 있습니다. 그리고 중요한 점은 사전을 인덱스하는 것이 배열을 인덱스하는 것보다 느리다는 것입니다. 따라서 자료의 성격에 맞는 자료 구조를 선택해야만 합니다.

10. 브라우저의 검증 기능을 이용하라.

브라우저가 지원하는 검증에 대한 스크립트 기능을 활용하십시오. 그렇지 않다면 결국 이를 서버에서 처리해야 되고 이로 인해 서버의 성능저하가 따르게 됩니다. 따라서 클라이언트에서 스크립트를 통해 처리될 수 있는 검증 기능은 서버에 클라이언트로 옮겨야 합니다. 서버는 더 이상 사용자의 요구사항 처리에 직접적인 연관이 없는 부분을 부담하지 않아도 됩니다..

예: 만일 서버 스크립트를 사용하여 다양한 조건 입력을 가진 폼을 사용한다면, 조건에 대해 검사하는 부분을 클라이언트 스크립트-예를 들면, VBScript! 혹은 JScript-로 처리하십시오. 서버는 브라우저에 관한 첵크나 입력값들에 대한 조건 검사를 생략함으로써 불필요했던 코드를 생략할 수 있습니다. 이것은 간단한 스크립트에 대해 유용한 방법입니다.

11. 서버 변수의 사용은 피해라.

서버 변수를 액세스하기 위해서 서버는 필요한 서버 변수만이 아니라 모든 서버 변수를 가져와야만 합니다. 이는 벼룩잡으려다 초가삼간 태우는 격입니다. 이런 일은 서버 변수를 요청할 때 발생하여, 서버 변수를 처음 호출할 때 성능 저하가 일어납니다. 그러나 이후에 일련의 다른 서버 변수를 액세스하는 경우에는 이로 인한 성능의 저하가 따르지는 않습니다. 이미 모든 변수를 가지고 있기 때문입니다.

12. "Option Explicit" 명령을 적용하라.

asp 파일 내에 Option Explicit를 삽입합니다. Visual Basic은 C와는 달리 변수를 정의하지 않고서도 사용할 수 있습니다. 이 옵션을 사용하면 정의되지 않은 변수에 대해서는 오류를 발생 시켜서 이러한 변수를 쉽게 찾을 수 있기 때문입니다. Option Explicit를 사용하면 정의되지 않은 변수의 사용이 허용되지 않습니다. 정의되지 않은 지역 변수는 전역 변수 만큼이나 느립니다(선언된 지역 변수보다 약 두 배 정도 느림). 이러한 옵션을 사용함으로써 코드 실행의 속도를 저하시키는 부분을 쉽게 찾아 제거할 수 있습니다.

13. 컬렉션 값을 로컬 변수로 복사하라.

반복적으로 사용되는 컬렉션 값이 있다면, 지역 변수로 클라이언트에 이를 복사하십시오. 컬렉션에 있는 값을 이용할 때마다 컬렉션에 대한 참조를 할 필요가 없어짐에 따라 스크립트를 실행 속도가 빨라지게 됩니다.

14. 세션 개체를 사용할때는 주의하라.

사용자 세션에 대해 필요한 정보를 저장하기 위해서는 세션 개체가 사용됩니다. 세션 개체에 저장된 변수들은 사용자가 애플리케이션의 다른 웹 페이지로 이동하더라도 없어지지 않습니다. 이 변수들은 사용자가 세션을 유지하고 있는 동안 계속 유지됩니다. 웹 서버는 세션이 설정되지 않은 사용자가 애플리케이션을 통해 웹 페이지를 요구할 때 자동으로 세션 개체를 생성합니다. 서버는 세션이 만료 혹은 중단되었을 때 세션 개체를 삭제합니다. 이를 피하기 위해서는 세션 기능을 정지시킬 수 있습니다. 그러나 IIS3.0에서는 애플리케이션 별로 이를 적용할 수 없습니다. 서버 전반적으로는 이 기능을 사용하지 않는 것이 빠르기는 하지만 일부 기능들이 사용할 수 없을 수 있습니다. 따라서, 정말로 필요할 경우에만 주의깊게 세션 개체를 사용해야 합

모든 애플리케이션에서 세션 개체를 사용한다면 세션 개체가 재초기화(reset)되는 것을 피하기 위해 빠른 시간에 처리되도록 해야 합니다. IIS4.0에서 세션 개체는 애플리케이션 별로 적용될 수 있고 별도의 .asp파일을 통해 세션 개체를 비활성화할 수 있습니다.

15. 성능 테스팅을 실행하라.

앞에서 언급되었듯이 HTML 주석을 없애는 것이 유감스럽기도 하지만 우선 이 방법부터 적용하는 것이 좋습니다(팁2). 이제 ASP 기반 애플리케이션에서 성능 테스트를 해보십시오. 이것은 성능 향상에 대한 안목을 키워주고, 올바른 코딩 '스타일'을 만들어가는데 많은 도움이 될 것입니다. 만약 웹 사이트를 운영하고 있다면 사용자들이 로딩속도가 느리다고 불평하지 않도록 해야 하는 것이 중요합니다. 이를 위해서 asp 파일에 주요한 변경이 이루어졌을 때마다 성능 테스트를 해 보십시오. 이미 웹 사이트를 변경할 때마다 테스트를 진행하고 있을 테니, 앞으로는 기존의 기능 테스트 이외에 성능 테스트를 추가하십시오.