◆ Performance Tips for All Applications

1. Exception 처리를 가급적 줄여라 : 매 Exception 처리마다 성능이 엄청나게 떨어진다.

예) 예제에서 throw Exception을 주석처리하고 실행속도를 비교해보라!
public static void Main(string[] args){
int j = 0;
for(int i = 0; i < 10000; i++){
try{
j = i;
throw new System.Exception();
} catch {}
}
System.Console.Write(j);
return;
}

☞ 런타임이 발생시키는 Exception도 있으므로 주의할 것.
예) Response.Redirect()는 ThreadAbort exception을 발생시킨다.
☞ VB에서는 overflow나 divide-by-zero 처리를 위한 int값 검사를 기본적으로 하도록 되어 있음.
☞ COM을 사용한다면 HRESULTS가 exception을 리턴할 수도 있음을 명심할 것.

2. 한번의 호출로 가급적 많은 일을 하게 하라. 호출이 많을수록 부하가 커진다.

3. boxing-unboxing 작업이 별로 없는 환경에서는 가급적 값형식(ValueTypes)으로 설계하라.

예) struct형식이 훨씬 빠르다!
using System;

namespace ConsoleApplication{

public struct foo{
public foo(double arg){ this.y = arg; }
public double y;
}
public class bar{
public bar(double arg){ this.y = arg; }
public double y;
}
class Class1{
static void Main(string[] args){
System.Console.WriteLine("starting struct loop...");
for(int i = 0; i < 50000000; i++)
{foo test = new foo(3.14);}
System.Console.WriteLine("struct loop complete.
starting object loop...");
for(int i = 0; i < 50000000; i++)
{bar test2 = new bar(3.14); }
System.Console.WriteLine("All done");
}
}
}

☞ 그러나, 이러한 값형식(ValueTypes)은 개체형식(Objects)보다 유연성이 훨씬 없으므로 적절히
사용하지 않으면 성능악화를 초래할 수 있다.
☞ 위 예제에서 foo와 bar를 배열이나 hashtable로 저장하는 단순한 boxing-unboxing작업으로만
수정해도 값형식의 성능이 상당히 떨어지게 됨을 볼 수 있을 것이다.

4. 그룹(여러개의 아이템)을 추가할 때는 Add() 함수 대신 AddRange() 함수를 사용하라.

5. 작업환경 관리를 위해 어셈블리 갯수를 최소한으로 줄여라.

6. String 반복작업에는 foreach 대신 for 루프문을 사용하는 것이 성능향상에 좋다.

예) 예제에서 마지막 for문 대신 foreach문의 주석을 풀고 실행해보라!
public static void Main(string[] args) {
string s = "monkeys!";
int dummy = 0;

System.Text.StringBuilder sb = new System.Text.StringBuilder(s);
for(int i = 0; i < 1000000; i++)
sb.Append(s);
s = sb.ToString();
//foreach (char c in s) dummy++;
for (int i = 0; i < 1000000; i++)
dummy++;
return;
}

7. 복잡한 문자열 처리는 단순 문자열 연결보다 StringBuilder를 사용하는 것이 훨씬 좋다.

예1) 단순 문자열 처리의 경우 : 느리다.
namespace ConsoleApplication1.Feedback{
using System;

public class Feedback{
public Feedback(){
text = "You have ordered: \n";
}

public string text;

public static int Main(string[] args) {
Feedback test = new Feedback();
String str = test.text;
for(int i=0;i<50000;i++){
str = str + "blue_toothbrush";
}
System.Console.Out.WriteLine("done");
return 0;
}
}
}

예2) StringBuilder를 사용한 경우 : 훨씬 빠르다.
namespace ConsoleApplication1.Feedback{
using System;

public class Feedback{
public Feedback(){
text = "You have ordered: \n";
}

public string text;

public static int Main(string[] args) {
Feedback test = new Feedback();
System.Text.StringBuilder SB = new System.Text.StringBuilder(test.text);
for(int i=0;i<50000;i++){
SB.Append("blue_toothbrush");
}
System.Console.Out.WriteLine("done");
return 0;
}
}
}

