게임과 같은 실시간 응용 프로그램에서 목적을 기록하는 데 종종 각 엔터티에 이름을 부여하는 데 유용합니다. 이렇게하면 고유 한 이름을 통해 엔티티를 찾는 것이 고유 한 숫자 나 다른 형태의 식별자를 보는 것보다 쉽게 오류를 추적 할 수 있습니다. 그러나 문자열은 거대하고 복사하고 비교하는 것은 느리기 때문에 성능 중요 코드에서는 종종 사용할 수 없습니다.
하나의 솔루션은 정수 일 뿐이므로 복사 및 비교하기에 빠르고 빠르게 해체 된 문자열입니다. 그러나 해시는 원래 문자열 값을 검색하는 것을 허용하지 않습니다.이 값은 로깅 및 디버깅 목적으로 정확히 필요한 것입니다! 또한 충돌 가능성이 있으므로 동일한 해시 코드가 반드시 동일한 문자열을 의미하지는 않습니다. 이 기회는 작지만 버그를 찾기 어려운 소스입니다.
또 다른 해결책은 String Interning입니다. String Interning은 각 문자열이 한 번만 저장되고 인덱스 또는 유사한 것을 통해 참조되는 전역 룩업 테이블을 사용합니다. 복사 및 비교도 빠르지 만 여전히 완벽하지는 않습니다. 런타임에만 액세스 할 수 있습니다. Compile Time에서 값을 얻는 데 대한 값을 얻는 것은 불가능합니다.
따라서 한편으로는 빠르고 가벼운 식별자를 원하지만 다른 한편으로는 이름을 되 찾는 방법도 원합니다.
This open source library provides a mix between the two solutions in the form of the class string_id . 각 객체는 해시 문자열 값과 원래 문자열 값이 저장되는 데이터베이스에 대한 포인터를 저장합니다. 이를 통해 필요할 때 문자열 값을 검색하면 해시 스트링의 성능 이점을 얻을 수 있습니다. 또한 데이터베이스는 사용자 정의 충돌 핸들러를 통해 처리 할 수있는 충돌을 감지 할 수 있습니다. Compile-Time Hashed String 값을 만들기위한 사용자 정의 리터럴이 있습니다.
데이터베이스는 특정 인터페이스 클래스에서 파생 된 사용자 정의 유형 일 수 있습니다. 몇 가지 사전 정의 된 데이터베이스가 있습니다. 여기에는 아무것도 저장하지 않는 더미 데이터베이스, 다른 데이터베이스를위한 어댑터가 포함되어 있으며,이를 효율적으로 저장하고 문자열을 검색하기위한 고도로 최적화 된 데이터베이스입니다. A typedef default_database is one of those databases and can be set via the following CMake options:
FOONATHAN_STRING_ID_DATABASE - if OFF , the database is disabled completely, eg the dummy database is used. 이렇게하면 문자열을 검색하거나 충돌 확인하는 것이 허용되지 않지만 많은 메모리가 필요하지 않습니다. It is ON by default.
FOONATHAN_STRING_ID_MULTITHREADED - if ON , database access will be synchronized via a mutex, eg the thread safe adapter will be used. 데이터베이스가 비활성화 된 경우에는 영향을 미치지 않습니다. Default value is ON .
특수 발전기 클래스가 있습니다. 표준 라이브러리의 임의 번호 생성기와 유사한 인터페이스를 가지고 있지만 문자열 식별자를 생성합니다. 이것은 자동화 된 방식으로 많은 식별자를 생성하는 데 사용됩니다. 발전기는 또한 항상 새로운 식별자가 생성되도록 조심합니다. 충돌 처리와 유사한 핸들러를 통해 제어 할 수 있습니다.
예를 들어 예제/main.cpp를 참조하십시오.
현재 FNV-1A 64 비트 해시를 사용하고 있습니다. 충돌은 정말 드물다. 나는 219,606 개의 영어 단어 (소문자)를 많은 숫자와 혼합하여 단일 충돌을 일으키지 않았다. 이것은 식별자의 일반적인 사용 사례이므로 해시 기능이 꽤 좋습니다. 또한 해시 값의 양호한 분포가 있으며 계산하기 쉽습니다.
데이터베이스는 특수 해시 테이블을 사용합니다. 버킷 인덱스의 충돌은 단일 링크 목록과 별도의 체인을 통해 해결됩니다. 각 노드에는 추가 메모리 할당없이 문자열이 직접 포함됩니다. 링크 된 목록의 노드는 해시 값을 사용하여 정렬됩니다. 이를 통해 효율적인 검색 및 동일한 해시 값이 저장된 문자열이 있는지 확인할 수 있습니다. 이를 통해 이전에 사용 된 std :: unordered_map보다 매우 효율적이고 빠릅니다 (벤치 마크에 사용한 LIBSTDC ++ 구현보다 적어도 빠릅니다).
이 라이브러리는 다음 컴파일러에 따라 컴파일되었습니다.
Constexpr, No Excrep, Override 및 Literal Operator의 호환 옵션 및 교체 Marcos가 있습니다. 원자 처리기 기능은 선택적으로 비활성화 될 수 있으며 GCC 4.6을 지원하지 않기 때문에 기본적으로 꺼져 있습니다.