Daha etkili olan nedir: Dictionary TryGetValue or ContainsKey + Item?


252

MSDN'nin Dictionary.TryGetValue Yöntemi üzerindeki girişinden :

Bu yöntem ContainsKey yönteminin ve Item özelliğinin işlevselliğini birleştirir.

Anahtar bulunmazsa, value parametresi TValue değer türü için uygun varsayılan değeri alır; örneğin, tamsayı türleri için 0 (sıfır), Boole türleri için false ve referans türleri için null.

Kodunuz sık sık sözlükte olmayan anahtarlara erişmeye çalışırsa TryGetValue yöntemini kullanın. Bu yöntemi kullanmak, Item özelliği tarafından atılan KeyNotFoundException yakalamak daha etkilidir.

Bu yöntem bir O (1) işlemine yaklaşır.

Açıklamadan, ContainsKey'i aramaktan ve daha sonra aramayı yapmaktan daha verimli veya daha uygun olup olmadığı açık değildir. TryGetValueSadece ContainsKey ve sonra Item çağrısı uygulanması veya aslında tek bir arama yaparak bundan daha verimli midir?

Başka bir deyişle, daha verimli olan nedir (yani hangisi daha az arama yapar):

Dictionary<int,int> dict;
//...//
int ival;
if(dict.ContainsKey(ikey))
{
  ival = dict[ikey];
}
else
{
  ival = default(int);
}

veya

Dictionary<int,int> dict;
//...//
int ival;
dict.TryGetValue(ikey, out ival);

Not: Bir kıyaslama aramıyorum!

Yanıtlar:


314

TryGetValue daha hızlı olacak.

ContainsKeyTryGetValuedahili olarak gerçek giriş konumuna atıfta bulunanla aynı kontrolü kullanır . ItemMülkiyet aslında neredeyse özdeş kod işlevselliğe sahip TryGetValuebu false dönen yerine bir istisna durumu dışında.

Kullanma ContainsKeyardından Itemtemelde bu durumda hesaplama toplu olan arama işlevselliğini çoğaltır.


2
Bu daha ince olduğunu: if(dict.ContainsKey(ikey)) dict[ikey]++; else dict.Add(ikey, 0);. Ama TryGetValueget ve indexer özelliği kümesi kullanıldığından bu hala daha verimli olduğunu düşünüyorum , değil mi?
Tim Schmelter

4
aslında bunun için .net kaynağına da bakabilirsiniz: referenceource.microsoft.com/#mscorlib/system/collections/… 3 TryGetValue, ContainsKey yönteminin üçünün de aynı FindEntry yöntemini çağırdığını ve aynı miktarda çalışma, yalnızca soruya nasıl cevap verdiklerine göre farklılık gösterir: trygetvalue döndürür bool ve değer, anahtar içerir yalnızca true / false döndürür ve bu [] değeri döndürür veya bir istisna atar.
John Gardner

1
@JohnGardner Evet, ben de bunu söyledim - ama eğer ContainsKey yaparsanız Öğe kazanırsanız, bu işi 1x yerine 2x yapıyorsunuz.
Reed Copsey

3
tamamen katılıyorum :) ben sadece gerçek kaynak şimdi kullanılabilir olduğunu işaret ediyordu. diğer cevapların / vb. hiçbirinin gerçek kaynağa bir bağlantısı yoktu: D
John Gardner

