2016-08-22 3 views
0

루프에 있고 변수를 사용하는 응용 프로그램이 있습니다. 기본적으로 문자열을 변수로 복사 한 다음 다음 문자열로 이동합니다. 나는 내가 필요한 변수를 어떻게 선언해야하는지 궁금해서이 코드를 테스트하여 어느 것이 더 빠를 것인지 테스트했다. malloc이 내가 로컬로 선언 한 변수보다 빠르다는 것은 흥미 롭다. 나는 또한 메모리를 제로화 한 이후로 calloc과 그 속도가 느린 것에 던져 넣었다.루프 내에서 malloc을 사용하여 생성 된 변수에 로컬로 선언 된 변수보다 빠르게 액세스하고 있습니까?

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 
#include <string.h> 
#include <sys/resource.h> 

struct rusage ruse; 
#define CPU_TIME (getrusage(RUSAGE_SELF,&ruse), ruse.ru_utime.tv_sec + ruse.ru_stime.tv_sec + 1e-6 * (ruse.ru_utime.tv_usec + ruse.ru_stime.tv_usec)) 

void gen_random_letters(char *random_buffer, const int len) 
{ 
    int i; 
    static const char alphanum[] = 
     "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 
     "abcdefghijklmnopqrstuvwxyz"; 

    /* initialize random seed: */ 
    srand (time(NULL)); 

    for (i = 0; i < len; ++i) { 
     random_buffer[i] = alphanum[rand() % (sizeof(alphanum) - 1)]; 
    } 

    random_buffer[len] = 0; 
} 

int main() 
{ 
    clock_t tic; 
    clock_t toc; 
    int counter; 
    char *buffer_calloc; 
    char *buffer_malloc; 
    char buffer_local_variable[1450]; 
    char copy_this[1450]; 
    double time_spent; 
    double first, second; 
    int loop_max; 

    loop_max = 5000000; 
    gen_random_letters(copy_this, sizeof(copy_this)); 

    /* Try the locally declared variable */ 
    tic = clock(); 
    first = CPU_TIME; 
    for (counter = 0; counter <= loop_max; counter++) 
    { 
     //memset(buffer_local_variable,0,sizeof(buffer_local_variable)); 
     memcpy(buffer_local_variable,copy_this,sizeof(buffer_local_variable)); 
    } 
    toc = clock(); 
    second = CPU_TIME; 
    time_spent = (toc - tic)/CLOCKS_PER_SEC; 
    printf("cpu local_variable : %.2f secs\n", second - first); 
    printf("Elapsed local_variable: %f seconds\n\n", time_spent); 

    /* Try calloc */ 
    tic = clock(); 
    first = CPU_TIME; 
    for (counter = 0; counter <= loop_max; counter++){ 
     buffer_calloc = calloc(1450,sizeof(char*)); 
     memcpy(buffer_calloc,copy_this,sizeof(buffer_calloc)); 
     free(buffer_calloc); 
    } 
    toc = clock(); 
    second = CPU_TIME; 
    time_spent = (toc - tic)/CLOCKS_PER_SEC; 
    printf("cpu calloc : %.2f secs\n", second - first); 
    printf("Elapsed calloc : %f seconds\n\n", time_spent); 

    /* And now malloc */ 
    tic = clock(); 
    first = CPU_TIME; 
    for (counter = 0; counter <= loop_max; counter++){ 
     buffer_malloc = malloc(1450 * sizeof(char*)); 
     memcpy(buffer_malloc,copy_this,sizeof(buffer_malloc)); 
     free(buffer_malloc); 
    } 
    toc = clock(); 
    second = CPU_TIME; 
    time_spent = (toc - tic)/CLOCKS_PER_SEC; 
    printf("Cpu malloc : %.2f secs\n", second - first); 
    printf("Elapsed malloc : %f seconds\n", time_spent); 

    return 0; 
} 

결과 :

cpu local_variable : 0.57 secs 
Elapsed local_variable : 0.000000 seconds 

cpu calloc : 2.08 secs 
Elapsed calloc : 2.000000 seconds 

Cpu malloc : 0.39 secs 
Elapsed malloc : 0.000000 seconds 

나는 그것을 위해 메모리가 이미 모든 루프를 호출 할 필요가 malloc을 달리 할당되기 때문에 빨리로 로컬로 선언 된 변수를 기다리고 있었다. 내 코드에 결함이 있기 때문에 malloc이 더 빠르거나 그게 바로 그 방법입니다.

+0

난 당신이 '버전'당 하나 개 이상의 실행했던이 오른쪽 평균 또는 뭔가 생각? 그리고 캐싱 작업이 진행될 때를 대비하여 여러 차례 명령을 내리셨습니까? 사과와 사과를 비교해보십시오. – John3136

+0

출력이 코드와 일치하지 않습니다. 랩톱에서이 코드를 실행할 때 ('CPU_TIME' 매크로에서 백 슬래시를 제거한 후) 우승자는 출력에 전혀없는 "buffer_fixed"입니다. – smarx

+0

내 컴퓨터의 결과는 세 가지 테스트를 재정렬해도 일관됩니다. – smarx

답변

2

코드에서 callocmalloc 건의 잘못된 바이트 수가 복사됩니다. sizeof(buffer_malloc)는 포인터의 크기를 알려줍니다.

이러한 경우 sizeof(...) 대신 1450을 사용해보십시오. 위의 변화에 ​​내 노트북 ​​(2015 맥북)에

결과 :

cpu local_variable : 0.16 secs 
Elapsed local_variable: 0.000000 seconds 

cpu calloc : 1.60 secs 
Elapsed calloc : 1.000000 seconds 

Cpu malloc : 0.56 secs 
Elapsed malloc : 0.000000 seconds 

UPDATE 당신이 정말로 1450 * sizeof(char)를 사용해야하는 경우 또한 malloc으로 1450 * sizeof(char*) 바이트를 할당하고

. 그 수정 후

는, 결과는 좀 더 가까이 얻을 :

cpu local_variable : 0.16 secs 
Elapsed local_variable: 0.000000 seconds 

cpu calloc : 0.76 secs 
Elapsed calloc : 0.000000 seconds 

Cpu malloc : 0.57 secs 
Elapsed malloc : 0.000000 seconds 
+0

좋은 캐치 :) 내 결과는 이제 당신에게 가깝습니다. 따라서 각 루프에서 로컬 변수가 mallocing보다 빠르다고 가정하는 것이 안전할까요? – kuchi

+0

@kuchi 원칙적으로 C 코드를 쓰지 않으려 고하므로 잘 모르겠습니다. :-) 그러나 결과는 그것을 제안하는 것으로 보이며 직관적으로 옳은 것으로 보인다. – smarx

+1

@kuchi : 일반적으로 예; 'malloc'과'calloc' 호출은 로컬 배열을 사용하는 오버 헤드를 추가하지 않기 때문에 첫 번째 버전이 더 빨라야합니다. 하지만 원시 속도를 두 가지 방법 중 하나를 사용하는 주된 기준으로 삼지 마십시오. 동적 할당은 속도가 느려지더라도 올바른 대답입니다. –