☞ 성능이 좋은 서버에서는 쉽게 차이를 느낄 수 없으나, 10개 이상의 문자열 조작이 동시에
발생하면 차이를 쉽게 느낄 수 있다.

8. Windows Forms 응용프로그램은 배포전에 Precompile하라. ngen.exe라는 툴로 인스톨할 때, 혹은
배포전에 Precompile할 것인지 선택할 수 있다.

9. 다차원 배열(rectangular arrays)보다 중첩배열(jagged arrays)이 성능이 더 좋다.

------------------------------------------------------
C# Visual Basic 7
------------------------------------------------------
Assignment (jagged) 14.16 12.24
Assignment (rectangular) 8.37 8.62
Neural Net (jagged) 4.48 4.58
Neural net (rectangular) 3.00 3.13
Numeric Sort (jagged) 4.88 5.07
Numeric Sort (rectangular) 2.05 2.06
------------------------------------------------------
(* 숫자가 높을수록 성능이 좋다)

10. IO 버퍼 크기를 4KB ~ 8KB로 유지하는 것이 성능이 가장 좋다.

11. 비동기 IO를 주의깊게 사용하라. 적절히만 사용하면 10배가량 성능 개선 효과가 있다.


◆ Tips for Database Access

1. 최적화된 공급자(Provider)를 사용하라. SQL Server에는 System.Data.SqlClient가 최적이다.

2. 가능한한 DataSet 대신 SqlDataReader를 사용하라.

------------------------
ADO SQL
------------------------
DataSet 801 2507
DataReader 1083 4585
------------------------
(* 숫자가 높을수록 성능이 좋다)

3. 멀티프로세서 서버에서는 Mscorwks.dll 대신 Mscorsvr.dll를 사용하라.

4. 가능한한 모든 쿼리문을 저장 프로시저로 대치하라.

5. 동적 연결 문자열을 사용할 때는 풀링을 고려하여 항상 동일하게 적용되도록 주의하라.

6. 사용하지 않는 기능은 꺼라(Turn off).

예) 자동 트랜잭션 참가기능은, 사용하지 않으면 꺼라.
SqlConnection conn = new SqlConnection(
"Server=mysrv01;
Integrated Security=true;
Enlist=false");

예) 기본키 정보가 필요하지 않으면 사용하지 말라. (MissingSchemaAction.AddWithKey를 사용하지 말라.)
public DataSet SelectSqlSrvRows(DataSet dataset,string connection,string query){
SqlConnection conn = new SqlConnection(connection);
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = new SqlCommand(query, conn);
adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;
adapter.Fill(dataset);
return dataset;
}

7. SqlDataAdapter 사용시, 비록 편리하더라도, 자동 생성되는 Command 개체를 사용하지 말라.

8. ADO 설계시 다음 사항을 주의하라.

☞ 쿼리문에 있는 모든 항목이 리턴된다.
☞ 서버측 커서가 필요하다면 저장 프로시저를 사용하고, 가급적 서버측 커서 사용을 피하라.
☞ 비상태(stateless), 비연결(connectionless) 페이징 기법을 활용하라.

9. 꼭 필요한 데이터만 DataSet에 저장하라.

10. SqlDataReader 사용시, 가능한 한 자주 순차적 접근(CommandBehavior.SequentialAccess)을 사용하라.


◆ Performance Tips for ASP.NET Applications

1. 캐시를 적극적으로 사용하라.

예)
Output Caching - Stores the static result of an ASP request.
Specified using the <@% OutputCache %> directive:

* Duration - Time item exists in the cache
* VaryByParam - Varies cache entries by Get/Post params
* VaryByHeader - Varies cache entries by Http header
* VaryByCustom - Varies cache entries by browser
* Override to vary by whatever you want:
- Fragment Caching - When it is not possible to store an entire page
(privacy, personalization, dynamic content), you can use fragment caching to store
parts of it for quicker retrieval! later.
a) VaryByControl - Varies the cached items by values of a control

