Wydajność jest prawie w 100% identyczna. Możesz to sprawdzić, otwierając klasę w Reflector.net
To jest ten indeksator:
public TValue this[TKey key]
{
get
{
int index = this.FindEntry(key);
if (index >= 0)
{
return this.entries[index].value;
}
ThrowHelper.ThrowKeyNotFoundException();
return default(TValue);
}
set
{
this.Insert(key, value, false);
}
}
A to jest metoda Add:
public void Add(TKey key, TValue value)
{
this.Insert(key, value, true);
}
Nie będę publikował całej metody Insert, ponieważ jest dość długa, jednak deklaracja metody jest taka:
private void Insert(TKey key, TValue value, bool add)
W dalszej części funkcji dzieje się tak:
if ((this.entries[i].hashCode == num) && this.comparer.Equals(this.entries[i].key, key))
{
if (add)
{
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_AddingDuplicate);
}
Który sprawdza, czy klucz już istnieje, a jeśli tak, a parametr add ma wartość true, zgłasza wyjątek.
Więc dla wszystkich celów i zamiarów wydajność jest taka sama.
Podobnie jak kilka innych wzmianek, wszystko zależy od tego, czy potrzebujesz czeku, aby spróbować dwukrotnie dodać ten sam klucz.
Przepraszam za długi post, mam nadzieję, że wszystko w porządku.
Pierwsza wersja doda nową KeyValuePair do słownika, zgłaszając, czy klucz jest już w słowniku. Drugi, używając indeksatora, doda nową parę, jeśli klucz nie istnieje, ale nadpisze wartość klucza, jeśli już istnieje w słowniku.
źródło
Dictionary.Add(key, value)
iDictionary[key] = value
mają różne cele:Add
metody, aby dodać nową parę klucz / wartość, istniejące klucze nie zostaną zastąpione (ArgumentException
zostanie wyrzucony).źródło
Aby odpowiedzieć na to pytanie, najpierw musimy przyjrzeć się celowi słownika i związanej z nim technologii.
Dictionary
to lista miejsc, wKeyValuePair<Tkey, Tvalue>
których każda wartość jest reprezentowana przez swój unikalny klucz. Powiedzmy, że mamy listę Twoich ulubionych potraw. Każda wartość (nazwa potrawy) jest reprezentowana przez swój unikalny klucz (pozycja = jak bardzo lubisz to jedzenie).Przykładowy kod:
Powiedzmy, że chcesz zachować zdrowie, zmieniłeś zdanie i chcesz zastąpić swojego ulubionego „burgera” sałatką. Twoja lista jest nadal listą ulubionych, nie zmienisz charakteru listy. Twój ulubiony pozostanie numerem jeden na liście, tylko jego wartość ulegnie zmianie. To wtedy nazywasz to:
Ale nie zapominaj, że jesteś programistą i od teraz kończysz swoje zdania; odmawiasz używania emoji, ponieważ zgłaszałyby one błąd kompilacji, a cała lista ulubionych jest oparta na indeksie 0.
Twoja dieta też się zmieniła! Więc ponownie zmieniasz listę:
Istnieją dwie możliwości definiowania: albo chcesz podać nową definicję czegoś, co wcześniej nie istniało, albo chcesz zmienić definicję, która już istnieje.
Add umożliwia dodanie rekordu, ale tylko pod jednym warunkiem: klucz dla tej definicji może nie istnieć w Twoim słowniku.
Teraz zajrzymy pod maskę. Kiedy tworzysz słownik, twój kompilator dokonuje rezerwacji dla zasobnika (spacje w pamięci do przechowywania twoich rekordów). Zasobnik nie przechowuje kluczy w sposób, w jaki je definiujesz. Każdy klucz jest haszowany przed przejściem do zasobnika (zdefiniowanego przez Microsoft), warto wspomnieć, że część wartości pozostaje niezmieniona.
Użyję algorytmu mieszania CRC32, aby uprościć mój przykład. Podczas definiowania:
Do wiadra trafia db2dc565 „Pizza” (uproszczona).
Gdy zmienisz wartość w:
Haszujesz swoje 0, które ponownie jest db2dc565, a następnie sprawdzasz tę wartość w swoim zasobniku , aby sprawdzić, czy tam jest. Jeśli tam jest, po prostu przepisujesz wartość przypisaną do klucza. Jeśli go tam nie ma, umieścisz swoją wartość w wiadrze.
Podczas wywoływania funkcji Dodaj w słowniku, na przykład:
Haszujesz swoje 0, aby porównać jego wartość z wartościami w zasobniku. Możesz umieścić go w wiadrze tylko wtedy, gdy go tam nie ma .
Ważne jest, aby wiedzieć, jak to działa, zwłaszcza jeśli pracujesz ze słownikami kluczy typu string lub char. W związku z haszowaniem rozróżniana jest wielkość liter. Na przykład „imię”! = „Imię”. Użyjmy naszego CRC32, aby to zobrazować.
Wartość dla „nazwy” to: e04112b1 Wartość dla „nazwy” to: 1107fb5b
źródło
Tak, na tym polega różnica, metoda Add zgłasza wyjątek, jeśli klucz już istnieje.
Powód użycia metody Add jest dokładnie taki. Jeśli słownik nie powinien już zawierać klucza, zwykle potrzebujesz wyjątku, abyś był świadomy problemu.
źródło
Biorąc pod uwagę najbardziej prawdopodobne podobieństwa w wydajności, użyj tego, co wydaje się bardziej poprawne i czytelne dla używanego fragmentu kodu.
Wydaje mi się, że operacja opisująca dodatek, będąca obecnością klucza, który jest już naprawdę rzadkim wyjątkiem, najlepiej reprezentuje dodatek. Semantycznie ma to większy sens.
dict[key] = value
Oznacza lepsze zmiany. Jeśli widzę ten kod, w połowie spodziewam się, że klucz i tak jest już w słowniku.źródło
dic[key] = value
tym, że klucz był już obecny, ale myślę, że to dyskusyjne;)Jeden przypisuje wartość, a drugi dodaje do słownika nowy klucz i wartość.
źródło
Aby wstawić wartość do słownika
źródło