Analyze the C # Set internally -- Dictionary

Source: Internet
Author: User

Dictionary and hashtable are similar in usage. They are all data sets based on key-value pairs, but in fact their internal implementation principles are quite different. First, let's briefly outline their main differences, later, we will analyze the general principle of the internal implementation of Dictionary. Difference: 1. Dictionary supports generics, but Hashtable does not. 2. Dictionary does not have the Load Facto concept. It is only resized when the capacity is insufficient (just like Hashtable, it is also twice the minimum Prime Number of the current capacity ), hashtable is a scale-out when the length of "loaded element" and "bucket array" is greater than the load factor. 3. the array of values stored in Dictionary is sorted in the order of insertion. Hashtable is not. 4. When no collision occurs, you need to perform two index locating for the query Dictionary, and the Hashtable needs to be performed once ,. Dictionary uses the Division hash method to calculate the storage address. If you want to know more, you can use Baidu. In short, it has two internal Arrays: buckets array and entries array (entries is an Entry structure array), entries has a next to simulate the linked list, this field stores an int value, point to the next storage address (actually the index of the bukets array). If no collision occurs, this field is-1. If a collision occurs, an int value is stored. This value points to the bukets array. as shown in the following figure, when you use a Dictionary normally, you can see how it is implemented internally. 1. instantiate a Dictionary, Dictionary <string, string> dic = new Dictionary <string, string> (); a. Call the Dictionary constructors without parameters by default. B. initialize the array container inside the Dictionary: buckets int [] and entries <T, V> [], respectively, with a length of 3. (There is an array of prime numbers: 3, 7, 11, 17 ....); 2. Add a value to dic. add ("a", "abc"); a: Expand the bucket array and the entries array to three lengths. B. Calculate the hash value of "a", c, and perform the modulo calculation with the bucket array length (3). If the result is: 2 d, because a is the first write, the value of a is automatically assigned to the key of entriys [0]. Similarly, "abc" is assigned to entriys [0]. value. The hash value of Step B is assigned to entriys [0]. hashCode, entriys [0]. the next value is-1, and the hashCode value is the hash value calculated in step B. E. Store 0 in bucket [2. 3. obtain the corresponding value through the key. var v = dic ["a"]; a: Calculate the hash value of "a" first. If the result is 2, B, based on the results of the previous step, find the value of the buckets array index on 2, if the value is 0. c. Find the key with an index of 0 on the entriys array. 1) if the key value is the same as the input "a" character, the corresponding value is the value to be searched. 2) If the key value is different from the input "a" character, it indicates that a collision occurs and the corresponding next value is obtained, locate the buckets array (buckets [next]) based on the next value, and then obtain the values stored on the corresponding buckets to locate the value on the entriys array ,......, until it is found. 3) if the key value is different from the input "a" character and the corresponding next value is-1, Dictionary does not contain the character "". Other methods in Dictionary will not be mentioned. You can view the source code by yourself. Next we will compare the addition and search performance of Hashtable and Dictionary through experiments. 1. Add element speed evaluation. 5 cycles, and the average value is obtained 10 times in each internal loop. PS: if there is any unfairness in the code, I hope you can point out that I will change it if I know the error. Code: copy the code static void Main (string [] args) {for (int I = 0; I <5; I ++) {Console. writeLine (string. format ("execution at {0}:", I + 1); Add (); Console. writeLine ("------- gorgeous separation line ---------");} Console. readKey () ;}public static void Add () {Hashtable ht = new Hashtable (); Stopwatch st = new Stopwatch (); long ticks1 = 0; for (int j = 0; j <10; j ++) {st. reset (); st. start (); for (int I = 0; I <1000000; I ++ ){ Ht. add (I, I);} st. stop (); ticks1 + = st. elapsedTicks; ht. clear ();} Console. writeLine (string. format ("Hashtable Add: {0} elements, consumption: {1}", 1000000, ticks1/10); Dictionary <int, int> dic = new Dictionary <int, int> (); ticks1 = 0; for (int j = 0; j <10; j ++) {st. reset (); st. start (); for (int I = 0; I <1000000; I ++) {dic. add (I, I);} st. stop (); ticks1 + = st. elapsedTicks; dic. clear ();} Console. writeLine (s Tring. format ("Dictionary Add: {0} elements, consumption: {1}", 1000000, st. elapsedTicks);} copy the code result: the running result shows that the HashTable speed is significantly slower than that of Dictionary, with an order of magnitude different. The reason for my personal analysis may be: a. Hashtable does not support generics. The int type I added to you will be boxed, while Dictionary supports generics. B. During expansion, Hashtable will first create a larger array and then copy the original data to the new array, you also need to re-hash the key in the new array (this may be the most influential factor in performance ). Dictionary does not. 2. Search speed evaluation (two cases: Value Type and reference type) 1. Copy the code static void Main (string [] args) {// GetByString (); getByInt (); Console. readKey ();} public static void GetByInt () {// Hashtable hs = new Hashtable (); Dictionary <int, int> dic = new Dictionary <int, int> (); for (int I = 0; I <10000000; I ++) {hs. add (I, I); dic. add (I, I);} long ticks = 0; Stopwatch st = new Stopwatch (); st. reset (); for (int I = 0; I <1 0; I ++) {st. start (); var result = hs [99999 + I]; st. stop (); ticks + = st. elapsedTicks; st. reset ();} Console. writeLine (string. format ("Hashtable 10 times, average consumption: {0}", (float) ticks/10); // Dictionary ticks = 0; st. reset (); for (int I = 0; I <10; I ++) {st. start (); var result = dic [I]; st. stop (); ticks + = st. elapsedTicks; st. reset ();} Console. writeLine (string. format ("Dictionary Search 10 times, average consumption: {0}", (float) tic Ks/10);} copy code execution result 2, reference type copy code 1 static void Main (string [] args) 2 {3 GetByString (); 4 5 Console. readKey (); 6} 7 8 public static void GetByString () 9 {10 // Hashtable11 Hashtable hs = new Hashtable (); 12 Dictionary <string, string> dic = new Dictionary <string, string> (); 13 14 for (int I = 0; I <1000000; I ++) 15 {16 hs. add (I. toString (), I. toString (); 17 dic. add (I. toString (), I. toString (); 18} 19 l Ong ticks = 0; 20 Stopwatch st = new Stopwatch (); 21 st. reset (); 22 string key = "9999"; 23 for (int I = 0; I <10; I ++) 24 {25 st. start (); 26 var result = hs [key]; 27 st. stop (); 28 ticks + = st. elapsedTicks; 29 st. reset (); 30} 31 Console. writeLine (string. format ("Hashtable Search 10 times, average consumption: {0}", (float) ticks/10); 32 33 // Dictionary34 ticks = 0; 35 st. reset (); 36 for (int I = 0; I <10; I ++) 37 {38 st. start (); 39 var Result = dic [key]; 40 st. stop (); 41 ticks + = st. elapsedTicks; 42 st. reset (); 43} 44 Console. writeLine (string. format ("Dictionary Search 10 times, average consumption: {0}", (float) ticks/10); 45} copy the code running result. Based on the above experiment results, we can get:, value type. The performance of Hashtable and Dictionary is slightly different. Hashtable is slightly faster than Dictionary. b. Reference Type: Hashtable is faster than Dictionary.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.