블로그 이미지
Every unexpected event is a path to learning for you. blueasa

카테고리

분류 전체보기 (2794)
Unity3D (852)
Programming (478)
Server (33)
Unreal (4)
Gamebryo (56)
Tip & Tech (185)
협업 (11)
3DS Max (3)
Game (12)
Utility (68)
Etc (98)
Link (32)
Portfolio (19)
Subject (90)
iOS,OSX (55)
Android (14)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (3)
Memories (20)
Interest (38)
Thinking (38)
한글 (30)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (18)
Exercise (3)
나만의 맛집 (3)
냥이 (10)
육아 (16)
Total
Today
Yesterday

effective c# - 1

Programming/C# / 2011. 11. 29. 10:56

C# 코드를 짤 때 좀 더 효율적인 코드를 짜기 위한 방법들을 정리한 포스트이다.
먼저 Code Project의 아래 포스트를 번역한 후 다른 글들도 한번 찾아 봐야겠다.

원본 : http://www.codeproject.com/KB/cs/effectivecspart1.aspx#item1

포스팅한 날짜가 2005년꺼라 꽤 오래된 자료라 현재 버전에서는 어느정도 차이가 있을듯하다.




Item 1 - String의 사이즈를 체크할때는 Length Property를 사용하라.[Performance]

String 비교는 불필요한 overhead를 포함하고 있다. 스트링이 비어 있는지를 체크하는 것이라면

Length properthy를 사용하도록 한다.

 
//NO

if ( str != "")//comparison of two strings {...}

//YES

if ( str.Length > 0) {...}

 

Item 2 - String을 연속적으로 붙일 때에는 StringBuilder 객체를 사용하라.[Performance]

C# string은 변경되지 않는다. string 값이 변경할 때, 아래와 같은 문제들이 야기된다.

  • 필요한양보다 메모리를 추가적으로 더 사용하게 된다.
  • garbage collector가 작업해야 될 일들이 더 생긴다.
  • 실행시 느려지는 코드를 만들게 된다.
 
//NO

String strConcat;
ArrayList arrayOfStrings = new ArrayList();
arrayOfStrings.Add("a"); 
arrayOfStrings.Add("b");
foreach (string s in stringContainer) {
  strConcat += s; 
}

//YES

StringBuilder sbConcat = new StringBuilder ();
foreach (string s in arrayOfStrings ) { 
  sbConcat.append(s);
}

 

Item 3 - 되도록이면 Boxing과 UnBoxing을 피하라[Performance]

BBoxing은 garbage-collected 힙 영역에 value types들을 저장하는데 이용된다.

value type이 box되면 새로운 ojbect가 메모리에 잡히고 생성되어야 한다.

즉, 아래의 두가지 작업이 일어난다.

  - Object 인스턴스를 할당한다.

  - 위 인스턴스에 value type 값을 복사해서 넣는다.

위의 이유로 되도록이면 Boxing을 피하는것이 좋다. ArrayList를 예로 들어보면 struct 키워드를

통해서 ArrayList의 값을 넣을 때 위와 같은 Boxing과 UnBoxing이 일어나게 된다.

 
//NO

struct st { public Int i; }
Arraylist arr = new ArrayList();
for (int i=0 ; i< count; i++) { 
  st s;
  s.i = 4; 
  arr.item.add(st) ; //<- Boxing (Allocating an object instance

                     // + copying the value-type value into that instance)

}
st obj = (st ) arr[0]; //<- Unboxing (casting and copy)


//YES

//Decalre the data type as class.

Class st { public Int i; }

 

Item4 - == 대신 Equal 함수를 사용하라 [Performance]

== 보다 equal 함수를 사용하는것이 좀 더 빠르다.

 

 
string s1= "code";
string s2 = "code1";
//No:

if(s1 == s2){...}
//Yes:

if(s1.Equals(s2)){...}


Item5 - 'foreach' 말고 'for' 를 사용해야 하는 케이스  . [Performance]

'foreach' 랑 'for'  키워드는 일부 비슷한 기능을 한다. - 블록 안에서 루프를 돌면서 기능을 수행

foreach와 for를 사용할때 가장 중요한 차이쯤은 루프문의 증가와 끝에 대해서 따로 작업이 필요 없다는것이다.  또한 foreach는 모든 collection을 사용할 수 있게 만들어졌다. foreach는for의 private한 case에 사용한다고 하기도 한다.

아래 코드를 통해서,  두 루프문이 동일한 결과를 낸다는것을 알 수 있다. 다만 foreach를 사용했을 경우퍼포먼스가 조금 떨어졌다. 좀더 무거운 변수와 큰 array를 사용하면 그 차이가 더 크게 날것이다.

foreach는 for에 비해서 좀더  사용하기 쉽지만 만약 큰 collection을 도는 경우는에는 'for' 를 사용하는것이 퍼포먼스에 좋을 것이다.


Code snippets:

 Collapse
//foreach