1
Biraz konu dışı, çok iş parçacıklı bir ortamda bir IDictionary yoluyla erişiyorsanız, her zaman TryGetValue'yu kullanırım çünkü ContainsKey'i çağırdığınız andan itibaren durum değişebilir (TryGetValue'nun dahili olarak doğru bir şekilde kilitleneceğinin garantisi yoktur, ancak muhtemelen daha güvenlidir)
Chris Berry

91

Hızlı bir karşılaştırma, TryGetValuehafif bir kenara sahip olduğunu gösterir :

    static void Main() {
        var d = new Dictionary<string, string> {{"a", "b"}};
        var start = DateTime.Now;
        for (int i = 0; i != 10000000; i++) {
            string x;
            if (!d.TryGetValue("a", out x)) throw new ApplicationException("Oops");
            if (d.TryGetValue("b", out x)) throw new ApplicationException("Oops");
        }
        Console.WriteLine(DateTime.Now-start);
        start = DateTime.Now;
        for (int i = 0; i != 10000000; i++) {
            string x;
            if (d.ContainsKey("a")) {
                x = d["a"];
            } else {
                x = default(string);
            }
            if (d.ContainsKey("b")) {
                x = d["b"];
            } else {
                x = default(string);
            }
        }
   }

Bu üretir

00:00:00.7600000
00:00:01.0610000

ContainsKey + Itemerişimin ve isabetlerin eşit bir karışımını varsayarak erişimi yaklaşık% 40 daha yavaş hale getirir .

Dahası, programı her zaman kaçırmak (yani her zaman aramak "b") için değiştirdiğimde, iki sürüm eşit derecede hızlı olur:

00:00:00.2850000
00:00:00.2720000

Ancak, "tüm hit" yaptığımda, TryGetValueaçık bir kazanan kalır:

00:00:00.4930000
00:00:00.8110000

11
Tabii ki, gerçek kullanım modeline bağlıdır. Eğer neredeyse hiç aramayı başaramazsanız, o TryGetValuezaman çok önde olmalısınız. Ayrıca ... bir nitpick ... DateTimeperformans ölçümlerini yakalamanın en iyi yolu değildir.
Ed S.

4
@EdS. Haklısın, TryGetValuedaha da ileri gidiyor. Cevabı "tüm isabetler" ve "tüm isabetsizlikler" senaryolarını içerecek şekilde düzenledim.
dasblinkenlight

2
Eğer nasıl kullandığını açıklamak @Luciano Any- Şunun gibi: Any(i=>i.Key==key). Bu durumda, evet, bu sözlükte kötü bir doğrusal aramadır.
weston

13
DateTime.Nowyalnızca birkaç ms'ye kadar doğru olacaktır. Kullanım Stopwatchsınıfı System.Diagnostics(çok daha yüksek doğruluk sağlamak için yorganın altında QueryPerformanceCounter kullanır) yerine. Kullanımı da daha kolay.
Alastair Maw

5
Alastair ve Ed'in yorumlarına ek olarak - DateTime.Şimdi, kullanıcı bilgisayar saatini güncellediğinde, bir saat dilimi geçtiğinde veya saat dilimi değiştiğinde (DST, örneği). Sistem saatinin GPS veya cep telefonu şebekeleri gibi bazı radyo servisleri tarafından sağlanan zamanla senkronize edildiği bir sistem üzerinde çalışmayı deneyin. DateTime.Now her yere gidecek ve DateTime.UtcNow bu nedenlerden yalnızca birini düzeltir. Sadece StopWatch'u kullanın.
antiduh

51

Şimdiye kadar cevapların hiçbiri soruyu gerçekten cevaplamadığından, bazı araştırmalardan sonra bulduğum kabul edilebilir bir cevap:

TryGetValue'yu kodalıyorsanız, bunun yapıldığını görürsünüz:

public bool TryGetValue(TKey key, out TValue value)
{
  int index = this.FindEntry(key);
  if (index >= 0)
  {
    value = this.entries[index].value;
    return true;
  }
  value = default(TValue);
  return false;
}

oysa ContainsKey yöntemi:

public bool ContainsKey(TKey key)
{
  return (this.FindEntry(key) >= 0);
}

yani TryGetValue sadece ContainsKey artı öğe varsa bir dizi arama.

Kaynak

TryGetValue, ContainsKey + Item kombinasyonundan neredeyse iki kat daha hızlı olacak gibi görünüyor.


20

Kimin umrunda :-)

