대부분의 프로그래밍 언어에서 사전은 해시 테이블보다 선호됩니다. 그 이유는 무엇입니까?
질문자 :Nakul Chaudhary
가치가 있는 사전 은 (개념적으로) 해시 테이블입니다.
"왜 Hashtable
Dictionary<TKey, TValue>
클래스를 사용합니까?"를 의미했다면 쉬운 대답입니다. Dictionary<TKey, TValue>
는 제네릭 유형이고 Hashtable
은 그렇지 않습니다. 즉, 임의의 개체를 삽입할 수 없고 Dictionary<TKey, TValue>
하여 형식 안전성을 얻을 수 있습니다.
흥미롭게도 Dictionary<TKey, TValue>
구현은 소스 코드의 이 주석에서 알 수 있듯이 Hashtable
기반으로 합니다.
일반 사전은 Hashtable의 소스에서 복사되었습니다.
Michael Madsen
Dictionary
<<<>>> Hashtable
차이점:
- 일반 <<<>>> 일반이 아닌
- 자체 스레드 동기화 필요 <<<>>>
Synchronized()
메서드를 통해 스레드 안전 버전 제공 - 열거 항목:
KeyValuePair
<<<>>> 열거 항목:DictionaryEntry
- 최신(> .NET 2.0 ) <<<>>> 이전( .NET 1.0 이후)
- System.Collections.Generic <<<>>>에 있음 System.Collections에 있음
- 존재하지 않는 키에 대한 요청은 예외를 throw합니다. <<<>>> 존재하지 않는 키에 대한 요청 은 null을 반환합니다.
- 값 유형의 경우 잠재적으로 조금 더 빠름 <<<>>> 값 유형의 경우 약간 느림 (박싱/언박싱 필요)
Dictionary
/ Hashtable
유사성:
- 둘 다 내부적으로 해시 테이블 == 키에 따라 많은 항목 데이터에 빠르게 액세스
- 둘 다 변경 불가능한 고유 키가 필요합니다.
- 두 키 모두 고유한
GetHashCode()
메서드가 필요합니다.
유사한 .NET 모음(사전 및 해시 테이블 대신 사용할 후보):
-
ConcurrentDictionary
- 스레드 안전 (여러 스레드에서 동시에 안전하게 액세스할 수 있음) -
HybridDictionary
- 최적화된 성능 (몇 가지 항목 및 많은 항목에 대해) -
OrderedDictionary
- int 인덱스를 통해 값에 액세스할 수 있습니다(항목이 추가된 순서에 따라). -
SortedDictionary
- 항목 자동 정렬 -
StringDictionary
- 문자열에 대해 강력하게 형식화되고 최적화됨(지금은 Dictionary<string,string>을 위해 더 이상 사용되지 않음)
Marcel Toth
Dictionary
는 일반 클래스( Dictionary<TKey, TValue>
)이므로 해당 콘텐츠에 액세스하는 것이 형식이 안전합니다(즉 Hashtable
와 같이 Object
에서 캐스트할 필요가 없음).
비교하다
var customers = new Dictionary<string, Customer>(); ... Customer customer = customers["Ali G"];
에게
var customers = new Hashtable(); ... Customer customer = customers["Ali G"] as Customer;
그러나 Dictionary
는 내부적으로 해시 테이블로 구현되어 기술적으로 동일한 방식으로 작동합니다.
gius
참고: .NET에서 Hashtable
은 여러 판독기 스레드와 단일 쓰기 스레드에서 사용하기 Dictionary
공용 정적 멤버가 스레드로부터 안전하지만 모든 인스턴스 멤버가 스레드로부터 안전하다고 보장되지는 않습니다.
이 때문에 모든 사전을 다시 Hashtable
user38902
.NET에서 Dictionary<,>
와 HashTable
의 차이점은 주로 전자가 제네릭 유형이므로 정적 유형 검사(및 축소된 boxing) 측면에서 제네릭의 모든 이점을 얻을 수 있지만 이는 사람들은 성능 측면에서 생각하는 경향이 있습니다. 하지만 복싱에는 확실한 메모리 비용이 있습니다.
Marc Gravell
사람들은 사전이 해시 테이블과 같다고 말합니다.
이것은 반드시 사실은 아닙니다. 해시 테이블은 사전을 구현 하는 한 가지 방법입니다. Dictionary
클래스의 .NET에서 기본 것일 수 있지만 정의상 유일한 것은 아닙니다.
연결 목록이나 검색 트리를 사용하여 사전을 똑같이 잘 구현할 수 있지만 (일부 효율적인 메트릭의 경우) 효율적이지 않습니다.
rix0rrr
Collections
및 Generics
은 개체 그룹을 처리하는 데 유용합니다. .NET에서 모든 컬렉션 개체는 IEnumerable
인터페이스 아래에 있으며 이 인터페이스에는 ArrayList(Index-Value))
및 HashTable(Key-Value)
있습니다. .NET 프레임워크 2.0 이후에는 ArrayList
& HashTable
List
& Dictionary
로 대체되었습니다. 이제 Arraylist
및 HashTable
은 요즘 프로젝트에서 더 이상 사용되지 않습니다.
HashTable
과 Dictionary
의 차이점으로 인해 Dictionary
Hastable
이 Generic 이 아닌 곳에서 일반적입니다. HashTable
에 모든 유형의 객체를 추가할 수 있지만 검색하는 동안 필요한 유형으로 캐스트해야 합니다. 따라서 유형 안전하지 않습니다. 그러나 dictionary
에서는 자체적으로 선언하면서 키와 값의 유형을 지정할 수 있으므로 검색하는 동안 캐스트할 필요가 없습니다.
예를 살펴보겠습니다.
해시 테이블
class HashTableProgram { static void Main(string[] args) { Hashtable ht = new Hashtable(); ht.Add(1, "One"); ht.Add(2, "Two"); ht.Add(3, "Three"); foreach (DictionaryEntry de in ht) { int Key = (int)de.Key; //Casting string value = de.Value.ToString(); //Casting Console.WriteLine(Key + " " + value); } } }
사전,
class DictionaryProgram { static void Main(string[] args) { Dictionary<int, string> dt = new Dictionary<int, string>(); dt.Add(1, "One"); dt.Add(2, "Two"); dt.Add(3, "Three"); foreach (KeyValuePair<int, String> kv in dt) { Console.WriteLine(kv.Key + " " + kv.Value); } } }
Sujit
사전:
존재하지 않는 키를 찾으려고 하면 예외를 반환/던집니다.
boxing과 unboxing이 없기 때문에 Hashtable보다 빠릅니다.
공용 정적 멤버만 스레드로부터 안전합니다.
Dictionary는 모든 데이터 유형과 함께 사용할 수 있음을 의미하는 일반 유형입니다(생성할 때 키와 값 모두에 대한 데이터 유형을 지정해야 함).
예:
Dictionary<string, string> <NameOfDictionaryVar> = new Dictionary<string, string>();
Dictionay는 Hashtable의 유형 안전 구현이며,
Keys
와Values
은 강력한 유형입니다.
해시 테이블:
존재하지 않는 키를 찾으려고 하면 null을 반환합니다.
boxing과 unboxing이 필요하기 때문에 사전보다 느립니다.
Hashtable의 모든 멤버는 스레드로부터 안전합니다.
Hashtable은 제네릭 유형이 아닙니다.
Hashtable은 느슨한 형식의 데이터 구조이므로 모든 형식의 키와 값을 추가할 수 있습니다.
Altaf Patel
MSDN의 C# 기사를 사용하여 데이터 구조에 대한 광범위한 조사에 따르면 충돌 해결 전략 에도 차이가 있다고 명시되어 있습니다.
Hashtable 클래스는 rehashing 이라는 기술을 사용합니다.
Rehashing은 다음과 같이 작동합니다. H 1 ... H n 이라는 해시 다른 함수 집합이 있으며 해시 테이블에서 항목을 삽입하거나 검색할 때 처음에는 H 1 해시 함수가 사용됩니다. 이로 인해 충돌이 발생하면 H 2 가 대신 시도되고 필요한 경우 H n까지 계속 시도됩니다.
사전은 연결 이라고 하는 기술을 사용합니다.
재해싱을 사용하면 충돌이 발생하면 해시가 다시 계산되고 해시에 해당하는 새 슬롯이 시도됩니다. 그러나 연결을 사용하면 2차 데이터 구조가 충돌을 유지하는 데 사용됩니다 . 특히 사전의 각 슬롯에는 해당 버킷에 매핑되는 요소 배열이 있습니다. 충돌이 발생하면 충돌하는 요소가 버킷 목록 앞에 추가됩니다.
alexandrekow
.NET Framework 3.5부터는 키만 필요하고 값은 필요하지 않은 경우 Dictionary<TKey, TValue>
의 모든 장점을 제공 HashSet<T>
따라서 Dictionary<MyType, object>
하고 항상 값을 null
로 설정하여 유형 안전 해시 테이블을 시뮬레이션하는 경우 HashSet<T>
전환하는 것을 고려해야 합니다.
Oliver
Hashtable
Hashtable
에 모든 형식의 키와 값을 추가할 수 있습니다. Dictionary
클래스는 유형이 안전한 Hashtable
구현이며 키와 값은 강력한 유형입니다. Dictionary
인스턴스를 생성할 때 키와 값 모두에 대한 데이터 유형을 지정해야 합니다.
flesh
문서에 "Dictionary<(Of <(TKey, TValue>)>) 클래스는 "Dictionary<(Of <(TKey, TValue>)>) 클래스가 다음과 같이 구현되는 것이 아니라 " 해시 테이블로 구현됩니다"라고 되어 있습니다. 해시 테이블 "
Dictionary는 HashTable로 구현되지 않고, Hash Table의 개념에 따라 구현된다. 구현은 Generics를 사용하기 때문에 HashTable 클래스와 관련이 없지만 내부적으로 Microsoft는 동일한 코드를 사용하고 Object 유형의 기호를 TKey 및 TValue로 대체할 수 있었습니다.
.NET 1.0에서는 제네릭이 존재하지 않았습니다. 이것은 HashTable 및 ArrayList가 원래 시작된 곳입니다.
Brant
해시 테이블:
키/값은 힙에 저장하는 동안 객체(박싱) 유형으로 변환됩니다.
힙에서 읽는 동안 키/값을 원하는 유형으로 변환해야 합니다.
이러한 작업은 비용이 많이 듭니다. 가능한 한 boxing/unboxing을 피해야 합니다.
사전: HashTable의 일반 변형입니다.
박싱/언박싱이 없습니다. 변환이 필요하지 않습니다.
Siva Sankar Gorantla
Hashtable 객체는 컬렉션의 요소를 포함하는 버킷으로 구성됩니다. 버킷은 Hashtable 내 요소의 가상 하위 그룹으로, 대부분의 컬렉션보다 쉽고 빠르게 검색 및 검색할 수 있습니다 .
Dictionary 클래스는 Hashtable 클래스와 동일한 기능을 가지고 있습니다. 특정 유형(Object 제외)의 사전은 Hashtable의 요소가 Object 유형이므로 값 유형에 대해 Hashtable보다 성능이 더 좋으며 따라서 일반적으로 값 유형을 저장하거나 검색할 때 boxing 및 unboxing이 발생합니다.
추가 정보: 해시 테이블 및 사전 컬렉션 유형
mparkuk
또 다른 중요한 차이점은 Hashtable이 스레드로부터 안전하다는 것입니다. Hashtable에는 다중 판독기/단일 작성기(MR/SW) 스레드 안전이 내장되어 있습니다. 즉, 해시 테이블은 잠금 없이 여러 판독기와 함께 하나의 작성기를 허용합니다.
Dictionary의 경우 스레드 안전성이 없습니다. 스레드 안전성이 필요한 경우 자체 동기화를 구현해야 합니다.
더 자세히 설명하려면:
Hashtable은 컬렉션 주위에 스레드로부터 안전한 래퍼를 반환하는
Synchronized
속성을 통해 몇 가지 스레드 안전성을 제공합니다. 래퍼는 모든 추가 또는 제거 작업에서 전체 컬렉션을 잠그는 방식으로 작동합니다. 따라서 컬렉션에 액세스를 시도하는 각 스레드는 하나의 잠금을 취할 차례를 기다려야 합니다. 이는 확장할 수 없으며 대규모 컬렉션의 경우 성능이 크게 저하될 수 있습니다. 또한 디자인은 경쟁 조건으로부터 완전히 보호되지 않습니다.
List<T>, Dictionary<TKey, TValue>
등과 같은 .NET Framework 2.0 컬렉션 클래스는 스레드 동기화를 제공하지 않습니다. 사용자 코드는 항목이 여러 스레드에서 동시에 추가되거나 제거될 때 모든 동기화를 제공해야 합니다.
유형 안전성과 스레드 안전성이 필요한 경우 .NET Framework에서 동시 컬렉션 클래스를 사용하십시오. 추가 읽기 여기 .
또 다른 차이점은 사전에 여러 항목을 추가할 때 항목이 추가되는 순서가 유지된다는 것입니다. 사전에서 항목을 검색할 때 삽입한 것과 동일한 순서로 레코드를 가져옵니다. 반면 Hashtable은 삽입 순서를 유지하지 않습니다.
NullReference
내가 알아낼 수있는 또 다른 차이점은 다음과 같습니다.
웹 서비스에서는 Dictionary<KT,VT>(generics)를 사용할 수 없습니다. 그 이유는 웹 서비스 표준이 제네릭 표준을 지원하지 않기 때문입니다.
prashant
Dictionary<>
는 제네릭 형식이므로 형식이 안전합니다.
HashTable에 모든 값 유형을 삽입할 수 있으며 때때로 예외가 발생할 수 있습니다. 그러나 Dictionary<int>
는 정수 값만 허용하고 마찬가지로 Dictionary<string>
은 문자열만 허용합니다.
HashTable
대신 Dictionary<>
를 사용하는 것이 좋습니다.
Kishore Kumar
대부분의 프로그래밍 언어에서 사전은 해시 테이블보다 선호됩니다.
나는 이것이 반드시 사실이라고 생각하지 않습니다. 대부분의 언어에는 선호 하는 용어에 따라 둘 중 하나가 있습니다.
그러나 C#에서 분명한 이유는 C# HashTables 및 System.Collections 네임스페이스의 다른 구성원이 대부분 더 이상 사용되지 않기 때문입니다. 그들은 C# V1.1에 있었습니다. C# 2.0에서 System.Collections.Generic 네임스페이스의 Generic 클래스로 대체되었습니다.
kristianp
.NET Reflector 를 사용하여 본 것에 따르면 :
[Serializable, ComVisible(true)] public abstract class DictionaryBase : IDictionary, ICollection, IEnumerable { // Fields private Hashtable hashtable; // Methods protected DictionaryBase(); public void Clear(); . . . } Take note of these lines // Fields private Hashtable hashtable;
따라서 DictionaryBase가 내부적으로 HashTable을 사용하는지 확인할 수 있습니다.
Yuriy Zaletskyy
출처 : http:www.stackoverflow.com/questions/301371/why-is-dictionary-preferred-over-hashtable-in-c
'etc. > StackOverFlow' 카테고리의 다른 글
속성 값을 기준으로 객체 배열 정렬 (0) | 2022.02.17 |
---|---|
정수의 제곱근이 정수인지 확인하는 가장 빠른 방법 (0) | 2022.02.17 |
프로젝트 커밋 기록에서 삭제된 파일을 찾는 방법은 무엇입니까? (0) | 2022.02.17 |
현대 Python에서 사용자 정의 예외를 선언하는 적절한 방법은 무엇입니까? (0) | 2022.02.17 |
Python에서 stderr로 인쇄하는 방법은 무엇입니까? (0) | 2022.02.17 |