int[] arrayOfInts= new int[5];
int sum= 0; 
foreach(int i arrayOfInts) {
  sum+= i; 
}

//for

int[] arrayOfInts= new int[1]; 
int sum= 0;
for(int i = 0; i < arrayOfInts.Length; i++) {
  sum+= arrayOfInts[i]; 
}

Item7 - Prefer the �as� operator instead of direct type casting. [Usage]

The 'as' operator does not throw an exception. In case of bad cast, the return value is null.

Code snippets:

 Collapse
//NO

object o = 1.3; 
try
{
  string str = (string)o; 
} 
catch(InvalidCastException ex){...}

//YES

string str = o as string;
if(null != str){...}

Item8 - Use the 'checked' keyword to avoid overflow. [Usage]

Code snippets:

 Collapse
//NO

short shortNum;
int i = 32768;
shortNum = (short) i; 
// problem after statment excution

// the shortNum variable has an uninitialized value,


//YES

try {
  shortNum = checked((short)i); // solution 

}
catch(OverflowException efx) {}

Item9 - Use the 'is' operator instead of casting. [Usage]

Code snippets:

 Collapse
public class Preson{int nAge;}

//No:

static void main(object o){
  try {
    (Person)o.nAge = 45;
  }
  catch(InvalidCastException ex){...}
}

//Yes:

static void func(object o)
{
  if ( true == (o is Person) )
  {
    (Person)o.nAge = 45;
  }
}

Item10 - Use Explicit interface to 'hide' the implementation of an interface [Usage]

Implementing an interface explicitly 'hides' the interface methods. Visual Studio does not display the interface methods in the intellisense.

Code snippets:

 Collapse
//interface definition

Public interface IChild{
  bool IsHuman();
  void lie();
}

//class definition

Pubic Pinocchio: IChild {
  IChild.IsHuman() //explicit interface implementation

  {
  }
  public void Lie(); //regular interface implementation

}

//using the object

static void main()
{
  // Visual studio will not display

  // the isHuman mwthod in the intellisence.

  Pinocchio o = new Pinocchio();
  ((IChild) o).IsHuman(); // using the IsHuman method explicitly.

  o.Lie();
}

Item11 - Use @ to ease the work with literal paths. [Usage]

Code snippets:

 Collapse
//Old way

String sFilePath = �c:\\a\\b\\c.txt�;

//The C# way

String sFilePath = @�c:\a\b\c.txt�;

Item12 - Make your API assembly CLS Compliant. [Usage]

The CLS-Compliant attribute cause the compiler to check whether your public exposed types in the assembly are CLS-Compliant.

Prefer to define the attribute for the entire assembly, especially for API. The incentive to create a CLS compliant assembly is that any assembly written in one of the .NET aware languages can use your assembly more efficiently because there is no data types interoperability.

Code snippets:

 Collapse
using System; 
[assembly:CLSCompliant(true)]

Item13 - Define destructor and implement IDisposable interface for classes that use native resource directly. [Garbage Collection]

You should define a destructor whenever you use native code in your assembly, i.e., use types that are not managed by the garbage collector. The compiler changes the destructor method to Finalize method (can be seen in the MSIL using the ILDasm.exe).

The Garbage collector marks a class with destructor as Finalized and calls the Finalize method while destructing the object. This behavior guarantees that your release of resources in the destructor will occur.

But, what if you want to release the resources immediately? For this purpose, you should implement the IDisposable interface and call theDispose method when you want to release the object.

Note 1: Do not use destructor if your class does not use native / unmanaged resources. If you do so, you create unnecessary work for the garbage collector.

Note 2: If you implement the IDisposable and a destructor, you should call the Dispose method from the destructor to force the object to release resources immediately.

Code snippets:

 Collapse
~my class {
  if ( true == b) { 
  }
} 

//The MSIL code:

protected override void Finalize() {
  try { 
    if ( true == b) { 
    }
  }finally { base.Finalize();} 
}

Item14 - Avoid the use of GC.Collect. [Garbage Collection]

The GC.Collect method forces garbage collection of all generations.

The performance is hurt during the call to GC.Collect, the application execution is paused. Moreover, the method might cause the promotion of short lived objects to a higher generation, i.e., those object live longer than it should in the first place.

If you must use it in order to reclaim the maximum amount of available memory, use the method only on generation 0.

Code snippets:

 Collapse
//No:

GO.Collect();
//Yes:

GC.Collect(0);

Item15 - Use StructLayout attribute for classes and structs when using COM Interop. [COM Interop]

The attributes cause the compiler to pack the structure in sequential memory so that it can be sent to unmanaged code correctly (unmanaged code that expects a specific layout).

Code snippets:

 Collapse
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)] 
public struct st{
  int i;
  float f;
}

What next?

The part II article, will deal with COM Interop in general, and events between managed and unmanaged code in particular.


출처 : http://www.cyworld.com/mengwi/7680825 

반응형
Posted by blueasa
, |