Muhtemelen soruyorsunuz çünkü TryGetValuekullanılacak bir acıdır - bu yüzden bunu bir uzatma yöntemiyle kapsülleyin.

public static class CollectionUtils
{
    // my original method
    // public static V GetValueOrDefault<K, V>(this Dictionary<K, V> dic, K key)
    // {
    //    V ret;
    //    bool found = dic.TryGetValue(key, out ret);
    //    if (found)
    //    {
    //        return ret;
    //    }
    //    return default(V);
    // }


    // EDIT: one of many possible improved versions
    public static TValue GetValueOrDefault<K, V>(this IDictionary<K, V> dictionary, K key)
    {
        // initialized to default value (such as 0 or null depending upon type of TValue)
        TValue value;  

        // attempt to get the value of the key from the dictionary
        dictionary.TryGetValue(key, out value);
        return value;
    }

O zaman arayın:

dict.GetValueOrDefault("keyname")

veya

(dict.GetValueOrDefault("keyname") ?? fallbackValue) 

1
@ Hüseyin Bunu olmadan göndermek için yeterince aptal olduğum için çok şaşkın oldum thisama yöntemimin kod tabanımda iki kez çoğaltıldığı ortaya çıktı - bir kez ve bir tane olmadan, thisbu yüzden hiç yakalamadım! düzelttiğiniz için teşekkürler!
Simon_Weaver

2
TryGetValueanahtar yoksa, out value parametresine varsayılan bir değer atar, bu nedenle bu basitleştirilebilir.
Raphael Smit

2
Basitleştirilmiş sürüm: public static TValue GetValueOrDefault <TKey, TValue> (bu sözlük <TKey, TValue> dict, TKey key) {TValue ret; dict.TryGetValue (anahtar, çıkış ret); geri dönüş; }
Joshua

2
C # 7'de bu gerçekten eğlenceli:if(!dic.TryGetValue(key, out value item)) item = dic[key] = new Item();
Shimmy Weitzhandler

1
İronik bir şekilde, gerçek kaynak kodunda zaten bir GetValueOrDefault () rutini var, ancak gizli ... referenceource.microsoft.com/#mscorlib/system/collections/…
Deven T. Corzine

10

Neden test etmiyorsun?

Ama bunun TryGetValuedaha hızlı olduğuna eminim , çünkü sadece bir arama yapıyor. Elbette bu garanti edilmez, yani farklı uygulamalar farklı performans özelliklerine sahip olabilir.

Bir sözlüğü uygulama Findşeklim, bir öğenin yuvasını bulan dahili bir işlev oluşturmak ve gerisini bunun üzerine inşa etmektir.


Uygulama ayrıntılarının, X eylemini bir kez gerçekleştirmenin X eylemini iki kez yapmaya eşit veya daha hızlı olduğu garantisini değiştirebileceğini düşünmüyorum. En iyi durum aynı, daha kötü durum 2X sürümü iki kat daha uzun sürüyor.
Dan Bechard

9

Şimdiye kadar tüm cevaplar, iyi olmasına rağmen, hayati bir noktayı kaçırıyor.

Bir API sınıfına (ör. .NET framework) yönelik yöntemler bir arayüz tanımının bir parçasını oluşturur (C # veya VB arayüzü değil, bilgisayar bilimi anlamında bir arayüz).

Bu nedenle, hız resmi arabirim tanımının (bu durumda olmadığı) bir parçası olmadığı sürece, böyle bir yöntemi çağırmanın daha hızlı olup olmadığını sormak genellikle yanlıştır.

Geleneksel olarak bu tür bir kısayol, dil, altyapı, işletim sistemi, platform veya makine mimarisine bakılmaksızın daha verimlidir. Ayrıca daha okunabilirdir, çünkü niyetinizi (kodunuzun yapısından) ima etmek yerine açıkça ifade eder.

Bu nedenle (grizzled eski bir kesmek) kesinlikle 'Evet' (TryGetValue bir sözlükten bir değer almak için ContainsKey ve Item [Get] birleşimi tercih edilir).

Bunun kulağa tuhaf geldiğini düşünüyorsanız, şöyle düşünün: TryGetValue, ContainsKey ve Item [Get] 'in güncel uygulamaları herhangi bir hız farkı vermese bile, gelecekteki bir uygulamanın (örn. .NET v5) olası olduğunu varsayabilirsiniz. (TryGetValue daha hızlı olacaktır). Yazılımınızın ömrünü düşünün.

Bir yana, tipik modern arayüz tanımlama teknolojilerinin nadiren zamanlama kısıtlamalarını resmi olarak tanımlamak için herhangi bir yol sağladığını belirtmek ilginçtir. Belki .NET v5?


2
Ben% 100 anlambilim hakkındaki argümanınıza katılırken, yine de performans testi yapmaya değer. Test yaptığınız sürece, semantik olarak doğru olan şeyin daha yavaş olacağı şekilde kullandığınız API'nın ne zaman bir yetersiz uygulaması olduğunu asla bilemezsiniz.
Dan Bechard

5

Hızlı bir test programı yapmak, TryGetValue kullanarak sözlükte 1 milyon öğe ile kesinlikle bir gelişme var.

Sonuçlar:

İçeriği 1000000 sonuç için Anahtar + Ürün: 45ms

1000000 sonuç için TryGetValue: 26ms

İşte test uygulaması:

static void Main(string[] args)
{
    const int size = 1000000;

    var dict = new Dictionary<int, string>();

    for (int i = 0; i < size; i++)
    {
        dict.Add(i, i.ToString());
    }

    var sw = new Stopwatch();
    string result;

    sw.Start();

    for (int i = 0; i < size; i++)
    {
        if (dict.ContainsKey(i))
            result = dict[i];
    }

    sw.Stop();
    Console.WriteLine("ContainsKey + Item for {0} hits: {1}ms", size, sw.ElapsedMilliseconds);

    sw.Reset();
    sw.Start();

    for (int i = 0; i < size; i++)
    {
        dict.TryGetValue(i, out result);
    }

    sw.Stop();
    Console.WriteLine("TryGetValue for {0} hits: {1}ms", size, sw.ElapsedMilliseconds);

}

5

Makinemde, bir sürü RAM ile, RELEASE modunda (DEBUG değil) çalıştırıldığında, tüm girişler bulunursa / ContainsKeydeğerine eşittir .TryGetValuetry-catchDictionary<>

ContainsKeysadece birkaç sözlük girişi bulunmadığında bunların hepsinden daha iyi performans gösterir (aşağıdaki örneğimde, bazı girişlerin kaçırılmasından MAXVALdaha büyük bir değere ayarlayın ENTRIES):

Sonuçlar:

Finished evaluation .... Time distribution:
Size: 000010: TryGetValue: 53,24%, ContainsKey: 1,74%, try-catch: 45,01% - Total: 2.006,00
Size: 000020: TryGetValue: 37,66%, ContainsKey: 0,53%, try-catch: 61,81% - Total: 2.443,00
Size: 000040: TryGetValue: 22,02%, ContainsKey: 0,73%, try-catch: 77,25% - Total: 7.147,00
Size: 000080: TryGetValue: 31,46%, ContainsKey: 0,42%, try-catch: 68,12% - Total: 17.793,00
Size: 000160: TryGetValue: 33,66%, ContainsKey: 0,37%, try-catch: 65,97% - Total: 36.840,00
Size: 000320: TryGetValue: 34,53%, ContainsKey: 0,39%, try-catch: 65,09% - Total: 71.059,00
Size: 000640: TryGetValue: 32,91%, ContainsKey: 0,32%, try-catch: 66,77% - Total: 141.789,00
Size: 001280: TryGetValue: 39,02%, ContainsKey: 0,35%, try-catch: 60,64% - Total: 244.657,00
Size: 002560: TryGetValue: 35,48%, ContainsKey: 0,19%, try-catch: 64,33% - Total: 420.121,00
Size: 005120: TryGetValue: 43,41%, ContainsKey: 0,24%, try-catch: 56,34% - Total: 625.969,00
Size: 010240: TryGetValue: 29,64%, ContainsKey: 0,61%, try-catch: 69,75% - Total: 1.197.242,00
Size: 020480: TryGetValue: 35,14%, ContainsKey: 0,53%, try-catch: 64,33% - Total: 2.405.821,00
Size: 040960: TryGetValue: 37,28%, ContainsKey: 0,24%, try-catch: 62,48% - Total: 4.200.839,00
Size: 081920: TryGetValue: 29,68%, ContainsKey: 0,54%, try-catch: 69,77% - Total: 8.980.230,00

İşte benim kod:

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;

    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                const int ENTRIES = 10000, MAXVAL = 15000, TRIALS = 100000, MULTIPLIER = 2;
                Dictionary<int, int> values = new Dictionary<int, int>();
                Random r = new Random();
                int[] lookups = new int[TRIALS];
                int val;
                List<Tuple<long, long, long>> durations = new List<Tuple<long, long, long>>(8);

                for (int i = 0;i < ENTRIES;++i) try
                    {
                        values.Add(r.Next(MAXVAL), r.Next());
                    }
                    catch { --i; }

                for (int i = 0;i < TRIALS;++i) lookups[i] = r.Next(MAXVAL);

                Stopwatch sw = new Stopwatch();
                ConsoleColor bu = Console.ForegroundColor;

                for (int size = 10;size <= TRIALS;size *= MULTIPLIER)
                {
                    long a, b, c;

                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine("Loop size: {0}", size);
                    Console.ForegroundColor = bu;

                    // ---------------------------------------------------------------------
                    sw.Start();
                    for (int i = 0;i < size;++i) values.TryGetValue(lookups[i], out val);
                    sw.Stop();
                    Console.WriteLine("TryGetValue: {0}", a = sw.ElapsedTicks);

                    // ---------------------------------------------------------------------
                    sw.Restart();
                    for (int i = 0;i < size;++i) val = values.ContainsKey(lookups[i]) ? values[lookups[i]] : default(int);
                    sw.Stop();
                    Console.WriteLine("ContainsKey: {0}", b = sw.ElapsedTicks);

                    // ---------------------------------------------------------------------
                    sw.Restart();
                    for (int i = 0;i < size;++i)
                        try { val = values[lookups[i]]; }
                        catch { }
                    sw.Stop();
                    Console.WriteLine("try-catch: {0}", c = sw.ElapsedTicks);

                    // ---------------------------------------------------------------------
                    Console.WriteLine();

                    durations.Add(new Tuple<long, long, long>(a, b, c));
                }

                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("Finished evaluation .... Time distribution:");
                Console.ForegroundColor = bu;

                val = 10;
                foreach (Tuple<long, long, long> d in durations)
                {
                    long sum = d.Item1 + d.Item2 + d.Item3;

                    Console.WriteLine("Size: {0:D6}:", val);
                    Console.WriteLine("TryGetValue: {0:P2}, ContainsKey: {1:P2}, try-catch: {2:P2} - Total: {3:N}", (decimal)d.Item1 / sum, (decimal)d.Item2 / sum, (decimal)d.Item3 / sum, sum);
                    val *= MULTIPLIER;
                }

                Console.WriteLine();
            }
        }
    }

