2012-10-08 2 views
0

할당 된 개체를 사용하고 나중에 할당을 풀링하는 풀링 알고리즘을 작업 중입니다. 그러나 객체를 재활용의 문제 중 하나는 예를 들면 다음과 같습니다사용 후 개체 변수 지우기 (풀링) C#

someObject obj = pool.alloc(); //gives me a new object if no previous allocations, If an allocation has been recycled, returns a previous allocation 
obj.someVariable = "foo"; 
pool.recycle(obj); 

나는 것이 었습니다 경우 여분의 램을 할당 할 필요가 없도록 기존 할당을하고 저장됩니다 위의 코드 또 다른 someObject. 그러나 다음이 문제가 작성

someObject obj = pool.alloc(); //gives me the above allocation 
obj.otherVariable = "bar"; 
obj.dump(); 

을 따라서, 나는 다음과 같은 결과를 얻을 것이다 :

someVariable = foo 
    otherVariable = bar 

위의 접근 방식은 문제를 만듭니다. 어떤 이유 (또는 다른 누군가)가 객체 내부에서 특정 변수를 사용하지 않는 알고리즘을 사용하면 이전 값으로 인해 불필요한 동작이 발생할 수 있습니다. 내가 약간의 방법으로 기본 생성자를 다시 호출 할 수 있는지 (나쁜 아이디어), C# (고맙게도)이 그렇게 할 수없는 것처럼 보이는지 조금 훑어 보았다. 그러나 이것을 수행하기 위해 리플렉션을 사용하는 방법이 있는지 궁금합니다. 또한 객체의 변수를 지우는 것이 malloc (새로운)을 피하는 목적을 무효화합니까? 즉, 변수를 지우는 데 시간을 소비하면 성능 향상이 최소화됩니까? 나는 비평과 조언이 크게 평가되도록 풀링을 가르치려고 노력하고 있습니다! 당신은 당신이 이미 존재하는 객체를 검색하여 피할 수있는 몇 가지 복잡한 설정 작업을 재사용하는 경우

풀링 정말 필요한 경우에만입니다 :

+6

이 풀링 *이 필요하다는 증거가 있습니까? –

+1

아마도이 작업을 원하지 않을 것입니다. 변수를 쉽게 재사용 할 수 있다면 컴파일러/JITter는 알지 못하면 그렇게 할 것입니다. 그렇지 않다면 더 비싸고 작동하지 않을 확률이 더 높습니다. (또한 프로그래머에게 더 높은 부담을줍니다. 각 항목이 완료되면 앱에 알립니다.) – Servy

답변

1

여기 풀링을 바라 보는 하나의 방법입니다. 예를 들어, 개체 풀링에 가장 잘 알려진 응용 프로그램 중 하나는 "데이터베이스 연결"의 형태입니다.

풀링은 데이터베이스 연결 (DBConns)에서 작동합니다. 이유는 1) DBConn을 연결 문자열로 쉽게 식별 할 수 있기 때문입니다. 2) DBConn은 많은 작업과 시간을 필요로합니다. 사소한 식별은 연결 문자열을 일치시킴으로써 수행됩니다. 두 개의 연결 문자열이 동일하면 연결 문자열도 동일해야합니다. 또한 연결 문자열이 있으면 서버 주소를 조회하고 소켓을 열고 인증하고 연결을 설정하는 데 수백 밀리 초가 걸릴 수 있습니다. 즉, 연결이 해제되면 다음 번에 동일한 연결 문자열에 대해 연결이 요청 될 때 다시 사용할 수 있기 때문에 풀링은 데이터베이스 연결에 적합합니다.

.NET 런타임 환경은 객체를 신속하게 할당하고 해제하여 메모리 문제가 발생하지 않도록하는 것이 매우 좋습니다. 메모리 사용이나 할당 속도가 걱정된다면 그렇게하지 마십시오. 당신은 당신 자신의 메모리를 제로로함으로써 컴파일러의 성능을 이길 수 없다. 그러나 개체에 풀에서 기존 개체를 검색하여 피할 수있는 복잡하고 긴 설정이있는 경우 몇 가지 이점을 찾을 수 있습니다.