- Cache API - Provides extremely fine granularity for caching by keeping a hashtable
of cached objects in memory (System.web.UI.caching). It also:
a) Includes Dependencies (key, file, time)
b) Automatically expires unused items
c) Supports Callbacks

2. Session State는 필요할 때만 사용하라.




3. View State는 필요할 때만 사용하라.



4. STA COM 사용을 피하라. MTA COM을 사용하라.

☞ 어쩔 수 없이 사용하게 될 경우에는 를 사용하라.

5. 웹에 배포하기 전에 일괄 컴파일(Batch Compile)하라.

6. 불필요하거나 사용되지 않는 Http 모듈을 제거하라.

7. Autoeventwireup 특성을 사용하지 말 것.



8. UTF 인코딩이 필요하지 않은 경우에는 항상 ASCII 인코딩을 사용하라.

9. 최적화된 인증 프로시저를 사용하라.

☞ None, Windows, Forms, Passport 순으로 성능이 저하된다.


◆ Tips for Porting and Developing in Visual Basic

1. 에러 처리는 On Error Goto문 대신 Try/Catch 블록을 사용하는 것이 훨씬 낫다.

예1) 두 함수 처리에 각각 244 ms, 179 ms 소요됨
Sub SubWithError()
On Error Goto SWETrap
Dim x As Integer
Dim y As Integer
x = x / y
SWETrap:
Exit Sub
End Sub

Sub SubWithErrorResumeLabel()
On Error Goto SWERLTrap
Dim x As Integer
Dim y As Integer
x = x / y
SWERLTrap:
Resume SWERLExit
Exit Sub

SWERLExit:
Exit Sub
End Sub

예2) 두 함수 처리에 각각 169 ms, 164 ms 소요됨
Sub SubWithError()
Dim x As Integer
Dim y As Integer
Try
x = x / y
Catch
Return
End Try
End Sub

Sub SubWithErrorResumeLabel()
Dim x As Integer
Dim y As Integer
Try
x = x / y
Catch
Goto SWERLExit
End Try

SWERLExit:
Return
End Sub

2. 전기(초기) 바인딩(Early Binding)을 사용하라.

3. Option Strict와 Option Explicit를 사용하라.

4. 텍스트 비교에 Binary Compare를 사용하라.

5. Format() 함수의 사용을 최소화하라. 대신 ToString()함수를 권장한다.

6. Char() 대신 CharW()를 사용하라. CLR은 내부적으로 Unicode를 사용한다.

7. 변수 할당시 변수 이름을 두번 쓰는 것을 피하라.

예) exp = exp + val 대신 exp += val 로 쓰라.

8. 불필요한 참조(byRef)를 피하라. heap을 사용하는 것이 stack을 사용하는 것보다 느리다.

9. 문자열 연결은 여러 라인에 걸쳐 하지 말고 하나의 표현식으로 표현하라.

☞ 문자열은 수정될 때마다 새로 String 개체를 생성하게 된다.

10. 함수 끝에 항상 Return문을 써주는 것이 성능향상에 도움이 된다.


◆ Tips for Porting and Developing in Managed C++

1. 관리되는 코드와 관리되지 않는 코드를 동시에 사용할 수 있다.

☞ 성능 향상에 필요한 내용을 선택할 수 있다.

2. 모든 C++ 코드는 MSIL(중간언어)로 컴파일될 수 있다.

3. C#이나 VB에 비해 여러가지 장점이 있다.

4. 일반화된 byref 포인터

☞ 배열의 중간을 가로채어 값을 리턴할 수도 있다.
예)
Byte* AddrInArray( Byte b[] ) {
return &b[5];
}

☞ 포인터를 사용하여 배열에서 루프를 돌 수도 있다.
예)
System::Char* PtrToStringChars(System::String*);
for( Char*pC = PtrToStringChars(S"boo");
pC != NULL;
pC++ )
{
... *pC ...
}

☞ linked-list를 쉽게 구현할 수 있다.
예)
Node **w = &Head;
while(true) {
if( *w == 0 || val < (*w)->val ) {
Node *t = new Node(val,*w);
*w = t;
break;
}
w = &(*w)->next;
}