Burada balık gibi bir şey oluyormuş gibi hissediyorum. Acaba alınan değeri hiç kullanmamanız nedeniyle optimize edicinin ContainsKey () kontrollerinizi kaldırıyor veya basitleştiriyor olabileceğini merak ediyorum.
Dan Bechard

Sadece yapamaz. ContainsKey (), derlenmiş bir DLL dosyasındadır. Optimizer, ContainsKey () 'in gerçekte ne yaptığı hakkında hiçbir şey bilmiyor. Yan etkilere neden olabilir, bu nedenle çağrılmalıdır ve kısaltılamaz.
AxD

Burada bir şey sahte. Gerçek şu ki, .NET kodunun incelenmesi ContainsKey, TryGetValue ve bunun [] hepsinin aynı dahili kodu çağırdığını gösterir, bu nedenle giriş olduğunda TryGetValue ContainsKey + this [] 'den daha hızlıdır.
Jim Balter

3

Pratik bir ortamda doğru sonuçlar verecek bir mikrobenchmark tasarlamanın yanı sıra, .NET Framework'ün referans kaynağını da inceleyebilirsiniz.

Hepsi FindEntry(TKey)işin çoğunu yapan ve sonucunu hatırlamayan yöntemi çağırır , bu nedenle arama TryGetValueneredeyse ContainsKey+ 'dan iki kat daha hızlıdırItem .


