হ্যাশসেট বনাম তালিকা সম্পাদনা


404

এটি স্পষ্ট যে জেনেরিক HashSet<T>শ্রেণির তুলনায় জেনেরিক শ্রেণির একটি অনুসন্ধান কর্মক্ষমতা বেশি List<T>List<T>ক্লাসে রৈখিক পদ্ধতির সাথে হ্যাশ-ভিত্তিক কীটি কেবল তুলনা করুন ।

তবে একটি হ্যাশ কী গণনা করা নিজেই কিছু সিপিইউ চক্র নিতে পারে, তাই সামান্য পরিমাণ আইটেমের জন্য লিনিয়ার সন্ধানের একটি আসল বিকল্প হতে পারে HashSet<T>

আমার প্রশ্ন: বিরতি কোথায়?

দৃশ্যটি সহজ করার জন্য (এবং ন্যায্য হতে) ধরে নেওয়া যাক List<T>শ্রেণি Equals()কোনও আইটেম সনাক্ত করার জন্য উপাদানটির পদ্ধতিটি ব্যবহার করে ।


7
আপনি যদি প্রকৃতপক্ষে অনুসন্ধানের সময়টি ন্যূনতম করতে চান তবে অ্যারে এবং সাজানো অ্যারেগুলিও বিবেচনা করুন। এই প্রশ্নের যথাযথভাবে উত্তর দেওয়ার জন্য, একটি মানদণ্ডের প্রয়োজন, তবে আপনাকে টি সম্পর্কে আরও আমাদের জানা দরকার, এছাড়াও হ্যাশসেটের পারফরম্যান্স টি.গেটহ্যাশকোড () চলমান সময় দ্বারা প্রভাবিত হতে পারে।
এল্ড্রিচ কনড্রাম

উত্তর:


818

অনেক লোক বলছেন যে একবার আপনি যখন আকারে পৌঁছে গেলেন সেখানে গতি আসলে একটি উদ্বেগ যা HashSet<T>সর্বদা পরাজিত হবে List<T>তবে এটি আপনি যা করছেন তার উপর নির্ভর করে।

ধরা যাক আপনার কাছে এমন একটি রয়েছে List<T>যাতে এটিতে সর্বদা গড়ে 5 টি আইটেম থাকবে। প্রচুর পরিমাণে চক্রের উপরে, যদি প্রতিটি চক্রটিতে একটি আইটেম যুক্ত করা হয় বা সরিয়ে দেওয়া হয় তবে আপনি এ ব্যবহার করে ভাল হতে পারেনList<T>

আমি আমার মেশিনে এটির জন্য একটি পরীক্ষা করেছি এবং, ভাল, এর সুবিধা পেতে খুব ছোট হওয়া দরকার List<T>। সংক্ষিপ্ত স্ট্রিংয়ের তালিকার জন্য, আকার 20 এর পরে অবজেক্টগুলির জন্য 5 মাপের পরে সুবিধাটি চলে গেল।

1 item LIST strs time: 617ms
1 item HASHSET strs time: 1332ms

2 item LIST strs time: 781ms
2 item HASHSET strs time: 1354ms

3 item LIST strs time: 950ms
3 item HASHSET strs time: 1405ms

4 item LIST strs time: 1126ms
4 item HASHSET strs time: 1441ms

5 item LIST strs time: 1370ms
5 item HASHSET strs time: 1452ms

6 item LIST strs time: 1481ms
6 item HASHSET strs time: 1418ms

7 item LIST strs time: 1581ms
7 item HASHSET strs time: 1464ms

8 item LIST strs time: 1726ms
8 item HASHSET strs time: 1398ms

9 item LIST strs time: 1901ms
9 item HASHSET strs time: 1433ms

1 item LIST objs time: 614ms
1 item HASHSET objs time: 1993ms

4 item LIST objs time: 837ms
4 item HASHSET objs time: 1914ms

7 item LIST objs time: 1070ms
7 item HASHSET objs time: 1900ms

10 item LIST objs time: 1267ms
10 item HASHSET objs time: 1904ms

13 item LIST objs time: 1494ms
13 item HASHSET objs time: 1893ms

16 item LIST objs time: 1695ms
16 item HASHSET objs time: 1879ms

19 item LIST objs time: 1902ms
19 item HASHSET objs time: 1950ms

22 item LIST objs time: 2136ms
22 item HASHSET objs time: 1893ms

25 item LIST objs time: 2357ms
25 item HASHSET objs time: 1826ms

28 item LIST objs time: 2555ms
28 item HASHSET objs time: 1865ms

31 item LIST objs time: 2755ms
31 item HASHSET objs time: 1963ms

34 item LIST objs time: 3025ms
34 item HASHSET objs time: 1874ms

37 item LIST objs time: 3195ms
37 item HASHSET objs time: 1958ms

40 item LIST objs time: 3401ms
40 item HASHSET objs time: 1855ms