☞ 포인터의 위치를 자유롭게 이동시킬 수 있다.
예)
if( Head==null || val < Head.val ) {
Node t = new Node(val,Head);
Head = t;
}
else {
// we know at least one node exists,
// so we can look 1 node ahead
Node w=Head;
while(true) {
if( w.next == null || val < w.next.val ){
Node t = new Node(val,w.next.next);
w.next = t;
break;
}
w = w.next;
}
}

5. Boxed Type으로의 접근이 가능하다.

예1) C++에서는 Boxed type을 이용하여 직접 형식전환이 가능하다.
__value struct V {
int i;
};
int main() {
V v = {10};
__box V *pbV = __box(v);
pbV->i += 10; // update without casting
}

예2) C#에서는 한단계 더 거쳐야 한다.
struct B { public int i; }
static void Main() {
B b = new B();
b.i = 5;
object o = b; // implicit box
B b2 = (B)o; // explicit unbox
b2.i++; // update
o = b2; // implicit re-box
}

6. STL Collections vs. Managed Collections의 장단점

☞ STL Collection은 빠르지만, CLR framework는 boxing-unboxing에 의해 영향을 많이 받는다.
☞ 이러한 boxing-unboxing 문제점은 금방 해결될 것이다.

7. 가급적 Stack관리 개체(stack-managed objects : ValueTypes)를 사용하라.

☞ Stack이나 Heap에 의해 관리되는 개체를 사용할 수도 있으나 주의해야 한다.
...

ASP.NET으로 웹응용프로그램을 만들고 성능으로 고민해본적이 있는가?

티어를 나누다보니 코드분리와 인터페이스 단계의 증가로 이어지고..

지나친 PostBack기능의 사용으로..

DataSet의 남용으로.. 또는 Pagelet에 의한 DB 커넥션의 증가로..

기타등등 Bind시에 해킹에 가까운 팁들을 필요로 해본적이 있는가?

대개 성능개선은 TDD로 개발할경우 미리 미리 대비할 수 있겠지만..

결국 오픈이 임박하면그때서야 부랴부랴 AppCenter로 부하테스트를 하며 성능 튜닝을 하기 마련이다.

이때 주로 참고하는 것이 스콧 구스리 아저씨의 성능극대화 팁일 것이다.

<Professional ASP.NET Wrox : 부록B스콧구스리의성능극대화팁 >


이것으로 무언가 부족함을 느끼던중 최근의 MSDN Magazine에서 발견한 팁이다.

http://msdn.microsoft.com/msdnmag/issues/05/01/ASPNETPerformance/default.aspx

요약 : 지극히 개인적으로 살을 붙여가면 쓴것으로 어쩌면 일부 정확하지 않은 내용이 포함되었을 수 있습니다.

[[ Performance on the Data Tier ]]

성능 튜닝이 필요한지는 아래의 질문등으로 알수 있다.

DB를 접근하는가? 얼마나 자주하는가? 필요한 데이터만 가져오는가?

라운드트립은 많은가?

문자열의 처리는 적당한가?

생각보다 좋은 10개의 팁을 알아보자...

Tip 1—Return Multiple Resultsets
성능향상을 위해서든 다른것을 위해서든 요즘 Stored Procedure를 많이 사용한다.

이때 DataReader로 ResultSet을 받을때 여러개를 한번의 SP호출로 받을수 있다.

reader = command.ExecuteReader();
while (reader.Read()) {
suppliers.Add(PopulateSupplierFromIDataReader( reader ));
}
reader.NextResult();
while (reader.Read()) {
products.Add(PopulateProductFromIDataReader( reader ));
}

몰라서 두개의 SP로 두번 호출하면 당연히 성능은 저하된다.

Tip 2—Paged Data Access

DataGrid의 페이징 기능은 정말 훌륭하다고 생각할지 모르지만 예제에서나 그런것 같다.

글이 1000개인 블로그에서 한페이지에 5개가 보인다고 가정해보자. DataGrid의 페이징 처리를 위해서는 모든 Row를 다 들고와야하기 때문에 995개는 나타나지도 않으면서 ViewState등의 크기를 아주 많이 증가시키곤 한다.