Uygunsuz arayüzü TryGetValueedilebilir bir uzantısı yöntemi kullanılarak adapte :

using System.Collections.Generic;

namespace Project.Common.Extensions
{
    public static class DictionaryExtensions
    {
        public static TValue GetValueOrDefault<TKey, TValue>(
            this IDictionary<TKey, TValue> dictionary,
            TKey key,
            TValue defaultValue = default(TValue))
        {
            if (dictionary.TryGetValue(key, out TValue value))
            {
                return value;
            }
            return defaultValue;
        }
    }
}

C # 7.1'den beri, default(TValue)düz ile değiştirebilirsiniz default. Tür çıkarılır.

Kullanımı:

var dict = new Dictionary<string, string>();
string val = dict.GetValueOrDefault("theKey", "value used if theKey is not found in dict");

nullAçık bir varsayılan değer belirtilmedikçe, araması başarısız olan referans türleri için döner .

var dictObj = new Dictionary<string, object>();
object valObj = dictObj.GetValueOrDefault("nonexistent");
Debug.Assert(valObj == null);

val dictInt = new Dictionary<string, int>();
int valInt = dictInt.GetValueOrDefault("nonexistent");
Debug.Assert(valInt == 0);

Uzantı yönteminin kullanıcılarının, var olmayan bir anahtar ile var olan bir anahtar arasındaki farkı söyleyemediğini, ancak değerinin varsayılan (T) olduğunu unutmayın.
Lucas

