2010-02-25 6 views
4

성능 향상을 위해 권장되는 이런 종류의 코드가 궁금합니다.C++에서 메모리 재사용

void functionCalledLotsofTimes() { 
    static int *localarray = NULL; 

    //size is a large constant > 10 000 
    if (localarray == NULL) localarray = new int[size]; 

    //Algorithm goes here 
} 

정적 변수가 g ++와 같은 최신 C++ 컴파일러에서 어떻게 구현되는지 궁금합니다. 그들은 전역 변수처럼 취급합니까?

+0

매개 변수를 만들면 완벽하게 유효한 최적화라고 말할 수 있습니다. – GManNickG

+1

'size'가 상수라면, 여기에'new []'를 사용할 이유가 없으며, 스택에 선언하거나 다른 사람들이 제안한 것처럼 함수에 전달할 이유가 없습니다. – Justicle

+0

@Justicle : 때때로 스택 공간이 문제가 될 수 있습니다. 즉, 나는'std :: vector'가 미가공 포인터보다 더 적절하다고 언급 했어야했다. – GManNickG

답변

12

함수에 전역 상태를 도입 했으므로 권장하지 않습니다. 함수에 전역 상태가 있으면 부작용이 있습니다. 부작용은 특히 멀티 스레드 프로그램에서 문제를 일으 킵니다.

자세한 내용은 Referential Transparency을 참조하십시오. 동일한 입력을 사용하면 얼마나 많은 스레드를 사용하더라도 동일한 출력을 항상 원하게됩니다.

효율성을 높이려면 사용자가 버퍼 매개 변수를 매개 변수 중 하나로 지정할 수 있습니다.

global and static variables here의 차이점을 참조하십시오.

0

성능이 크게 향상되었지만 데이터가 어떻게 사용될 것인지 매우 신중해야합니다. 다중 스레드 인 경우 데이터에 대한 액세스 제어를 제공해야합니다. 내가 잘못 본게 아니라면 이미 초기화 된 정적 변수가 어쨌든 "시스템"에 의해 수행되는 경우

 
#include <windows.h> 
#include <stdio.h> 

void StartTime (LARGE_INTEGER * pTime) 
{ 
    QueryPerformanceCounter (pTime); 
} 

ULONG EndTime(LARGE_INTEGER * pTime) 
{ 
    LARGE_INTEGER liDiff; 
    LARGE_INTEGER liFreq; 

    QueryPerformanceCounter(&liDiff); 

    liDiff.QuadPart -= pTime->QuadPart; 
    liDiff.QuadPart *= 1000; // Adjust to milliseconds, shouldn't overflow... 

    (void)QueryPerformanceFrequency(&liFreq); 

    return ((ULONG)(liDiff.QuadPart/liFreq.QuadPart)); 
} 

void functionCalledLotsofTimesStatic(int size) 
{ 
    static int *localarray = NULL; 

    //size is a large constant > 10 000 
    if (localarray == NULL) localarray = new int[size]; 

    //Algorithm goes here 

} 

void functionCalledLotsofTimesDynamic(int size) 
{ 
    int *localarray = NULL; 

    //size is a large constant > 10 000 
    if (localarray == NULL) localarray = new int[size]; 

    //Algorithm goes here 

    delete [] localarray; 
} 


int _tmain(int argc, _TCHAR* argv[]) 
{ 
    LARGE_INTEGER liTimeDynamic, liTimeStatic; 

    StartTime (& liTimeDynamic); 
    for (int loop = 0; loop < 100000 ; loop++) 
    { 
     functionCalledLotsofTimesDynamic (10000); 
    } 
    printf ("Time dynamic alocation : %lu milliseconds\n", EndTime(&liTimeDynamic)); 

    StartTime (& liTimeStatic); 
    for (int loop = 0; loop < 100000 ; loop++) 
    { 
     functionCalledLotsofTimesStatic (10000); 
    } 
    printf ("Time staic alocation : %lu milliseconds\n", EndTime(&liTimeStatic)); 

    return 0; 
} 

0

은, 테스트가 볼 수 :
이 시험을한다. 직접 할 필요가 없습니다. 쓰기 만하십시오

static int *localarray = new int[size]; 

함수가 처음 호출 될 때만 배열이 만들어집니다.

0

일반적으로 이러한 종류의 코드는 사전 할당 된 큰 버퍼가있는 사용자 지정 할당 자 클래스 뒤에 숨겨져 있으므로 "동적 할당"은 실제로 적용되지 않습니다.

std :: vector의 많은 구현에는 기본 구현 형식이 있습니다. 기본적으로 메모리의 "블록"을 2의 제곱으로 할당하므로 벡터가 생성 될 때까지 실제 새로운 할당을 수행 할 필요가 없습니다. 크기가 두 배로 커졌습니다.

관련 문제