풀링의 또 다른 좋은 예는 비디오 게임의 입자 시스템입니다. 수백 개의 입자가 생성되고, 수명주기를 거치며, 파괴되어야합니다. 오래된 입자가 죽은 후에 생성되는 새로운 입자에 대해서만. 일반적인 파티클 시스템은 X 개의 오브젝트를 배열로 생성하고, 원래 위치에 새로 생성 된 파티클로 수명이 다한 오브젝트를 반환하는 Reset() 함수를 가지고 있습니다. 입자가 쉽게 식별 될 수 있고 설정 작업 (그래픽 시스템에 질감, 위치 지정 등을 제공하기 때문에)이 작동하는 이유는 다시 나타납니다.

응용 프로그램에 "사소한 일치 식별"기능과 피할 수있는 오랜 설치 프로세스가 모두 있습니까? 그렇지 않은 경우 매번 객체를 새로 할당하십시오. 성능 저하가 나타나지 않을 것을 제안합니다.

편집 : 성능 관점에서, 이제 여기를 살펴 보자 :

재설정 변수 = O (N) 할당 문; 리플렉션을 사용하면 상당히 증가시킬 수 있습니다.

새 오브젝트 인스턴스화 = 하나의 malloc 호출, 하나의 생성자 호출; 복잡성 수준은 생성자 코드 및 메모리 조각화에 따라 다릅니다.

리셋을 사용하여 변수를 재설정 할 수 있지만 할당을위한 O (N)이 malloc 및 생성자보다 빠르다는 것을 미리 알아야합니다. 데이터베이스 연결의 경우 조건이 만족됨을 알고 있습니다. 수영장에 맞는 것이 사실입니까?

편집 : 아래에서 귀하의 의견을 통해 실제로 풀링이 적절한 경우를 발견 할 수 있습니다. 그렇다면 이상적인 접근 방법은 풀링하려는 모든 클래스에 대해 Reset() 함수를 만드는 것입니다. 함수 Reset()을 정의하는 IPoolable 인터페이스를 만들어보십시오. 그런 다음 풀링 할 각 클래스에 대해 Reset() 함수를 정의하여 모든 키 변수를 0으로 만듭니다. 컴파일하기 때문에 리플렉션 오버 헤드가 발생하지 않으며 동적 코드에서는 가능하지 않은 객체 별 최적화를 유지 관리 할 수 ​​있습니다.

풀의 경우 풀 클래스를 MyPool<IPoolable>으로 정의하십시오. 이전에 재활용 된 객체가 검색 될 때마다 호출자에게 다시 전달하기 전에 Reset()으로 호출 할 수 있습니다.

+0

지금은 데이터베이스에서 데이터를 가져 오는 거대한 ASPX 응용 프로그램입니다. 많은 것은 내 코드가 아니며, 모든 코드가 객체를 mallocing한다는 것을 알게되었습니다. 대개 동일한 유형의 객체를 대개 신속하게 폐기하기 위해 계속 반복합니다. 몇 명의 사용자는 여전히 OK이지만 잠시 후 부담이됩니다. 또한, 아니, 비디오 게임 코드에서 일하는 것에서 GC는 꽤 나쁜 관리 할당입니다. –

+0

너무 많은 개체를 할당하는 ASPX 웹 서버의 경우 나중에 풀링하지 않고 나중에 다시 요청할 수있는 개체를 캐싱하기를 원할 수 있습니다. 가비지 컬렉터가 매우 잘 최적화되어 있지만 불필요한 할당/할당을 피하면 가장 큰 이점을 얻을 수 있습니다. –

+0

성능이 향상된 캐싱 시스템을 이미 구축했습니다. 미래에는이 애플리케이션이 더 커질 것이기 때문에 한 걸음 더 나아가려고 노력합니다. 이전 코드를 수정하는 유일한 방법은 다시 작성하는 것이지만 시간이 없거나 그렇게 할 의향이 없습니다. –