STL의 map 컨테이너 테스트

STL의 컨테이너 중에서 Hash 검색 알고리즘을 사용하고 있는 map 컨테이너를 테스트 해보았다. Hash 검색 알고리즘은 검색 항목의 개수에 상관없이 검색시간은 항상 일정하다라고 되어 있다. 바로 이것을 테스트해 보고자 했다.

N의 개수는 천만(10,000,000)개를 생성했으며 hash key는 unsigned long 타입으로 했다. 0, 2000000, 5000000, 7000000, 9999999 hash key 값을 검색하여 그곳에 -1을 넣었다. 과연 상수 시간이 나올 것인가? 나올 경우 시간은 얼마나 걸릴것인가…

아래는 그 결과다..


소요 시간은 분명 상수이긴 한데…. 0초다. 분명 0초는 아니겠지만 거의 0초가 걸린다. 사실 믿기지가 않는다. 아래는 테스트한 코드인데… 잘못된 부분이라도 있는건가? 옳바르다면 stl의 map 컨테이너는 정말 물건이다…

<#include 
#include <sys/timeb.h>
#include 

using namespace std;

void PerformanceTest(bool bStart, const char *szTitle="") {
    static timeb start;
    static timeb stop;

    if(bStart) {
        ftime(&start);
    } else {
        ftime(&stop);

        double gab;
        gab = 1.0e3 * difftime(stop.time, start.time);
        gab+=(double)(stop.millitm - start.millitm);

        double ReturnValue = gab/1.0e3;
        printf( "%s: %.10lf sec required.\n", szTitle, ReturnValue);
    }
}

map container_;

int _tmain(int argc, _TCHAR* argv[])
{
    PerformanceTest(true);
    for(unsigned long i=0; i<10000000; i++) {
        container_[i] = i;
    }
    PerformanceTest(false, "generating 10000000 data");

    printf("Now container has %ld items.\n\n", container_.size());

    for(size_t i=0; i<5; i++) {
        PerformanceTest(true);
        container_[0] = -1;
        PerformanceTest(false, "finding index 0:");

        PerformanceTest(true);
        container_[2000000] = -1;
        PerformanceTest(false, "finding index 2000000:");

        PerformanceTest(true);
        container_[5000000] = -1;
        PerformanceTest(false, "finding index 5000000:");

        PerformanceTest(true);
        container_[7000000] = -1;
        PerformanceTest(false, "finding index 7000000:");

        PerformanceTest(true);
        container_[10000000-1] = -1;
        PerformanceTest(false, "finding index 9999999:");
    }

    printf("\n[%ld %ld %ld %ld %ld]\n", 
        container_[0], 
        container_[2000000], 
        container_[5000000], 
        container_[7000000], 
        container_[9999999]
    );

    return 0;
}

GDI+에서 화면에 표시될 String(문자, Text)의 정확한 Width(폭) 구하기

GDI+에서 graphics의 MeasureString 함수를 통해 출력된 문자열의 폭을 구해보면 기대했던 폭 보다 다소 넓게 구해진다. MeasureString 보다 훨씬 정확한 폭을 구하는 방법에 대한 코드이다.

static public int MeasureDisplayStringWidth(Graphics graphics,
    string text, Font font)
{
    System.Drawing.StringFormat format = 
        new System.Drawing.StringFormat();

    System.Drawing.RectangleF rect = 
        new System.Drawing.RectangleF(0, 0, 1000, 1000);

    System.Drawing.CharacterRange[] ranges  = { 
        new System.Drawing.CharacterRange0,text.Length) 
    };

    System.Drawing.Region[] regions = new System.Drawing.Region[1];

    format.SetMeasurableCharacterRanges(ranges);

    regions = graphics.MeasureCharacterRanges(text, font, rect, format);
    rect = regions[0].GetBounds(graphics);

    return (int)(rect.Right + 1.0f);
}
옮겨온 곳 : Code Project, Pierre Arnaud의 글

 

참고로, 이 방법을 알기 전에는 필자는 String에 대한 Path를 만든 후, 즉 GraphicsPath를 만들고  GetBounds 매서드를 통해 크기를 얻었다. 하지만 이 방법은 MeasureString에 비해 정확하기는 하지만 역시 다소 부정확하다. 하지만 여전이 실제 프로젝트 적용에 대해서는 Path를 이용한 방법을 사용하고 있다.