C#의 해시테이블보다 딕셔너리가 우선되는 이유는 무엇입니까?
대부분의 프로그래밍 언어에서는 사전이 해시 테이블보다 선호됩니다.그 배경은 무엇입니까?
사전은 (개념적으로) 해시 테이블입니다.
만약 당신이 "왜 우리는 이 시스템을 사용하는가?" " " " " " "Dictionary<TKey, TValue>
""가 "" Hashtable
라고 하면 대답할 수 있습니다.class?」라고 하는 것은, 간단한 대답입니다.Dictionary<TKey, TValue>
유형입니다.Hashtable
렇지않않 않않않다다, 하다는 뜻이죠, 안전은 안전하다는 입니다.Dictionary<TKey, TValue>
임의의 오브젝트를 삽입할 수 없기 때문에 꺼낸 값을 캐스트할 필요가 없습니다.
도, ★★★★★★★★★★★★★★★★★★★.Dictionary<TKey, TValue>
.는 NET Framework를 .Hashtable
" " " " " " 、 " " "
해시 테이블의 원본에서 일반 사전을 복사했습니다.
차이점.
Dictionary |
Hashtable |
---|---|
포괄적인 | 일반적이지 않다 |
자체 스레드 동기화 필요 | 스레드 세이프 버전부터 메서드까지 제공 |
열거된 항목: | 열거된 항목: |
최신 (>)NET 2.0) | 이전(이래)NET 1.0) |
시스템에 있습니다.컬렉션범용 | 시스템에 있습니다.컬렉션 |
존재하지 않는 키에 대한 요청이 예외를 발생시킵니다. | 존재하지 않는 키에 대한 요청이 null을 반환합니다. |
잠재적으로 가치 유형의 경우 좀 더 빠를 수 있습니다. | 값 유형의 경우 비트 저속(복싱/언박싱) |
유사점:
- 둘 다 내부 해시 테이블 == 키에 따라 여러 항목 데이터에 빠르게 액세스합니다.
- 둘 다 불변하고 고유한 키가 필요합니다.
- 두 키 모두 고유한 방법이 필요합니다.
대안.NET 컬렉션:
(Dictionary 및 Hashtable 대신 사용할 후보)
ConcurrentDictionary
- 스레드 세이프(여러 스레드에서 동시에 안전하게 액세스 가능)HybridDictionary
- 퍼포먼스 최적화 (소수품목, 다수품목)OrderedDictionary
- int 인덱스를 통해 값 접근 가능 (항목 추가 순서)SortedDictionary
- 아이템 자동 정렬StringDictionary
- 스트링용으로 강력 입력되어 최적화되어 있습니다(현재는 사전으로 권장되지 않습니다).
★★★★★★★★★★★★★★★★★★Dictionary
클래스입니다( is is ( ( (((((((((((( ) 。Dictionary<TKey, TValue>
에의 액세스는 세이프( 「유형 안전」에서 할 필요는 Object
」와 같이, 「 」를 사용해 주세요.Hashtable
를 참조해 주세요.
비교하다
var customers = new Dictionary<string, Customer>();
...
Customer customer = customers["Ali G"];
로.
var customers = new Hashtable();
...
Customer customer = customers["Ali G"] as Customer;
★★★★★★★★★★★★★★.Dictionary
는 내부적으로 해시 테이블로 구현되기 때문에 기술적으로도 동일하게 동작합니다.
.NET에서는, 「 」입니다.넷Hashtable
는 여러 및 스레드에서 입니다.는, 「리더 스레드」로, 「리더욱더욱더욱더욱더욱더욱더욱더욱더욱더욱더욱더욱더욱더욱더욱더욱.Dictionary
세이프이지만 멤버는 세이프가 .public static은 스레드 세이프가 되지 않습니다.
우리는 모든 사전을 다시 로 바꿔야 했다.Hashtable
이것 때문에.
.에서는, 의 차이.NET 、 음 net 、 음 net net netDictionary<,>
★★★★★★★★★★★★★★★★★」HashTable
주로 전자는 범용 타입이기 때문에, 정적인 타입 체크의 관점에서 제네릭스의 모든 메리트를 얻을 수 있습니다(그리고 박스를 줄였습니다만, 이것은 퍼포먼스 면에서 사람들이 생각하는 것만큼 크지 않습니다.이치노
사람들은 사전이 해시 테이블과 같다고 말한다.
이것은 반드시 사실이 아니다.해시 테이블은 사전을 구현하는 한 가지 방법입니다.일반적인 것으로, 의 디폴트인 경우도 있습니다.의 NETDictionary
하지만 그게 유일한 건 아니에요
링크된 목록이나 검색 트리를 사용하여 사전을 똑같이 구현할 수 있지만, (일부 메트릭의 경우) 효율적이지 않을 뿐입니다.
Collections
&Generics
는 오브젝트 그룹을 처리하는 데 도움이 됩니다. .NET에서는 모든 컬렉션 오브젝트는 인터페이스 아래에 있습니다.IEnumerable
에 그 ,,,가 있어요ArrayList(Index-Value))
&HashTable(Key-Value)
그 후... 2.0 프레임워크 2.0,ArrayList
&HashTable
로 대체되었다.List
&Dictionary
이제 ㅇㅇ, ㅇㅇ.Arraylist
&HashTable
현재 프로젝트에서는 더 이상 사용되지 않습니다.
HashTable
&Dictionary
,Dictionary
는 일반적입니다.Hastable
총칭하다할 수 .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);
}
}
}
MSDN의 'C#을 사용한 데이터 구조의 광범위한 검사' 기사에는 충돌 해결 전략에도 차이가 있다고 기재되어 있습니다.
해시 테이블 클래스는 리해싱이라고 불리는 기술을 사용합니다.
리해싱은 다음과 같이 동작합니다.해시마다 다른 함수의 집합이 있습니다.H1 ...Hn 및 해시 테이블에서 항목을 삽입하거나 검색할 때 처음에는 H1 해시 함수를 사용합니다.이로 인해 충돌이 발생할 경우 대신2 H가 시행되고 필요에 따라 H까지n 시행됩니다.
사전은 체인이라고 하는 기술을 사용합니다.
리허싱을 사용하면 충돌 시 해시가 재계산되고 해시에 대응하는 새로운 슬롯이 시도됩니다.그러나 체인을 사용하면 2차 데이터 구조를 사용하여 충돌을 유지합니다.특히 사전의 각 슬롯에는 해당 버킷에 매핑되는 요소 배열이 있습니다.충돌이 발생하면 충돌 요소가 버킷 목록 앞에 추가됩니다.
.NET Framework 3.5 이후로는 키만 필요하고 값이 없는 경우 의 장점을 모두 제공하는 것도 있습니다.
에 '아예'를Dictionary<MyType, object>
을항항항 the the the the and and 、 and 、 정 、 and and 、null
타입 세이프 해시 테이블을 시뮬레이트하려면 로의 전환을 검토할 필요가 있습니다.
사전:
존재하지 않는 키를 찾으려 하면 Exception이 반환 또는 throw됩니다.
박스와 언박스가 없기 때문에 해시 테이블보다 빠릅니다.
스레드 세이프가 되는 것은 퍼블릭 스태틱멤버뿐이에요
사전은 모든 데이터 유형과 함께 사용할 수 있는 범용 유형입니다(작성할 때 키와 값 모두에 대해 데이터 유형을 지정해야 함).
::
Dictionary<string, string> <NameOfDictionaryVar> = new Dictionary<string, string>();
Dictionaryay의 타입 입니다.
Keys
★★★★★★★★★★★★★★★★★」Values
강한 타입입니다.
해시 테이블:
존재하지 않는 키를 찾으려고 하면 null이 반환됩니다.
그것은 박스와 언박싱을 필요로 하기 때문에 사전보다 느리다.
해시 테이블의 모든 구성원은 스레드 세이프입니다.
해시 테이블이 일반 유형이 아닙니다.
해시 테이블은 느슨한 형식의 데이터 구조이므로 모든 유형의 키와 값을 추가할 수 있습니다.
Hashtable
의 유형의 와 값을 수.Hashtable
. 。Dictionary
세이프입니다.Hashtable
키와 값은 강하게 입력됩니다.「」를 Dictionary
★★★★★★★★★★★★★★★★★에서는 키와 값 모두에 대한 데이터 유형을 지정해야 합니다.
문서에는 다음과 같이 기재되어 있습니다."Dictionary <(TKey, TValue>) 클래스는 해시 테이블로 구현됩니다."가 아니라 "Dictionary <(TKey, TValue>) 클래스는 해시 테이블로 구현됩니다."
사전은 해시 테이블로 구현되지 않지만 해시 테이블의 개념에 따라 구현됩니다.구현은 Generics를 사용하기 때문에 HashTable 클래스와 무관하지만 Microsoft 내부에서는 동일한 코드를 사용하여 Type Object 기호를 TKey 및 TValue로 대체할 수 있습니다.
.NET 1.0에는 Generics가 존재하지 않았습니다.HashTable과 ArrayList는 여기서부터 시작되었습니다.
해시 테이블:
힙에 저장하는 동안 키/값이 개체(상자) 유형으로 변환됩니다.
힙에서 읽는 동안 키/값을 원하는 유형으로 변환해야 합니다.
이러한 작업에는 비용이 많이 듭니다.우리는 가능한 한 권투/언박스를 피해야 한다.
Dictionary : 해시테이블의 일반적인 변형입니다.
박스/언박스는 안됩니다.변환은 불필요합니다.
해시 테이블 개체는 컬렉션의 요소를 포함하는 버킷으로 구성됩니다.버킷은 해시 테이블 내의 요소의 가상 서브그룹으로 대부분의 컬렉션보다 쉽고 빠르게 검색 및 검색을 수행할 수 있습니다.
사전 클래스의 기능은 해시 테이블 클래스와 동일합니다.특정 유형의 사전(개체 제외)은 해시 테이블의 요소가 개체 유형이기 때문에 일반적으로 값 유형을 저장하거나 검색할 때 상자 및 언박스가 발생하기 때문에 값 유형의 해시 테이블보다 성능이 우수합니다.
자세한 내용은 다음을 참조하십시오.해시 테이블 및 사전 수집 유형
또 다른 중요한 차이점은 해시 테이블이 스레드 세이프하다는 것입니다.Hashtable에는 멀티 리더/싱글 라이터(MR/SW) 스레드 안전성이 내장되어 있습니다.즉, Hashtable은 잠금 없이 하나의 라이터와 여러 개의 라이터를 함께 사용할 수 있습니다.
사전의 경우 스레드 안전성이 없습니다. 스레드 안전성이 필요한 경우 자체 동기화를 구현해야 합니다.
자세한 내용은 다음과 같습니다.
은 해시 테이블을 통해 스레드 합니다.
Synchronized
property합니다.래퍼는 추가 또는 제거 작업을 수행할 때마다 전체 컬렉션을 잠그는 방식으로 작동합니다.따라서 컬렉션에 액세스하려는 각 스레드는 1개의 잠금을 받을 차례가 올 때까지 기다려야 합니다.이는 측정할 수 없으며 대규모 수집의 경우 성능이 크게 저하될 수 있습니다.또한 디자인은 레이스 조건으로부터 완전히 보호되지 않습니다.. 2.0 NET Framework 2.0을 사용합니다.
List<T>, Dictionary<TKey, TValue>
은 스레드 사용자 는 모든 .여러 스레드에서 항목이 동시에 추가 또는 삭제될 경우 사용자 코드가 모든 동기화를 제공해야 합니다.
유형 안전 및 스레드 안전이 필요한 경우 의 동시 컬렉션 클래스를 사용하십시오.NET 프레임워크자세한 내용은 이쪽.
또 다른 차이점은 딕셔너리에 여러 엔트리를 추가할 때 엔트리가 추가되는 순서가 유지된다는 것입니다.사전에서 항목을 검색할 때 삽입한 순서대로 레코드를 가져옵니다.해시 테이블은 삽입 순서를 유지하지 않습니다.
또 하나의 차이점은 다음과 같습니다.
Web 서비스에서는 Dictionary <KT,VT>(범용)를 사용할 수 없습니다.그 이유는 범용 표준을 지원하는 웹 서비스 표준이 없기 때문입니다.
Dictionary<>
이치노
HashTable에는 임의의 값 유형을 삽입할 수 있으며 이로 인해 예외가 발생할 수 있습니다. ★★★★★★★★★★★★★★★★★.Dictionary<int>
만 사용할 수 있으며 로 "정수값"도 할 수 있습니다.Dictionary<string>
을 사용하다
때문에 이렇게 하는 것이 .Dictionary<>
HashTable
.
대부분의 프로그래밍 언어에서 사전은 해시 테이블보다 선호됩니다.
나는 이것이 반드시 사실이라고 생각하지 않는다.대부분의 언어는 그들이 선호하는 용어에 따라 어느 한쪽 또는 다른 한쪽을 가지고 있다.
단, C#에서는 C# HashTables 및 시스템의 다른 멤버가 명확한 이유를 알 수 있습니다.컬렉션 네임스페이스는 대부분 사용되지 않습니다.그것들은 c# V1.1에 존재합니다.C# 2.0에서 시스템의 Generic 클래스로 대체되었습니다.컬렉션범용 네임스페이스
를 사용하여 표시되는 내용에 따라 달라집니다.NET 리플렉터:
[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을 사용하고 있는지 확인할 수 있습니다.
언급URL : https://stackoverflow.com/questions/301371/why-is-dictionary-preferred-over-hashtable-in-c
'programing' 카테고리의 다른 글
퍼스널을 사용합니다.새 워크북에 xlsb 기능이 있습니까? (0) | 2023.04.19 |
---|---|
C#을 사용하여 마지막으로 채워진 Excel 행을 프로그래밍 방식으로 가져오는 중 (0) | 2023.04.19 |
NSString이 특정 문자로 시작되는지 확인하는 방법 (0) | 2023.04.19 |
Swift: 어레이를 참조로 전달하시겠습니까? (0) | 2023.04.19 |
Mac OS 10.10+에서 GNU sed를 사용하는 방법, 'brew install --default-names'는 더 이상 지원되지 않습니다. (0) | 2023.04.19 |