STL의 hash_map

pool007의 이미지

안녕하세요. STL의 hash_map에 대한 질문을 드리고자 합니다.
SGI의 hash_map 예제를 실행해보던중 g++에서 컴파일하려면
다음과 같이 해야함을 알게 되었습니다.

#include <iostream>
#include <vector>
#include <algorithm>
#include <ext/hash_map>

using namespace std;
using namespace __gnu_cxx;

struct eqstr
{
        bool operator()(const char* s1, const char* s2) const
        {
                return strcmp(s1, s2) == 0;
        }
};

int main()
{
        hash_map<const char*, int, hash<const char*>, eqstr> months;

        months["january"] = 31;
        months["february"] = 28;
        months["march"] = 31;
        months["april"] = 30;
        months["may"] = 31;
        months["june"] = 30;
        months["july"] = 31;
        months["august"] = 31;
        months["september"] = 30;
        months["october"] = 31;
        months["november"] = 30;
        months["december"] = 31;

        cout << "september -> " << months["september"] << endl;
        cout << "april     -> " << months["april"] << endl;
        cout << "june      -> " << months["june"] << endl;
        cout << "november  -> " << months["november"] << endl;

        return EXIT_SUCCESS;
}

여기서 제가 궁금한 점은 2가지입니다.

1) namespace __gnu_cxx 는 어떤의미인가요? __gnu_cxx는 일반 extension들이 공유하는 namespace인가요? cxx의 의미를 모르겠네요.

2) hash_map, map, hashtable 간의 성능/기능 비교는 어떻게 되나요? 각자 어떤 해싱 알고리즘을 쓰는건지. 특히 hash_map과 hashtable의 구분은 모호하군요.

kewlbear의 이미지

1) cxx의 x는 +를 45도 기울인 것입니다. C++의 식별자처럼 +를 쓰지 못하는 곳에 c++대신 cxx를 사용하죠. 그러니까 __gnu_cxx는 gnu c++에서 지원되는 것이란 표시라고 보면 되겠죠.

2) 세가지 중에 map만이 표준입니다. hash_map 등은 비표준이지만 표준 map에 비해 빠른 성능을 위해 제공하는 것입니다. 자세한 성능비교는 다른 분이 해주시겠죠 ;)

익명 사용자의 이미지

kewlbear wrote:
2) 세가지 중에 map만이 표준입니다. hash_map 등은 비표준이지만 표준 map에 비해 빠른 성능을 위해 제공하는 것입니다. 자세한 성능비교는 다른 분이 해주시겠죠 ;)

제가 조금 찾아보니 stl의 map구현은 모두 레드블랙 트리인 모양이더군요. 그래서 lookup시간은 O(logN)인가 봅니다. 그리고 이것은 분명히 문제가 되는 것이라고 생각됩니다.

역시나 조금 찾아보다가 말았는데, 아마도 standard 에 hash_table이 들어가지 못한 이유는 성능이 좋은 구현이 나오지 못했기 때문인 듯합니다.

좋은 구현이 없었던 이유에 대한 제 추측은 해싱이 이상적으로는 O(1)이나 잘못되어 키가 몰리거나, 제때 resize가 되지 않으면 결국은 한 버킷에 값이 모두 몰려 O(N)이 되버리기 때문이 아닐까 생각합니다. 완전 제 추측일뿐입니다;;

정답을 알려주세요....

jyoung의 이미지

Quote:
그래서 lookup시간은 O(logN)인가 봅니다. 그리고 이것은 분명히 문제가 되는 것이라고 생각됩니다.

O(logN)이 문제가 될 정도인가요? random한 input인 경우 O(logN)은 search의 이론적인 lower bound인거 같은데..(hash같이 lookup을 위해 저장공간을 더 사용한다거나 하지 않는 한에요.. )

될대로 되라지..

pool007의 이미지

jyoung wrote:
Quote:
그래서 lookup시간은 O(logN)인가 봅니다. 그리고 이것은 분명히 문제가 되는 것이라고 생각됩니다.

O(logN)이 문제가 될 정도인가요? random한 input인 경우 O(logN)은 search의 이론적인 lower bound인거 같은데..(hash같이 lookup을 위해 저장공간을 더 사용한다거나 하지 않는 한에요.. )

제 생각에 문제는 뭔가를 넣을 때 항상 소트한다는 점 인 듯 합니다. 뉴스그룹에 물어봤더니, 당시에 C++ Standard 를 만드는데 시간이 촉박해서 넣지 못하였다고 합니다.