43 item LIST objs time: 3618ms
43 item HASHSET objs time: 1869ms

46 item LIST objs time: 3883ms
46 item HASHSET objs time: 2046ms

49 item LIST objs time: 4218ms
49 item HASHSET objs time: 1873ms

গ্রাফ হিসাবে প্রদর্শিত তথ্য এখানে:

এখানে চিত্র বর্ণনা লিখুন

কোডটি এখানে:

static void Main(string[] args)
{
    int times = 10000000;


    for (int listSize = 1; listSize < 10; listSize++)
    {
        List<string> list = new List<string>();
        HashSet<string> hashset = new HashSet<string>();

        for (int i = 0; i < listSize; i++)
        {
            list.Add("string" + i.ToString());
            hashset.Add("string" + i.ToString());
        }

        Stopwatch timer = new Stopwatch();
        timer.Start();
        for (int i = 0; i < times; i++)
        {
            list.Remove("string0");
            list.Add("string0");
        }
        timer.Stop();
        Console.WriteLine(listSize.ToString() + " item LIST strs time: " + timer.ElapsedMilliseconds.ToString() + "ms");


        timer = new Stopwatch();
        timer.Start();
        for (int i = 0; i < times; i++)
        {
            hashset.Remove("string0");
            hashset.Add("string0");
        }
        timer.Stop();
        Console.WriteLine(listSize.ToString() + " item HASHSET strs time: " + timer.ElapsedMilliseconds.ToString() + "ms");
        Console.WriteLine();
    }


    for (int listSize = 1; listSize < 50; listSize+=3)
    {
        List<object> list = new List<object>();
        HashSet<object> hashset = new HashSet<object>();

        for (int i = 0; i < listSize; i++)
        {
            list.Add(new object());
            hashset.Add(new object());
        }

        object objToAddRem = list[0];

        Stopwatch timer = new Stopwatch();
        timer.Start();
        for (int i = 0; i < times; i++)
        {
            list.Remove(objToAddRem);
            list.Add(objToAddRem);
        }
        timer.Stop();
        Console.WriteLine(listSize.ToString() + " item LIST objs time: " + timer.ElapsedMilliseconds.ToString() + "ms");



        timer = new Stopwatch();
        timer.Start();
        for (int i = 0; i < times; i++)
        {
            hashset.Remove(objToAddRem);
            hashset.Add(objToAddRem);
        }
        timer.Stop();
        Console.WriteLine(listSize.ToString() + " item HASHSET objs time: " + timer.ElapsedMilliseconds.ToString() + "ms");
        Console.WriteLine();
    }

    Console.ReadLine();
}

8
তোমাকে অনেক ধন্যবাদ! এটি দুর্দান্ত ব্যাখ্যা, আমি এমন কিছু সন্ধান করছিলাম যা List<T>একটি গেম ইঞ্জিনের চেয়ে দ্রুত যোগ করতে এবং অপসারণ করতে পারে এবং যেহেতু আমার কাছে সাধারণত বস্তুগুলির উচ্চ পরিমাণ থাকে তাই এই ধরণের সংগ্রহটি নিখুঁত হবে।
redcodefinal

17
.NET ফ্রেমওয়ার্কে আসলে একটি সংগ্রহ রয়েছে যা এতে থাকা আইটেমের সংখ্যার উপর নির্ভর করে একটি তালিকা এবং তাড়াতাড়ি বাস্তবায়নের মধ্যে স্যুইচ করে: হাইব্রিডডোরিয়রিয়াল
এমজিএসএম

8
এমএস মনে হয় এটিকে ভেবে ফেলেছিল, কারণ এটির কেবল একটি জেনারিক সংস্করণ উপলব্ধ।
এমজিএসএম

47
এই উত্তরটি সম্পূর্ণ হিসাবে এটি হ্যাশসেট অনুসন্ধানের কার্য সম্পাদনা তালিকা সম্পর্কিত মূল প্রশ্নের উত্তর দিতে ব্যর্থ। আপনি কত তাড়াতাড়ি sertোকাতে এবং এগুলি সরাতে পারবেন তা আপনি পরীক্ষা করছেন, যা অনুসন্ধানের চেয়ে যথেষ্ট বেশি সময় এবং বিভিন্ন পারফরম্যান্স বৈশিষ্ট্য নেয়। আবার চেষ্টা করুন .Contains ব্যবহার করে এবং আপনার গ্রাফটি উল্লেখযোগ্যভাবে পরিবর্তিত হবে।
রবার্ট ম্যাককি