Modern bir bilgisayarda, bir altyordamı art arda iki kez çağırırsanız, bir kez çağırmanın iki katını alması olası değildir. Bunun nedeni, CPU ve önbellek mimarisinin ilk çağrı ile ilişkili birçok talimatı ve veriyi önbelleğe almasıdır, bu nedenle ikinci çağrı daha hızlı yürütülecektir. Öte yandan, iki kez aramanın bir kez aramaktan biraz daha uzun sürmesi neredeyse kesindir, bu nedenle mümkünse ikinci aramayı ortadan kaldırmanın bir avantajı vardır.
debater

2

Sözlüğü değerden çıkarmaya çalışıyorsanız, TryGetValue (anahtar, çıkış değeri) en iyi seçenektir, ancak anahtarın varlığını kontrol ediyorsanız, yeni bir ekleme için eski anahtarların üzerine yazmadan, ve sadece bu kapsamda, ContainsKey (anahtar) en iyi seçenektir, kıyaslama bunu onaylayabilir:

using System;
using System.Threading;
using System.Diagnostics;
using System.Collections.Generic;
using System.Collections;

namespace benchmark
{
class Program
{
    public static Random m_Rand = new Random();
    public static Dictionary<int, int> testdict = new Dictionary<int, int>();
    public static Hashtable testhash = new Hashtable();