그러나 tr1에는 포함되어있고, hash table 추가를 위한 제안이 이루어지고 있나 봅니다.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1456.html

답변 주신분들 감사합니다.

--
Passion is like genius; a miracle.

쌀밥의 이미지

linux 머신을 사용할 수가 없어서 확인은 못해봤습니다만

제 생각에 __gnu_cxx 네임스페이스가 있는 이유는

hash_map, hashtable 등이 STL 표준이 아니기 때문에
std 에 넣지 못하고 따로 __gnu_cxx 에 들어있는 것으로 짐작됩니다.

아니라면 지적해주세요.
저도 궁금합니다.

일하는 사람들의 희망 민주노동당 : http://www.kdlp.org
반공 교육의 성과로, 민주주의의 반대가 공산주의(또는 사회주의)라고 생각하는 사람이 많다.

lifthrasiir의 이미지

쌀밥 wrote:
linux 머신을 사용할 수가 없어서 확인은 못해봤습니다만

제 생각에 __gnu_cxx 네임스페이스가 있는 이유는

hash_map, hashtable 등이 STL 표준이 아니기 때문에
std 에 넣지 못하고 따로 __gnu_cxx 에 들어있는 것으로 짐작됩니다.

아니라면 지적해주세요.
저도 궁금합니다.

sgi stl에는 hash_map 등이 그냥 std namespace에 들어 있지 않나요? 단순히 구현마다 확장을 어디다 넣을 지가 다른 것 같아 보이네요.

- 토끼군

pool007의 이미지

뉴스그룹에서 물어봤는데 해시 테이블을 위해 현재 std::tr1::unordered_map 등이 이미 존재한다는군요. 이후에는 표준이 될건가 봅니다.

그런데 tr1은 언제 std로 합쳐지는건지는 모르겠네요.. 아시는 분 좀 알려주세요.

--
Passion is like genius; a miracle.

doldori의 이미지

tokigun wrote:
sgi stl에는 hash_map 등이 그냥 std namespace에 들어 있지 않나요? 단순히 구현마다 확장을 어디다 넣을 지가 다른 것 같아 보이네요.

SGI STL은 표준 이전에 만들어졌으니 namespace를 아예 쓰지 않죠.
(정확히 말하면 global namespace)
doldori의 이미지

pool007 wrote:
그런데 tr1은 언제 std로 합쳐지는건지는 모르겠네요.. 아시는 분 좀 알려주세요.

그거야 차기 표준이 확정되는 시점 아니겠습니까?
200x년이라는 것은 거의 확실합니다. :-)
쌀밥의 이미지

SGI의 STL도 namespace를 사용합니다.
(정확히 말하면 옵션인듯..)

정확한 내용은 아래를 참고해주세요.
http://www.sgi.com/tech/stl/hash_map.h

차기 C표준이 200x년에 확정될지는 미지수라고 생각합니다.

관례로 보건데 표준안은 11년에 한번씩 정해지고 있는데
마지막으로 표준안이 정해진것이 99년이니 (C99)
2010년에 될 가능성이 높다고 생각합니다.
혹은 뒤의 두자리를 맞출수 있는 2011년에 될 수도 있을듯..

일하는 사람들의 희망 민주노동당 : http://www.kdlp.org
반공 교육의 성과로, 민주주의의 반대가 공산주의(또는 사회주의)라고 생각하는 사람이 많다.

doldori의 이미지

쌀밥 wrote:
SGI의 STL도 namespace를 사용합니다.
(정확히 말하면 옵션인듯..)

정확한 내용은 아래를 참고해주세요.
http://www.sgi.com/tech/stl/hash_map.h


그렇군요. 제가 잘못 알고 있었습니다.

쌀밥 wrote:
차기 C표준이 200x년에 확정될지는 미지수라고 생각합니다.

관례로 보건데 표준안은 11년에 한번씩 정해지고 있는데
마지막으로 표준안이 정해진것이 99년이니 (C99)
2010년에 될 가능성이 높다고 생각합니다.
혹은 뒤의 두자리를 맞출수 있는 2011년에 될 수도 있을듯..


그런 관례가 있었나요? 그럼 88년에는 무슨 일이 있었나요? -.-a
게다가 C++ 표준 개정 시점과 C99가 어떤 관련이 있는지 잘 모르겠습니다.

ps. 제가 200x년이라고 한 것은 차기 표준안을 보통 C++0x라고 부르기 때문입니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.