5
@ হাইপিউম্যান সিপিইউ সিস্টেম মেমরির ডেটাতে সরাসরি কাজ করতে পারে না তবে কাজ করার জন্য মেমরি থেকে ডেটা টেনে তার ক্যাশে s মেমোরিটি স্থানান্তরিত হওয়ার অনুরোধ এবং মেমরিটি আসলে আসার মধ্যে একটি উল্লেখযোগ্য বিলম্ব রয়েছে যাতে সিপিইউ প্রায়শই একযোগে স্থানান্তরিত করার জন্য একটি বৃহত অংশের সাথে থাকা মেমরির অনুরোধ করবে। এর পিছনে ধারণাটি হ'ল পরবর্তী নির্দেশের দ্বারা প্রয়োজনীয় স্মৃতি সম্ভবত পূর্ববর্তী নির্দেশাবলীর দ্বারা ব্যবহৃত স্মৃতিটির খুব কাছাকাছি এবং এভাবে প্রায়শই ক্যাশে থাকে। আপনার ডেটা যখন মেমরি জুড়ে ছড়িয়ে যায় তখন ভাগ্যবান হওয়ার সম্ভাবনা হ্রাস পায়।
রায় টি।

70

আপনি এই ভুল দেখছেন। হ্যাঁ তালিকার একটি লিনিয়ার অনুসন্ধান অল্প সংখ্যক আইটেমের জন্য একটি হ্যাশসেটকে পরাজিত করবে। তবে পারফরম্যান্সের পার্থক্যটি সাধারণত ছোট সংগ্রহের ক্ষেত্রে আসে না। এটি সাধারণত আপনাকে যে বড় সংগ্রহগুলি নিয়ে চিন্ত করতে হবে তা হ'ল এবং আপনি এখানে বিগ-ও-র বিবেচনা করুন । তবে, যদি আপনি হ্যাশসেটের পারফরম্যান্সের ক্ষেত্রে সত্যিকারের বাধাটি পরিমাপ করেন, তবে আপনি একটি হাইব্রিড তালিকা / হ্যাশসেট তৈরি করার চেষ্টা করতে পারেন, তবে আপনি প্রচুর অভিজ্ঞতামূলক পারফরম্যান্স পরীক্ষা চালিয়ে যাবেন - এসও-তে প্রশ্ন জিজ্ঞাসা করবেন না।


5
বড় সংগ্রহগুলি সম্পর্কে আপনাকে চিন্তিত হতে হবে । আমরা দশকে when small collection becomes large enough to worry about HashSet vs List?দশকে, কয়েক হাজারে, কোটি কোটি উপাদানকে এই প্রশ্নটির নতুন সংজ্ঞা দিতে পারি ?
সর্বজনীন-মনোনীত

8
না, আপনি কয়েক শতাধিক উপাদানের উপরে পারফরম্যান্সের যথেষ্ট পার্থক্য দেখতে পাবেন। পয়েন্টটি সর্বদা একটি হ্যাশসেট ব্যবহার করা হয় যদি আপনি হ্যাশসেট যে ধরণের প্রবেশাধিকারের ক্ষেত্রে ভাল হন (যেমন সেটটিতে উপাদান এক্স রয়েছে)) যদি আপনার সংগ্রহটি এত ছোট হয় যে কোনও তালিকা দ্রুততর হয় তবে খুব কমই দেখা যায় যে সেগুলি দেখার জন্য আসলে আপনার অ্যাপ্লিকেশন একটি বাধা আছে। যদি আপনি এটি এক হিসাবে পরিমাপ করতে পারেন তবে সূক্ষ্ম আপনি এটিকে অনুকূল করতে চেষ্টা করতে পারেন - তবে অন্যথায় আপনি আপনার সময় নষ্ট করছেন।
এলফ

15
আপনার যদি একটি ছোট সংগ্রহ থাকে যা লুপে বহুবার আঘাত করে? এটি কোনও অস্বাভাবিক পরিস্থিতি নয়।
ড্যান-জিএফ

3
@ ওম-নম-নোম - আমি মনে করি মূল বক্তব্যটি হ'ল টিপিং পয়েন্টটি কোথায় তা বিবেচ্য নয় কারণ: "যদি পারফরম্যান্সটি উদ্বেগজনক হয় তবে ব্যবহার করুন HashSet<T>the অল্প সংখ্যক ক্ষেত্রে যেখানে List<T>দ্রুততর হতে পারে সেখানে পার্থক্যটি তাত্পর্যপূর্ণ নয় is । "
স্কট স্মিথ

66

পারফরম্যান্সের জন্য দুটি কাঠামোর তুলনা করা মূলত অর্থহীন যা ভিন্ন আচরণ করে। উদ্দেশ্যটি বোঝায় এমন কাঠামোটি ব্যবহার করুন। এমনকি যদি আপনি বলেন যে আপনার List<T>নকল এবং পুনরাবৃত্তির অর্ডার এটির সাথে তুলনাযোগ্য করে তোলে তবে এটি HashSet<T>এখনও ব্যবহারের পক্ষে বাজে পছন্দ নয়List<T> কারণ এটি তুলনামূলকভাবে কম দোষ সহনীয়।

এটি বলেছিল, আমি পারফরম্যান্সের আরও কয়েকটি দিক পরিদর্শন করব ,