    public static void Main(string[] args)
    {
        Console.WriteLine("Adding elements into hashtable...");
        Stopwatch watch = Stopwatch.StartNew();
        for(int i=0; i<1000000; i++)
            testhash[i]=m_Rand.Next();
        watch.Stop();
        Console.WriteLine("Done in {0:F4} -- pause....", watch.Elapsed.TotalSeconds);
        Thread.Sleep(4000);
        Console.WriteLine("Adding elements into dictionary...");
        watch = Stopwatch.StartNew();
        for(int i=0; i<1000000; i++)
            testdict[i]=m_Rand.Next();
        watch.Stop();
        Console.WriteLine("Done in {0:F4} -- pause....", watch.Elapsed.TotalSeconds);
        Thread.Sleep(4000);

        Console.WriteLine("Finding the first free number for insertion");
        Console.WriteLine("First method: ContainsKey");
        watch = Stopwatch.StartNew();
        int intero=0;
        while (testdict.ContainsKey(intero))
        {
            intero++;
        }
        testdict.Add(intero, m_Rand.Next());
        watch.Stop();
        Console.WriteLine("Done in {0:F4} -- added value {1} in dictionary -- pause....", watch.Elapsed.TotalSeconds, intero);
        Thread.Sleep(4000);
        Console.WriteLine("Second method: TryGetValue");
        watch = Stopwatch.StartNew();
        intero=0;
        int result=0;
        while(testdict.TryGetValue(intero, out result))
        {
            intero++;
        }
        testdict.Add(intero, m_Rand.Next());
        watch.Stop();
        Console.WriteLine("Done in {0:F4} -- added value {1} in dictionary -- pause....", watch.Elapsed.TotalSeconds, intero);
        Thread.Sleep(4000);
        Console.WriteLine("Test hashtable");
        watch = Stopwatch.StartNew();
        intero=0;
        while(testhash.Contains(intero))
        {
            intero++;
        }
        testhash.Add(intero, m_Rand.Next());
        watch.Stop();
        Console.WriteLine("Done in {0:F4} -- added value {1} into hashtable -- pause....", watch.Elapsed.TotalSeconds, intero);
        Console.Write("Press any key to continue . . . ");
        Console.ReadKey(true);
    }
}
}

Bu gerçek bir örnektir, oluşturulan her "Öğe" için aşamalı bir sayı ilişkilendiren bir hizmetim var, bu sayı, her yeni öğe oluşturduğunuzda ücretsiz bulunmalıdır, bir Öğeyi silerseniz, ücretsiz numara olur ücretsiz, elbette bu optimize edilmemiştir, çünkü geçerli sayıyı önbelleğe alan statik bir değişkenim var, ancak tüm sayıları bitirmeniz durumunda 0'dan UInt32.MaxValue'ya yeniden başlayabilirsiniz.

İdam Testi:
hashtable içine ekleme elemanları ...
0,5908 Tamamlandı - duraklama ....
sözlüğüne unsurları ekleniyor ...
.... duraklama - 0,2679 Tamamlandı
yerleştirme için ilk serbest numara bulma
İlk yöntemde : ContainsKey
0,0561 Tamamlandı - Sözlük değeri 1000000 eklenen - duraklama ....
İkinci yöntem: TryGetValue
0,0643 Tamamlandı - Sözlük değeri 1.000.001 eklenen - duraklama ....
test hashtable
0 olarak hazırlanmış 3015 - hashtable - pause içine 1000000 değeri eklendi .... Devam
etmek için herhangi bir tuşa basın. .

Bazılarınız ContainsKeys bir avantajı olup olmadığını soruyor olabilir, hatta TryGetValue ile Contains anahtarını ters çevirmeye çalıştım, sonuç aynı.

Yani, benim için, son bir değerlendirme ile, hepsi programın davranış şekline bağlıdır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.