좋은 방법은 Stored Procedure에서 한페이지에 나타날 갯수와 페이지 인덱스를 받아서 딱 그만큼만 돌려받는 것이다. 뭐 예전부터 게시판 짤때 필요한 페이지만 들고오기 쿼리는 많이 있었다.

그때에 비하면 페이지 노가다가 많이 줄었다.

http://communityserver.org에가면 Tip1, Tip2를 이용한 페이징 서버컨트롤이 있다고 한다.

Tip 3—Connection Pooling

뭐, 직접만들어서 쓰든, 기본 프로바이더를 사용하든, 써드파티를 쓰든 커넥션 풀링은 기본이 되었다. 커넥션 풀의 역할이야 커넥션을 열고 닫는데 드는 시간이 실제 쿼리하는 시간보다 더 걸리는 경우가 많으니까 일단 열어두면 몇개는 닫지말고 가지고 있다가 다음에 또 쓰자는 의도로 만들어 졌다.

근데 .NET의 가비지컬렉션에의한 Close와 Dispose는 절대 의존하지 말자.. 가끔 오픈후에 곤란한 경험을 해본적이 몇번 있다. 예를 들어 오라클내의 커서가 제대로 닫히지 않아서 여러번 호출이 일어나고 나면 더이상 열수 있는 커서다 없다는 식의 리소스 부족 문제가 발생하는데.. 반드시 확실하게 닫아주자.

.NET CLR의 Perfomance Counter를 이용하면 성능을 측정하고 분석하는데 유용하다.

기타 인증방법에 따라, 또는 캐쉬관련, 기타 여러가지 팁이 있다.

Tip 4—ASP.NET Cache API

캐쉬는 ASP.NET에서만 쓸수 있는게 아니다. 만약 어떤 컴포넌트를 만들어서 이것을 ASP.NET에서 사용하고 있다면, HttpContext.Current를 이용해 해당 Request나 Response와 관련된 코딩을 해봤을 수도 있다. 이런 컴포넌트에서 System.Web.dll만 추가하면 HttpRuntime.Cache를 사용할 수 있다. (Page객체, HttpContext객체에 있는 바로 그것-캐쉬객체-이다.)

1. 한번이상 사용될 경우 캐쉬는 유용하다.

2. 특정 유저나 Request에 따라 General한경우에도 유용하다. 특히 오래동안 같은 결과를 가지는 경우 더욱 그렇다. (물론 1보다는 못하다.)

3. 너무 일반적이지 않은 경우 VaryByParam등의 VaryBy가 넘 많을 경우 x6에서 800MB이상을 가지면 메모리 부족 에러가 발생한다.

즉 캐쉬에 최대한 적게 담고, 이걸로 최대한 많은 출력을 반복적으로 Hit시키면서 재사용가능하도록 노력해야 한다. VaryBy None, User, Param, Custom등이 있고, Contents Management Srv.를 이용하면 더 많이 세분화 시킬수 있는걸로 기억한다.

캐쉬에 관해 알아야 할 것은

1. 담았다고 계속 담겨 있진 않는다. 유휴 메모리가 낮아지면 least-recently-used algorithm으로 잘 사용되지 않는 캐쉬는 지워진다.

2. 강제로 무효화 시점을 지정할 수 있다. (무효화 기준은 시간, 키, 파일 : 주로 시간을 사용한다.)

ASP.NET 2.0에서는 DataBase객체에 의한 무효화를 지원한다. 즉 SQL서버에서 데이타가 변경될경우 Cache가 지워 지도록 할수 있다. (즉 메인페이지의 공지사항 캐쉬는 새로운 공지사항이 등록되었을 경우 지워지도록 할 수 있어서, 새 공지 사항을 올리면 딱 한번만 DB에서 읽어오고 이후 계속 캐쉬를 사용하도록 만들수 있다니, 참 좋은 기능이다.)

http://msdn.microsoft.com/msdnmag/issues/04/07/CuttingEdge