+------------+--------+-------------+-----------+----------+----------+-----------+
| Collection | Random | Containment | Insertion | Addition |  Removal | Memory    |
|            | access |             |           |          |          |           |
+------------+--------+-------------+-----------+----------+----------+-----------+
| List<T>    | O(1)   | O(n)        | O(n)      | O(1)*    | O(n)     | Lesser    |
| HashSet<T> | O(n)   | O(1)        | n/a       | O(1)     | O(1)     | Greater** |
+------------+--------+-------------+-----------+----------+----------+-----------+
  • যদিও উভয় ক্ষেত্রে সংযোজন O (1) হলেও এটি হ্যাশসেটে তুলনামূলকভাবে ধীর হবে কারণ এটি সংরক্ষণ করার আগে হ্যাশ কোডটি পূর্ববর্তীকরণের জন্য জড়িত।

  • হ্যাশসেটের উচ্চতর স্কেলাবিলিটির মেমরির ব্যয় রয়েছে। প্রতিটি এন্ট্রি তার হ্যাশ কোড সহ একটি নতুন অবজেক্ট হিসাবে সংরক্ষণ করা হয়। এই নিবন্ধটি আপনাকে একটি ধারণা দিতে পারে।


11
আমার প্রশ্ন (ছয় বছর আগে) তাত্ত্বিক অভিনয় সম্পর্কে ছিল না ।
মাইকেল দামাতভ

1
হ্যাশসেট এলিমেন্টআট () এর সাথে এলোমেলো অ্যাক্সেসের অনুমতি দেয় এবং আমি মনে করি এটি ও (এন) সময় হবে। এছাড়াও, সম্ভবত আপনি আপনার টেবিলটিতে রাখতে পারেন প্রতিটি সংগ্রহ নকলকে অনুমতি দেয় কিনা (যেমন: তালিকাগুলি করে, তবে হ্যাশসেটগুলি দেয় না)।
ড্যান ডাব্লু

1
টেবিলের মধ্যে ড্যানডাব্লু আমি নিখুঁত পারফরম্যান্সের সাথে তুলনা করছি, আচরণগত বৈশিষ্ট্যগুলি নয়। এলিমেন্টআট টিপের জন্য ধন্যবাদ
নওফাল

1
এলিমেন্টএটি হ'ল একটি লাইনকিউ এক্সটেনশন .. এটি আপনি করতে পারবেন না এমন কিছু করে না এবং আপনি নিজের সাথে যুক্ত অন্য পদ্ধতিতে আরও ভাল করে তুলবেন। আমি মনে করি যে টেবিলটি এলিমেন্টএটি বিবেচনা না করে আরও বোধগম্য হয়েছে যেহেতু এই সমস্ত শ্রেণিতে স্পষ্টভাবে অন্যান্য সমস্ত পদ্ধতি বিদ্যমান রয়েছে exist
ডিনারডো

এই টেবিলটির জন্য ধন্যবাদ, আমার ব্যবহারের ক্ষেত্রে যখনই আমি সক্ষম / অক্ষম হয়েছি তখনই জনবহুল সংগ্রহে লক্ষ্যমাত্রা যুক্ত করতে এবং অপসারণ করতে হবে এবং এটি আমাকে সঠিক পছন্দ (হ্যাশসেট) করতে সহায়তা করেছে।
কেসি হফল্যান্ড

50

হ্যাশসেট <> বা তালিকা <> ব্যবহার করবেন কিনা তা আপনার সংগ্রহে কীভাবে অ্যাক্সেস করতে হবে তা নেমে আসে । আপনার যদি আইটেমগুলির ক্রম গ্যারান্টির প্রয়োজন হয় তবে একটি তালিকা ব্যবহার করুন। যদি আপনি না করেন তবে একটি হ্যাশসেট ব্যবহার করুন। মাইক্রোসফ্টকে তাদের হ্যাশিং অ্যালগরিদম এবং অবজেক্টগুলির প্রয়োগ সম্পর্কে উদ্বিগ্ন হতে দিন।

একটি হ্যাশসেট সংগ্রহ ( ও (1) এর জটিলতা বা তার কাছাকাছি ) গণনা ছাড়াই আইটেমগুলিতে অ্যাক্সেস করবে এবং হ্যাশসেটের বিপরীতে কোনও তালিকা আদেশের গ্যারান্টি দেয় বলে কিছু আইটেম গণনা করতে হবে (ও (এন) এর জটিলতা)।


তালিকাটি সূচক দ্বারা নির্দিষ্ট উপাদানটির জন্য অফসেট গণনা করতে পারে (কারণ সমস্ত উপাদান একই ধরণের এবং সম্ভবত একই মেমরির আকার ধারণ করে)। সুতরাং তালিকাটি এর উপাদানগুলি গণ্য করার জন্য প্রয়োজনীয় নয়
লু 55

