হ্যাশসেট <টি> বনাম অভিধান <কে, ভি> আর্ট অনুসন্ধানের সময় কোনও আইটেমের উপস্থিতি আছে কিনা তা খুঁজে পাওয়ার জন্য


103
HashSet<T> t = new HashSet<T>();
// add 10 million items


Dictionary<K, V> t = new Dictionary<K, V>();
// add 10 million items.

কার .Containsপদ্ধতিটি দ্রুত ফিরে আসবে?

কেবল স্পষ্ট করে বলার জন্য, আমার প্রয়োজনীয়তা হল আমার কাছে 10 মিলিয়ন অবজেক্ট রয়েছে (ভাল, স্ট্রিংগুলি সত্যই) যা আমার ডেটা স্ট্রাকচারে বিদ্যমান আছে কিনা তা খতিয়ে দেখা উচিত। আমি কখনও পুনরাবৃত্তি করব না।


1
পদক্ষেপ 1: দেখুন উভয়ই একই কাজ করে কিনা (এই ক্ষেত্রে, দুটি সংগ্রহ বিভিন্ন উদ্দেশ্যে হয়) পদক্ষেপ 2: নথিপত্র পড়ুন এবং দেখুন যে আপনি তাদের অ্যাসিপোটোটিক জটিলতা সম্পর্কে ভাল লাগছেন কিনা। পদক্ষেপ 3: আপনার যদি মনে হয় যে আপনাকে আরও চিন্তিত হওয়া দরকার, নিজেকে মাপুন এবং তারপরে বেনমার্কটি পোস্ট করার সাথে প্রশ্নটি জিজ্ঞাসা করুন। আপনার ক্ষেত্রে প্রশ্নটি প্রথম ধাপে অর্থহীন হয়ে যায়।
নওফাল

উত্তর:


153

হ্যাশসেট বনাম তালিকা বনাম অভিধান সম্পাদনা পরীক্ষা, এখান থেকে নেওয়া ।

1000000 অবজেক্ট যুক্ত করুন (নকল পরীক্ষা না করে)

10000 সংগ্রহের অর্ধেক অবজেক্টের জন্য চেক থাকে

10000 এর সংগ্রহের অর্ধেক অবজেক্টগুলি সরান


9
দুর্দান্ত বিশ্লেষণ! দেখে মনে হচ্ছে। অভিধানের জন্য নিয়ন্ত্রণগুলি এত দ্রুত যে ওপির ক্ষেত্রে হ্যাশসেট ব্যবহার করে কোনও লাভ হয় না।
ইথারড্রাগন

2
হ্যাঁ, আমি ওপি হিসাবে একই প্রশ্ন ছিল। আমার কাছে ইতিমধ্যে একটি অভিধান আছে যা আমি অন্যান্য কারণে ব্যবহার করছি এবং আমি জানতে চেয়েছিলাম যে কনটেনস্কি ব্যবহার না করে হ্যাশেটে পরিবর্তন করে আমি উপকৃত হচ্ছি কিনা। দেখে মনে হচ্ছে উত্তরটি নেই কারণ উভয়ই এত দ্রুত so
ফিস্টঅফফুরি

4
পূর্ববর্তী মন্তব্যগুলি যা বোঝায় তার বিপরীতে, হ্যাঁ, আপনার হ্যাশসেটে স্যুইচ করা উচিত কারণ এটি আপনাকে যা চান তা দেয়: মানগুলির একটি সেট সংরক্ষণ করে (কোনও ধরণের ম্যাপিং বজায় রাখার বিরোধিতা করে)। এই উত্তরটি নির্দেশ করে যে অভিধানের তুলনায় পারফরম্যান্সে কোনও নেতিবাচক প্রভাব পড়বে না।
ফ্রাঙ্কোইস বিউশিয়ার

এই উত্তরটি আপনাকে জানায় না যে হ্যাশসেট এবং অভিধানের পারফরম্যান্স তুলনা করে ... এটি আপনাকে কেবলমাত্র বলে যে তারা উভয়ই তালিকার চেয়ে দ্রুত .. ভাল ... হ্যাঁ! একথাও ঠিক যে! হ্যাশসেটটি 3 গুণ দ্রুত হতে পারে এবং আপনি জানতে পারবেন না কারণ প্রাসঙ্গিক পরীক্ষা " তালিকার সাথে তুলনায় তারা তাত্ক্ষণিক ..." উভয়কেই ভেঙে পড়েছে ।
ব্রোনডাহাল