Tip 5—Per-Request Caching

이제부터 개인적으로 잘 사용해보려고 하는 팁이다.

간단한 이야기다. Request가 살아있는 동안만 유효한 캐쉬를 생성하는 것이다. 일반적인 캐쉬는 어떤 컨디션이 충족될때까지 살아있는점이 다르다.

예를 들어 Request가 실행되는 동안 반복적으로 사용되어야 하는 것(예. 포럼의 스킨기능구현시 개인화된 일부 컨트롤의 스킨)에서 사용할 수 있다.

사용방법은 HttpContext객체를 이용하면 된다. (이 객체는 매 Request마다 생성되고 HttpContext.Current 로 어디서나 접근 가능하다.) HttpContext객체의 Items값에 넣고 필요할때 거기서 찾아서 쓰면 된다.

Tip 6—Background Processing

일부 값비싼 비용이 드는 일이 코드중에 있을수 있다. 이메일 발송, 파싱, 입력데이타의 검증등..

예를 들어 블로그에 글을 Post할 경우 중복된 Post가 없는지 검사하고, 금칙어 필터를 돌리고, 이모티콘을 파싱하고, 토큰을 처리하고, 인덱스를 만들어서 Post를 요청하고, Attachment를 검사해서 있으면 Post후 이메일로 모든 구독자에 알린다.. 참 스텝이 많다.. --;

이때 인덱싱과 이메일에 비용이 많이 든다. 인덱싱엔 시간이 이메일에발송시는 SMTP에 연결하는 기능이 구독자가 많으면 더 오래걸린다. 이것을 배치작업으로 빼고 VS2005의 DB Cache 무효화를 이용하면 훨씬 효율적일 것이다.

System.Threading.Timer는 잘 알려져있지 않지만 유용한 클래스이다. 적어도 웹개발에는 유용하다.(잉?) 한번 만들어지면 타이머는 설정된 간격으로 ThreadPool의 한 쓰레드에 특정 CallBack을 실행한다. 실감이 안온다면.. 간단히 말해서 Request와 상관없이 ASP.NET코드를 실행이 가능한것이다. 즉 일정 시간간격으로 이메일 배치를 실행하는 것등이 가능핟. 마치 백그라운드 프로세스처럼 말이다.

물론 약간의 문제점도 있다. 내 어플리케이션 도메인이 언로드되면, 당연히 Timer이벤트를 더이상 받을 수 없다. 또 CLR은 프로세스당 쓰레드 갯수 관리가 엄격해서, 타이머가 쓰레드를 할당받지 못해 서버에 큰 로드를 줄 수 있다. 그래서 ASP.NET은 이런 문제발생을 최소화하기위해 미리 프로세스내의 쓰레드들을 예약해 놓고, 전체 쓰레드중 일부는 Request처리에만 사용한다. 그러므로 내가 너무 많은 비동기 처리를 요구하면 문제가 될 수 있다.

Tip 7—Page Output Caching and Proxy Servers

스콧 구스리 아저씨의 팁에서 가장 많이 활용한 것일지도 모르겠다.

Page, User Control, Server Control(HttpHandlers, HttpModules)와 컨텐츠로 만들어진 ASP.NET 프리젠테이션 레이어는 결국 Output을 만들어 낸다. 이 Output이 만약 같다면 다시 Output을 조합해서 만들어낼 필요없이 아까의 Output을 보내주면 될것이다. 이것이 Output Cache다.

사용법은 초간단.

<%@ Page OutputCache VaryByParams="none" Duration="60" %>
60초동안 아무구분없이 이페이지에 대한 모든 요청에 대해 처음에 만들어진 결과를 보낸다는 거다.

default.aspx?Report=1와 default.aspx?Report=2의 결과가 달라야 할경우에는 VaryByParam="Report"으로 처리하면 된다. 이밖에VaryByCustom등으로 사용자가 출력이 다른각각의 경우를 구분해서 캐쉬할수 있다. 이렇게 해야만 요즘의 로그인상태와파라미터에의해 동적으로 변하는 웹에서 문제가 없다. 적용할때는 조심해서 적당한 구분식과 기간을 정해야 한다.