@ লু 55 - প্রশ্নটি কোনও সংগ্রহের কোনও আইটেম অনুসন্ধানের বিষয়ে । একটি সাধারণ দৃশ্যটি হ'ল সংগ্রহটি গতিশীল - আপনি প্রদত্ত আইটেমটি অনুসন্ধানের সময় থেকে আইটেমগুলি যুক্ত বা মুছে ফেলা হতে পারে - সুতরাং একটি সূচকটি অর্থবহ নয় (কারণ এটি পরিবর্তিত হবে)। যদি আপনার একটি স্থিতিশীল সংগ্রহ থাকে (আপনি আপনার গণনা সম্পাদন করার সময় এটি বদলাবে না), বা আইটেমগুলি কখনই মুছে ফেলা হয় না এবং সর্বদা শেষে যুক্ত করা হয়, তবে Listএকটিকে অগ্রাধিকার দেওয়া হয়, কারণ আপনি একটি সূচক মনে রাখতে পারেন - এটাই পরিস্থিতি আপনি বর্ণনা করছি
টুলমেকারস্টেভ

যদি আপনার কোনও হ্যাশসেটকে বাছাই করতে হয় তবে আপনি একটি সাজানো সেট ব্যবহার করতে পারেন। এখনও একটি তালিকার চেয়ে অনেক দ্রুত।
লাইভ-লাভ

25

পূর্ববর্তী উত্তরগুলি চিত্রিত করার জন্য আমি বিভিন্ন পরিস্থিতিতে কিছু বেঞ্চমার্ক নিয়ে চিমযুক্ত করে ভেবেছিলাম:

  1. কয়েকটি (12 - 20) ছোট স্ট্রিং (দৈর্ঘ্য 5 এবং 10 বর্ণের মধ্যে)
  2. অনেকগুলি (~ 10 কে) ছোট স্ট্রিং
  3. কয়েকটি দীর্ঘ স্ট্রিং (দৈর্ঘ্য 200 এবং 1000 বর্ণের মধ্যে)
  4. অনেকগুলি (~ 5K) দীর্ঘ স্ট্রিং
  5. কয়েকটি পূর্ণসংখ্যা
  6. অনেকগুলি (10 ডলার) পূর্ণসংখ্যা

এবং প্রতিটি দৃশ্যের জন্য, প্রদর্শিত মানগুলি সন্ধান করা:

  1. তালিকার শুরুতে ("শুরু", সূচক 0)
  2. তালিকার শুরুতে ("প্রথম" সূচক 1)
  3. তালিকার মাঝখানে ("মাঝারি", সূচকের গণনা / 2)
  4. তালিকার শেষের নিকটে ("দেরী", সূচি গণনা -২)
  5. তালিকার শেষে ("শেষ", সূচি গণনা -১)

প্রতিটি দৃশ্যের আগে আমি এলোমেলো আকারের এলোমেলো স্ট্রিংয়ের তালিকা তৈরি করতাম এবং তারপরে প্রতিটি তালিকা হ্যাশসেটে খাওয়াতাম। প্রতিটি দৃশ্য 10,000 বার চলেছিল, মূলত:

(পরীক্ষা সিউডোকোড)

stopwatch.start
for X times
    exists = list.Contains(lookup);
stopwatch.stop

stopwatch.start
for X times
    exists = hashset.Contains(lookup);
stopwatch.stop

নমুনা আউটপুট

উইন্ডোজ 7, ​​12 জিবি র‌্যাম, 64৪ বিট, জিওন ২.৮ গিগাহার্টজে পরীক্ষিত

---------- Testing few small strings ------------
Sample items: (16 total)
vgnwaloqf diwfpxbv tdcdc grfch icsjwk
...

Benchmarks:
1: hashset: late -- 100.00 % -- [Elapsed: 0.0018398 sec]
2: hashset: middle -- 104.19 % -- [Elapsed: 0.0019169 sec]
3: hashset: end -- 108.21 % -- [Elapsed: 0.0019908 sec]
4: list: early -- 144.62 % -- [Elapsed: 0.0026607 sec]
5: hashset: start -- 174.32 % -- [Elapsed: 0.0032071 sec]
6: list: middle -- 187.72 % -- [Elapsed: 0.0034536 sec]
7: list: late -- 192.66 % -- [Elapsed: 0.0035446 sec]
8: list: end -- 215.42 % -- [Elapsed: 0.0039633 sec]
9: hashset: early -- 217.95 % -- [Elapsed: 0.0040098 sec]
10: list: start -- 576.55 % -- [Elapsed: 0.0106073 sec]


---------- Testing many small strings ------------
Sample items: (10346 total)
dmnowa yshtrxorj vthjk okrxegip vwpoltck
...