71

আমি ধরে নিলাম আপনি Dictionary<TKey, TValue>দ্বিতীয় ক্ষেত্রে মানে ? HashTableএকটি নন-জেনেরিক ক্লাস।

আপনার প্রকৃত প্রয়োজনীয়তার উপর ভিত্তি করে আপনার কাজের জন্য সঠিক সংগ্রহ চয়ন করা উচিত। আপনি কি প্রতিটি কীতে কোনও মানকে ম্যাপ করতে চান ? যদি তাই হয়, ব্যবহার করুন Dictionary<,>। আপনি যদি সেট হিসাবে কেবল এটি যত্নশীল হন তবে ব্যবহার করুন HashSet<>

মূলত একই কাজটি করার জন্য আমি প্রত্যাশা করব HashSet<T>.Containsএবং Dictionary<TKey, TValue>.ContainsKey(যা তুলনামূলক অপারেশনস, আপনি নিজের অভিধানটি বোধগম্যভাবে ধরে নিচ্ছেন) ধরে নিই - তারা একই অ্যালগরিদমটি মূলত ব্যবহার করছে। আমি Dictionary<,>বড় হওয়ার এন্ট্রিগুলির সাথে অনুমান করি আপনি শেষের Dictionary<,>চেয়ে ক্যাশে ফুঁকানোর আরও বেশি সম্ভাবনা শেষ করেছেন HashSet<>, তবে আমি প্রত্যাশা করব যে আপনি যা সঠিকভাবে ভুল তথ্য টাইপ করার বেদনার সাথে তুলনা করে তুচ্ছ হন you're অর্জনের চেষ্টা করছি


হ্যাঁ, আমার অর্থ অভিধানটি ছিল <টি কে, টিভিয়াল>। আমি শুধুমাত্র একটি ডাটা কাঠামো আইটেমের অস্তিত্ব, যে অনুসন্ধানের জন্য সম্পর্কে উদ্বিগ্ন সব
হ্যালিভিংস্টন

3
@ হালভিংস্টন সে ক্ষেত্রে হ্যাশসেট ব্যবহার করুন। এটা সুস্পষ্ট যে তোলে হয় আপনার প্রয়োজন।
জন স্কিটি

2
ঠিক আছে ধন্যবাদ. আমার কাছে এখনই একটি হ্যাশসেট <টিকি> এবং মেমরির মধ্যে অভিধান <টিকি, টিভিয়াল> এর একটি সদৃশ কপি রয়েছে। আমি প্রথমে .হ্যাশসেটে অন্তর্ভুক্ত, তারপরে অভিধান <টিকি, টিভিয়াল>> এ মানটি পুনরুদ্ধার করুন। আমার এখনই অসীম স্মৃতি রয়েছে, তবে শীঘ্রই আমি আশঙ্কা করছি যে আমার স্মৃতিশক্তি বাধাগ্রস্ত হবে এবং আমাদের দল আমাকে স্মরণে এই সদৃশ জিনিসটি সরিয়ে ফেলতে বলবে, এই মুহুর্তে আমি অভিধান <টিকি, টিভিয়াল> ব্যবহার করতে বাধ্য হব।
হ্যালিভিংস্টন

4
আপনি কি জানেন অভিধানে একটি কনটেনস্কি ফাংশন খুব সঠিকভাবে আছে? আপনি কেন ডাটা নকল করছেন?
অন্ধ

8
আপনার যদি ইতিমধ্যে অভিধানে ডেটা থাকে তবে আপনার প্রথম মন্তব্যটি স্পষ্টতই ভুল keys আপনার কীগুলিও মানগুলির সাথে যুক্ত করতে হবে। কোডের এই বিশেষ বিটের জন্য নাও হতে পারে , তবে এটি অপ্রাসঙ্গিক। যদি আপনি Dictionaryঅন্য কারণে ইতিমধ্যে একটি পেয়ে থাকেন তবে আপনার এটি ব্যবহার করা উচিত।
জন স্কিটি

