2010-07-24 5 views
3

그래서 C++의 정렬 알고리즘을 구현하고 있습니다.하지만 시간이 오래 걸리므로 지금은 벤치마킹하는 것이 좋습니다. 알고리즘을 실행하지만 입력 데이터를 작성하십시오. 저는 현재 각 길이의 입력 (1000, 2000, ...)을 10 번 테스트하여 어느 정도 평균 시간을 얻습니다. 이 10 배 각각에 대해, 나는 수행하여, 올바른 길이의 새로운 임의의 vector를 만들 :이 할 수있는 더 좋은 방법이벤치마킹을위한 무작위 벡터를 만드는 가장 빠른 방법

// Each of the 10 times. 
    for(int j = 0; j < 10; j++) { 

     A.clear(); 

     // 'i' is the current input size. 
     for(int k = 0; k < i; k++) { 
      A.push_back(rand() % 10000); 
     } 

     // Other stuff 
    } 

있습니까? 내가 10000에서 rand()를 모자라는데 귀찮게해야합니까, 아니면 OCD 두뇌가 라운드 수를 좋아하는 것입니까? (즉, modulo 연산은 실제로 수행 할 때 고려해야 할 때 상당한 시간이 걸릴 수 있습니다. - 현재 10의 각 루프에 대해 10,000 개). 또는 실행 할 때마다 새 벡터를 실제로 만들어야합니까? 종류? 나는 생성 된 벡터가 편향되어있을 가능성이 있다고 생각했기 때문에 그렇게 해왔습니다. 그래서 그 중 하나가 생성되어 10 번 사용 되었다면 그 답은 꽤 꺼져있을 수도 있습니다 ...

+0

나는 모듈로는 난수 생성에 비해 관련 상상할 수 없습니다. 그러나 그것을 테스트하는 것은 쉽습니다. 단지 그것을 제거하고 측정하십시오. (테스트 릴리스 빌드를 수행합니까?) – sbi

+1

정렬 알고리즘 * 실제로 * 임의의 데이터를 좋아합니다. * 실제 * 데이터를 사용하여 정확한 벤치 마크를 작성하지 않습니다. –

+0

@Hans Passant 미리 만들어진 실제 데이터를 어디서 찾을 수 있는지 보여 줄 수 있습니까? 왜냐하면 내가 진짜 * 데이터를 생성하는 방법을 고려할 때 어디에서 시작해야할지 모르겠다 ... 특히 얼마나 많은 다른 유형이 있는지 상상해보십시오. (매우 선전하고 매우 혼란 스럽습니다.) 더 일반적 일 것입니다 ... – Stephen

답변

1

더 좋은 방법이 있나요?

이런 일을 빠르게하기 위해 여기에 할 일이 몇 가지 있습니다. 앞에서 언급했듯이 std :: vector에서 공간을 예약 한 다음 알려진 요소에 값을 할당하는 것이 더 빠릅니다. 또한 최적화되지 않은 컴파일러를 사용할 때 사전 증가 (++ ++ 대신 ++ var)가 빠릅니다. 코드를 빨리 작성하기 위해 누가 코드를 작성했는지에 상관없이 지금부터 코드를 작성하는 것이 좋습니다. 메모리가 간다면 사소한 것일 수도 있지만, unsigned이며 부당하게 크지 않은 알려진 크기를 사용할 때 for 루프에 unsigned short를 사용합니다.

그러나 모듈러스에 대해서. 필요하지 않으면 사용하지 않을 수도 있습니다. 벡터에 저장된 데이터 유형에 따라 형식의 최대 저장 용량을 초과하면 결과가 줄 바꿈됩니다.

변수를 처리하는 데 더 많은 처리 능력을 필요로한다면 손을 잘 모른다. 그렇다면 덜 비싼 연산이 모듈성을 수행하는지 확실하지 않다. rand를 사용하기 전에 알려진 속도로 몇 가지 속도 테스트를 실행하고 싶을 것입니다.

A.reserve(i * i); 
    for(unsigned short j = 0; j < 10; ++j) {    
     for(unsigned short k = 0; k < i; ++k) 
      A[k + (i*10)] = rand();     
     // Other stuff 
    } 

편집

아주 작은 변화주의 할 : 루프는 10 번 것입니다, 당신은뿐만 아니라 오히려 짧은보다, 부호 문자를 사용할 수 있도록. 적어도 Win32에서는 절반의 메모리가 필요합니다.내가 하나를 만들

A.reserve(i * i); 
    for(unsigned char j = 0; j < 10; ++j) {    
     for(unsigned char k = 0; k < i; ++k) 
      A[k + (i*10)] = rand();     
     // Other stuff 
    } 
+2

가독성은 성능과 상관없이 "누가 구축했는지"보다 중요합니다. 사후 증분은 20 년 전의 증분만큼 빠릅니다! –

+0

하하, 네, 맞아요. 나는 대학 시절에 내가 이것을 썼을 때, 내가 보지 못했던 컴파일러에서 마이크로 초 동안 겪었던 광기의 수준을 뒷모습에서 꽤 어리석게 보았다. 저는 스타일 론적으로 사전 증분을 선호합니다. 그것은 제 동료가하는 일입니다. 하지만 그렇습니다. 가독성/디버깅 가능성과 모든 좋은 것들에 중점을 둡니다. 스타일 기본 설정의 경우 원래 작성자가 사용한 것을 그대로 사용하거나 새 코드를 작성하는 경우 프로젝트 표준 문서를 사용하십시오. 그것은 내가 초짜에게 나에게 오늘 물었다면 나는 초심자에게 말할 것입니다. – Xoorath

1

cplusplus의 인용문.

"재 할당은 일반적으로 새 위치로 복사 할 벡터에서 사용하는 전체 저장 공간을 포함하기 때문에 성능면에서 비용이 많이 드는 작업 일 수 있습니다. 따라서, 벡터 크기가 크게 증가 할 때마다 멤버 함수 vector::reserve을 사용하여 벡터의 용량을 명시 적으로 나타내는 것이 좋습니다. "

vector::reserve을 사용하면 거의 확실하게 성능이 향상됩니다.

편집 : 당신은 그것을 한 번 작성한 당신의 벡터를 셔플 (http://www.cplusplus.com/reference/algorithm/random_shuffle/) random_shuffle를 사용하여 시도해 볼 수도 있습니다 (분명히, random_shuffle 요소의 수에 선형 적이다).

+2

처음 실행하는 동안은 거의 확실합니다. 나는 구현이 실제로 자신의 역량을 '명백하게'해산하고 있다고 생각하지 않는다. 그렇다면 스왑 트릭이 필요하지 않습니다. – sbi

+0

@sbi : 그 점을 지적 해 주셔서 고맙습니다. 당신은 절대적으로 옳습니다. 'clear()'는 벡터를 축소시키지 않으며,'shrink_to_fit()'도 분명히하지 않습니다. (http://stackoverflow.com/questions/) 2664051/why-is-shrink-to-fit-non-binding). –

0

는 살펴 :

#include <iostream> 
#include <cstdlib> 
#include <stdio.h> 
#include <time.h> 
#include <unistd.h> 
#include <sstream> 

int main(int argc, char* argv[]){ 
    if (argc < 2){ 
     printf("No arguments found\n"); 
     exit(1); 
    } 
    int maxi; 
    maxi = atoi(argv[1]); 
    int * a; 
    a = new int [5]; 

    std::stringstream ss; 
    ss << maxi; 
    printf(ss.str()); 
    printf("\n"); 
}