Benchmarks:
1: hashset: end -- 100.00 % -- [Elapsed: 0.0017443 sec]
2: hashset: late -- 102.91 % -- [Elapsed: 0.0017951 sec]
3: hashset: middle -- 106.23 % -- [Elapsed: 0.0018529 sec]
4: list: early -- 107.49 % -- [Elapsed: 0.0018749 sec]
5: list: start -- 126.23 % -- [Elapsed: 0.0022018 sec]
6: hashset: early -- 134.11 % -- [Elapsed: 0.0023393 sec]
7: hashset: start -- 372.09 % -- [Elapsed: 0.0064903 sec]
8: list: middle -- 48,593.79 % -- [Elapsed: 0.8476214 sec]
9: list: end -- 99,020.73 % -- [Elapsed: 1.7272186 sec]
10: list: late -- 99,089.36 % -- [Elapsed: 1.7284155 sec]


---------- Testing few long strings ------------
Sample items: (19 total)
hidfymjyjtffcjmlcaoivbylakmqgoiowbgxpyhnrreodxyleehkhsofjqenyrrtlphbcnvdrbqdvji...
...

Benchmarks:
1: list: early -- 100.00 % -- [Elapsed: 0.0018266 sec]
2: list: start -- 115.76 % -- [Elapsed: 0.0021144 sec]
3: list: middle -- 143.44 % -- [Elapsed: 0.0026201 sec]
4: list: late -- 190.05 % -- [Elapsed: 0.0034715 sec]
5: list: end -- 193.78 % -- [Elapsed: 0.0035395 sec]
6: hashset: early -- 215.00 % -- [Elapsed: 0.0039271 sec]
7: hashset: end -- 248.47 % -- [Elapsed: 0.0045386 sec]
8: hashset: start -- 298.04 % -- [Elapsed: 0.005444 sec]
9: hashset: middle -- 325.63 % -- [Elapsed: 0.005948 sec]
10: hashset: late -- 431.62 % -- [Elapsed: 0.0078839 sec]


---------- Testing many long strings ------------
Sample items: (5000 total)
yrpjccgxjbketcpmnvyqvghhlnjblhgimybdygumtijtrwaromwrajlsjhxoselbucqualmhbmwnvnpnm
...

Benchmarks:
1: list: early -- 100.00 % -- [Elapsed: 0.0016211 sec]
2: list: start -- 132.73 % -- [Elapsed: 0.0021517 sec]
3: hashset: start -- 231.26 % -- [Elapsed: 0.003749 sec]
4: hashset: end -- 368.74 % -- [Elapsed: 0.0059776 sec]
5: hashset: middle -- 385.50 % -- [Elapsed: 0.0062493 sec]
6: hashset: late -- 406.23 % -- [Elapsed: 0.0065854 sec]
7: hashset: early -- 421.34 % -- [Elapsed: 0.0068304 sec]
8: list: middle -- 18,619.12 % -- [Elapsed: 0.3018345 sec]
9: list: end -- 40,942.82 % -- [Elapsed: 0.663724 sec]
10: list: late -- 41,188.19 % -- [Elapsed: 0.6677017 sec]


---------- Testing few ints ------------
Sample items: (16 total)
7266092 60668895 159021363 216428460 28007724
...

Benchmarks:
1: hashset: early -- 100.00 % -- [Elapsed: 0.0016211 sec]
2: hashset: end -- 100.45 % -- [Elapsed: 0.0016284 sec]
3: list: early -- 101.83 % -- [Elapsed: 0.0016507 sec]
4: hashset: late -- 108.95 % -- [Elapsed: 0.0017662 sec]
5: hashset: middle -- 112.29 % -- [Elapsed: 0.0018204 sec]
6: hashset: start -- 120.33 % -- [Elapsed: 0.0019506 sec]
7: list: late -- 134.45 % -- [Elapsed: 0.0021795 sec]
8: list: start -- 136.43 % -- [Elapsed: 0.0022117 sec]
9: list: end -- 169.77 % -- [Elapsed: 0.0027522 sec]
10: list: middle -- 237.94 % -- [Elapsed: 0.0038573 sec]


---------- Testing many ints ------------
Sample items: (10357 total)
370826556 569127161 101235820 792075135 270823009
...

Benchmarks:
1: list: early -- 100.00 % -- [Elapsed: 0.0015132 sec]
2: hashset: end -- 101.79 % -- [Elapsed: 0.0015403 sec]
3: hashset: early -- 102.08 % -- [Elapsed: 0.0015446 sec]
4: hashset: middle -- 103.21 % -- [Elapsed: 0.0015618 sec]
5: hashset: late -- 104.26 % -- [Elapsed: 0.0015776 sec]
6: list: start -- 126.78 % -- [Elapsed: 0.0019184 sec]
7: hashset: start -- 130.91 % -- [Elapsed: 0.0019809 sec]
8: list: middle -- 16,497.89 % -- [Elapsed: 0.2496461 sec]
9: list: end -- 32,715.52 % -- [Elapsed: 0.4950512 sec]
10: list: late -- 33,698.87 % -- [Elapsed: 0.5099313 sec]