7

<টি কে, টিভিয়াল>> এর এমএসডিএন ডকুমেন্টেশন থেকে

"মানটির কীটি ব্যবহার করে পুনরুদ্ধার করা খুব দ্রুত, ও (1) এর কাছাকাছি , কারণ অভিধান ক্লাসটি হ্যাশ টেবিল হিসাবে প্রয়োগ করা হয় " "

একটি নোট সহ:

"পুনরুদ্ধারের গতি TKey এর জন্য নির্দিষ্ট ধরণের হ্যাশিং অ্যালগরিদমের মানের উপর নির্ভর করে"

আমি জানি আপনার প্রশ্ন / পোস্টটি পুরানো - তবে অনুরূপ প্রশ্নের উত্তর খুঁজতে গিয়ে আমি এটিকে হোঁচট খেয়েছি।

আশাকরি এটা সাহায্য করবে. আরও তথ্যের জন্য নীচে মন্তব্যসমূহ বিভাগে স্ক্রোল করুন। https://msdn.microsoft.com/en-us/library/xfhwa508(v=vs.110).aspx


4

এগুলি বিভিন্ন ডেটা স্ট্রাকচার। এছাড়াও এর জেনেরিক সংস্করণ নেই HashTable

HashSetটি টাইপের মান রয়েছে যাতে HashTable(বা Dictionary) কী-মান জোড়া রয়েছে। সুতরাং আপনার কোন ডেটা সংরক্ষণ করতে হবে তা সংগ্রহ সংগ্রহ করা উচিত।


0

এই প্রশ্নের গৃহীত উত্তর বৈধভাবে প্রশ্নের উত্তর দেয় না! সঠিক উত্তর দেওয়ার ক্ষেত্রে এটি ঘটে তবে তাদের দেওয়া প্রমাণ দ্বারা উত্তরটি প্রদর্শিত হয় না।

কি যে উত্তর শো একটি উপর কী লুক-হয় Dictionaryবা HashSetএকটি আপ খুঁজছেন চেয়ে অতি দ্রুততর হয় List। যা সত্য, তবে আকর্ষণীয় নয়, অবাক হওয়ার মতোও নয় বা প্রমাণও নেই যে তাদের একই গতি রয়েছে।

দেখার সময়টির তুলনা করার জন্য আমি নীচের কোডটি চালিয়েছি এবং আমার উপসংহারটি হ'ল তারা আসলে একই গতি। (বা কমপক্ষে, যদি কোনও পার্থক্য থাকে তবে পার্থক্যটি সেই গতির স্ট্যান্ডার্ড বিচ্যুতির মধ্যে ভালভাবে হয়)

বিশেষত, এই পরীক্ষায় আমার জন্য উভয়ের জন্য ১০০,০০০,০০০ এর মধ্যে সন্ধান করা হয়েছে ,000

পরীক্ষার কোড:

private const int TestReps = 100_000_000;
[Test]
public void CompareHashSetContainsVersusDictionaryContainsKey()
{
    for (int j = 0; j < 10; j++)
    {
        var rand = new Random();
        var dict = new Dictionary<int, int>();
        var hash = new HashSet<int>();

        for (int i = 0; i < TestReps; i++)
        {
            var key = rand.Next();
            var value = rand.Next();
            hash.Add(key);
            dict.TryAdd(key, value);
        }

        var testPoints = Enumerable.Repeat(1, TestReps).Select(_ => rand.Next()).ToArray();
        var timer = new Stopwatch();
        var total = 0;
        
        timer.Restart();
            for (int i = 0; i < TestReps; i++)
            {
                var newKey = testPoints[i];
                if (hash.Contains(newKey))
                {
                    total++;
                }
            }
        Console.WriteLine(timer.Elapsed);
        
        var target = total;
        Assert.That(total == target);
        

        timer.Restart();
            for (int i = 0; i < TestReps; i++)
            {
                var newKey = testPoints[i];
                if (dict.ContainsKey(newKey))
                {
                    total++;
                }
            }
        Console.WriteLine(timer.Elapsed);

        Assert.That(total == target * 2);
        Console.WriteLine("Set");
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.