일단 ASP.NET 페이지 출력캐쉬를 쓰면 downstream caching servers(Microsoft Internet Security and Acceleration Server)에 캐쉬하기 위한 HTTP헤더도 자동으로 설정된다. 이렇게되서 원래의 서버에 오지도 않고 네트워크상에서 캐쉬가 되게 된다.

지극히 개인화된 페이지보다는 거의 변동이 없거나 유저와 파라미터에 영향을 받지 않는 페이지에 효율적이다. 동접10만의 사이트에서 유저별로 캐쉬를 길게 생성한다면 최악의경우 캐쉬기간동안 방문한 페이시 수 * 유저수(10만) 가 설정된 캐쉬기간동안 존재하게 된다. 그러므로 각각의 페이지에 최적화 시켜 설정하자.

Tip 8—Run IIS 6.0 (If Only for Kernel Caching)

windows2003의 IIS6.0을 사용하고 있지 않다면, 좋은 성능 향상 기회를 놓친것이다. 위의 출력캐쉬가 IIS 5.0에서는 Request가 IIS -> ASP.NET으로 간다. 캐싱이 되어 있다면, ASP.NET의 HttpModule이 Request를 받아서 캐쉬로부터 Contents를 보내준다.

IIS 6.0에서는 ASP.NET의 코드를 바꾸지 않고 커널캐싱을 이용할수 있다. ASP.NET으로 캐쉬되어 있으면 커널에서 Request를 네트워크 드라이브에서 바로 받아서 캐쉬의 Response를 응답하고 종료한다.(이때 User Context로는 전혀 전환이 일어나지 않는다.)

이로 인한 성능 향상은 대단하다고 한다. (아직 Windows 2003 Server을 IDC의 실제 서버에서 운영해본적이 없어서 나도 경험은 없다.) It was amazing! 이라는데.. ^^

Tip 9—Use Gzip Compression

대역폭이 문제가 될때 쓸수 있지만 약간의 제한사항이 있다. IIS는 gzip으로 전송할 컨텐츠를 압축 가능한데, 브라우저가 지원해야 한다. IE 6.0과 fireFox가 지원한다. 이렇게 하면 많은 양의 데이터를 압축하여 전송시간도 줄이고, 대역폭을 아낄수 있다.

IIS5.0에서 사용하는것에 비해Gzip보다 IIS6.0에서 빌트인 되어 있다.

IIS5.0에서 설정하려면 http://support.microsoft.com/?id=322603를 참고하면 된다.

Tip 10—Server Control View State

ASP.NET에서 출력할때 서버쪽 일부 객체들의 인스턴스값들을 직렬화해서 클라이언트에 Input hidden Tag로 보낸다. 이정보는 다음 PostBack처리시 다시 생성되는 서버 객체들의 기존 상태를 복원하는데 사용되고 이후 이벤트 처리기가 동작하여 마지 상태가 저장되는 것 처럼 보이는 것이다.
즉 서버 메모리 사용없이 쿠키 없이 어떤 상태를 보존 가능한 방식이다.

하지만 기본적으로 View State를 사용하는 서버컨트롤이 많아질수록 ViewState문자열도 비례하여 많아져서 Request시마다 서버로 전송되고 서버에선 이것을 파싱하고 값을 복원하므로 성능저하의 원인이 된다. 결국 서버의 메모리 사용량도 증가시킨다.

DataGrid 같은 경우 ViewState기능이 필요 없을때도 기본값이 Enable로 매우 비싼 비용이 소요될수 있다.

각각의 Server컨트롤의 ViewState를 조정해도 되고, Page자체에서 비활성화 시킬수 있다.

<%@ Page EnableViewState="false" %>

만약 PostBack을 사용하지 않는다면 반드시 비활성화 시키자.

참 좋은 정보가 많은 글이었다.. 시간이 되면 정확한 원문을 봐보자..

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag/html/scalenetchapt06.asp

에도 관련된 좋은 정보들이 있다.

Posted by 퓨전마법사
,