7
মজাদার. এটি চালানোর জন্য ধন্যবাদ। দুঃখের বিষয়, আমি সন্দেহ করি যে এই আলোচনাগুলি অযথা রিফ্যাক্টরিংগুলি ট্রিগার করে। আশাকরি বেশিরভাগ লোকের গ্রহণযোগ্যতাটি হল আপনার একদম খারাপ পরিস্থিতির মধ্যে Listএখনও একক অনুসন্ধান করতে মাত্র 0.17 মিলিসেকেন্ড লাগবে এবং HashSetযতক্ষণ না লুকোচুরির ফ্রিকোয়েন্সিটি অযৌক্তিক স্তরে পৌঁছায় ততক্ষণের জন্য বিকল্পের প্রয়োজন হবে না। ততক্ষণে তালিকার ব্যবহার সাধারণত সমস্যাগুলির মধ্যে সবচেয়ে কম হয়।
পল ওয়ালস

এটি আপাতত সত্যিকারের তথ্য নয় .. বা সম্ভবত এটি মূলত ভুল ... আমি কেবলমাত্র 2 থেকে 8 টি অক্ষর থেকে ছোট মানগুলি পরীক্ষা করেছি। প্রতিটি 10 ​​টি মানের জন্য তালিকা / হ্যাশসেট তৈরি করা হয়েছিল ... 30% হ্যাশসেট ধীর গতিতে ... তালিকার ক্ষমতা যদি ব্যবহার করা হয় তবে তার চেয়ে বেশি পার্থক্যও 40%। হ্যাশসেট কেবলমাত্র 10% এর জন্য দ্রুত হয়ে ওঠে যদি আমরা তালিকাটি নির্দিষ্ট ক্ষমতা ছাড়াই থাকে এবং পুরো তালিকার মাধ্যমে যুক্ত করার আগে প্রতিটি মান পরীক্ষা করে দেখি।
ম্যাক্সিম

যদি আইটেমগুলি 4 এ কমে যায় তবে তালিকাটি আবার খারাপতম পরিস্থিতিতেও জিততে পারে (10% পার্থক্য সহ)। সুতরাং আমি স্ট্রিংয়ের ছোট সংগ্রহের জন্য হ্যাশসেট ব্যবহার করার পরামর্শ দিচ্ছি না (আসুন <20)। এবং এটি আপনার "কয়েকটি ছোট" পরীক্ষার চেয়ে আলাদা।
ম্যাক্সিম

1
@ ম্যাক্সিম সত্যই বলতে পারবেন না যে আমার ফলাফলগুলি "ভুল" - এটি আমার মেশিনে ঘটেছিল। YMMV। আসলে, আমি কেবল তাদের আবার চালিয়েছি ( gist.github.com/zaus/014ac9b5a78b267aa1643d63d30c7554 ) একটি নতুন Win10 4.0GHz 16GB শক্ত রাষ্ট্র কম্পিউটারে এবং অনুরূপ ফলাফল পেয়েছি। আমি যে অবকাশটি দেখছি তা হ্যাশসেটের পারফরম্যান্সটি আরও সামঞ্জস্যপূর্ণ ছিল যেখানে অনুসন্ধান কী ছিল বা তালিকা কত বড়, যদিও তালিকার পারফরম্যান্স অবিচ্ছিন্নভাবে 300x এরও বেশি ধীরে ধীরে পরিবর্তিত হয়েছিল। তবে পলওয়ালস প্রথমদিকে যেমন মন্তব্য করেছিলেন আমরা গুরুতর # মাইক্রোপ্রটিমাইজেশন কথা বলছি।
ড্রজাউস

রেফারেন্সের জন্য ম্যাক্সিম: ডটনেটফিডেল.এন. / ৫ টিআরডিডি - এটির সাথে চারপাশে খেলতে নির্দ্বিধায়
ড্রজাউস

10

ব্রেকিংভেন হ্যাশ গণনার ব্যয়ের উপর নির্ভর করবে। হ্যাশ গণনাগুলি তুচ্ছ বা নাও হতে পারে ... :-) সর্বদা সিস্টেম.কলেশনস Sস্পেশালাইজড Hহাইব্রিডডিয়েশনারি ক্লাসটি আপনাকে ব্রেকডেভেন পয়েন্ট সম্পর্কে উদ্বিগ্ন না হওয়ার জন্য সহায়তা করে।


1
তুলনা করার জন্য আপনার ব্যয়টিও বিবেচনায় নেওয়া উচিত। কনটেইনস (টি) এর ক্ষেত্রে হ্যাশসেটটি তুলনা করে যাচাই করবে এটি হ্যাশের সংঘর্ষের তুলনায় বনাম তালিকার তুলনায় কাজ করবে না যা তালিকার প্রতিটি আইটেমের সাথে তুলনা করে এটি সঠিকটি আবিষ্কার করার আগে এটি দেখায়। আপনাকে টি.গেটহ্যাশকোড () দ্বারা উত্পাদিত হ্যাশগুলির বিতরণকেও ધ્યાનમાં নিতে হবে যেন এটি সর্বদা একই মান দেয় যা আপনি মূলত হ্যাশসেটকে তালিকার মতো একই কাজ করে যাচ্ছেন।
মার্টিন ব্রাউন

6

উত্তর, বরাবরের মতো, " এটি নির্ভর করে "। আপনি যে ট্যাগগুলি সি # এর কথা বলছেন তা থেকে আমি ধরে নিই।

আপনার সেরা বাজি নির্ধারণ করা হয়

  1. ডেটার একটি সেট
  2. ব্যবহারের প্রয়োজনীয়তা

এবং কিছু পরীক্ষার কেস লিখুন।

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

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

অতিরিক্ত:

অবশ্যই, আমার উপরের মন্তব্যগুলি 'পারফরম্যান্স' মানে ডেটা অ্যাক্সেস। অন্য কিছু বিবেচনা করার বিষয়: আপনি যখন "পারফরম্যান্স" বলছেন তখন আপনি কী খুঁজছেন? পারফরম্যান্সের স্বতন্ত্র মান কি সন্ধান করা হয়? এটি কি বড় (10000, 100000 বা আরও) মান সেটগুলির পরিচালনা? এটি কি ডেটা দিয়ে ডেটা স্ট্রাকচার পূরণের পারফরম্যান্স? ডেটা সরানো হচ্ছে? ডেটা পৃথক বিট অ্যাক্সেস? মান প্রতিস্থাপন? মূল্যবোধের উপর আইট্রেটিং? স্মৃতি এর ব্যবহার? ডাটা কপি করার গতি? উদাহরণস্বরূপ, আপনি যদি স্ট্রিং মান দ্বারা ডেটা অ্যাক্সেস করেন তবে আপনার প্রধান পারফরম্যান্সের প্রয়োজনীয়তা হ'ল ন্যূনতম মেমরির ব্যবহার, আপনার বিবাদী নকশার সমস্যা থাকতে পারে।


5

আপনি একটি হাইব্রিডডিয়েশনার ব্যবহার করতে পারেন যা ব্রেকিং পয়েন্টটি স্বয়ংক্রিয়ভাবে সনাক্ত করে এবং নাল-মানগুলি গ্রহণ করে, এটি হ্যাশসেটের মতোই প্রয়োজনীয় করে তোলে।


1
এটি ধারণার জন্য উত্সাহিত করেছে, তবে কেউ দয়া করে আজ কখনও এটি ব্যবহার করবেন না। অ জেনারিকদের বলুন না। এছাড়াও একটি অভিধান একটি মূল-মান ম্যাপিংস, সেটটি নয়।
নওফাল

4

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


3

আপনি যা করছেন তার উপর নির্ভর করে end যদি আপনার কীগুলি পূর্ণসংখ্যা হয় তবে হ্যাশসেটটি দ্রুত হওয়ার আগে আপনার সম্ভবত খুব বেশি আইটেমের দরকার নেই। যদি আপনি এটিকে স্ট্রিংয়ে চাপ দিচ্ছেন তবে এটি ধীর হবে এবং ইনপুট স্ট্রিংয়ের উপর নির্ভর করবে।

অবশ্যই আপনি খুব সহজেই একটি মানদণ্ড বেত্রাঘাত করতে পারে?


3

আপনার বিবেচনায় না নেওয়ার একটি কারণ হ'ল গেটহ্যাশকোড () ফাংশনটির দৃust়তা। একটি নিখুঁত হ্যাশ ফাংশন সহ হ্যাশসেটের স্পষ্টভাবে আরও ভাল অনুসন্ধান কার্যকারিতা থাকবে। তবে হ্যাশ ফাংশন হ্রাস হওয়ার সাথে সাথে হ্যাশসেট অনুসন্ধানের সময়টিও কমে যাবে।


0

অনেকগুলি কারণের উপর নির্ভর করে ... তালিকা বাস্তবায়ন, সিপিইউ আর্কিটেকচার, জেভিএম, লুপ শব্দার্থবিজ্ঞান, সমান পদ্ধতির জটিলতা ইত্যাদির ... তালিকাটি কার্যকরভাবে বেঞ্চমার্ক (1000+ উপাদান), হ্যাশ-ভিত্তিক বাইনারি হিসাবে যথেষ্ট বড় হয়ে যাওয়ার পরে অনুসন্ধানগুলি রৈখিক অনুসন্ধানগুলিকে হাতছাড়া করে, এবং পার্থক্যটি সেখান থেকে কেবল স্কেল আপ করে।

আশাকরি এটা সাহায্য করবে!


1
জেভিএম ... বা সিএলআর :-)
বিভিঘেলুওয়ে
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.