.NET HashTable Vs Dictionary - พจนานุกรมสามารถเร็วได้หรือไม่


276

ฉันพยายามที่จะคิดออกว่าเมื่อไหร่และทำไมต้องใช้พจนานุกรมหรือ HashTable ฉันได้ทำการค้นหาเล็กน้อยที่นี่และพบว่ามีคนพูดถึงข้อดีทั่วไปของพจนานุกรมที่ฉันเห็นด้วยอย่างสมบูรณ์ซึ่งนำไปสู่ความได้เปรียบในการชกมวยและการแกะกล่องเพื่อเพิ่มประสิทธิภาพเล็กน้อย

แต่ฉันได้อ่านพจนานุกรมจะไม่กลับวัตถุตามลำดับที่พวกเขาจะแทรกสิ่งที่เรียงลำดับ HashTable จะอยู่ที่ไหน ในขณะที่ฉันเข้าใจว่าสิ่งนี้นำไปสู่ ​​HashTable ที่เร็วขึ้นสำหรับบางสถานการณ์

คำถามของฉันเป็นจริงสถานการณ์เหล่านั้นอาจเป็นอย่างไร ฉันแค่คิดผิดไปจากข้อสันนิษฐานข้างต้นหรือไม่? คุณอาจใช้สถานการณ์ใดในการเลือกสถานการณ์หนึ่งเหนือสถานการณ์อื่น (ใช่สถานการณ์สุดท้ายค่อนข้างคลุมเครือ)


5
ฉันไม่อยากลงคะแนนเสียง แต่กรรมของคุณคือ 7,777 และฉันไม่ต้องการที่จะเป็นคนที่ยุ่งกับคุณ
CaptainMarvel

คำตอบ:


298

System.Collections.Generic.Dictionary<TKey, TValue>และSystem.Collections.Hashtableคลาสทั้งสองรักษาโครงสร้างข้อมูลตารางแฮชภายใน ไม่มีใครรับประกันการรักษาลำดับของรายการ

การออกจากการชกมวย / การแยกออกเป็นประเด็นส่วนใหญ่พวกเขาควรมีประสิทธิภาพที่คล้ายกันมาก

ความแตกต่างทางโครงสร้างหลักระหว่างพวกมันนั้นDictionaryขึ้นอยู่กับการผูกมัด (การบำรุงรักษารายการสำหรับแต่ละถังตารางแฮช) เพื่อแก้ไขการชนในขณะที่Hashtableใช้rehashingสำหรับการแก้ปัญหาการชนกัน (เมื่อเกิดการชนลองฟังก์ชันแฮชอีกอัน .

มีประโยชน์เล็กน้อยในการใช้Hashtableคลาสถ้าคุณกำหนดเป้าหมายสำหรับ. NET Framework 2.0+ Dictionary<TKey, TValue>มันแสดงผลได้อย่างมีประสิทธิภาพโดยล้าสมัย


21
@ Jon- การผูกมัดและการทำอุ่น
RichardOD

ขอบคุณทั้งคู่ เพิ่งพบหน้านั้นในขณะที่ Richard โพสต์ ... กำลังจะถามเกี่ยวกับ Chaining แต่เว็บไซต์ MSDN มีประโยชน์จริง ๆ
Jon

6
@ Mehrdad - มีอะไรไม่ชัดเจนสำหรับฉันเกี่ยวกับวิธีการแก้ไขการชนกันคือ: ถ้าหลาย ๆ คีย์อาจส่งผลให้เกิดการแฮชเดียวกันคุณจะมั่นใจได้อย่างไรว่าคุณได้รับคุณค่าที่ถูกต้องในการค้นหา กลับ? ใน msdn.microsoft.com/en-us/library/ms379571%28VS.80%29.aspxกล่าวว่า "แทนที่จะทำซ้ำในกรณีที่เกิดการชนเช่นเดียวกับคลาส Hashtable พจนานุกรมเพียงเชื่อมโยงการชนใด ๆ ลงในรายการถัง " นี่หมายความว่าเมื่อใช้พจนานุกรมการชนไม่ใช่สิ่งที่นักพัฒนาต้องกังวล
Howiecamp

6
@ Howiecamp: มันไม่ได้แตกต่างไปจากHashtableนี้จริงๆ ตารางแฮชเก็บข้อมูล 3 ชิ้นในรายการ: แฮชคีย์, คีย์เองและค่า สำหรับรายการที่มีแฮชเท่ากันคุณจะต้องสำรวจรายการเพื่อค้นหารายการที่มีคีย์เท่ากับและส่งคืนค่าของมัน นี่ก็เป็นความจริงHashtableด้วยเช่นกัน ในฐานะนักพัฒนาซอฟต์แวร์ที่ใช้งานDictionaryตามปกติคุณไม่จำเป็นต้องกังวลเกี่ยวกับมัน
Mehrdad Afshari

@ Mehrdad เพื่อให้ชัดเจนทั้งวัตถุ Hashtable และพจนานุกรมเก็บกุญแจเองและทั้งคู่ก็ซ่อนการชนจากนักพัฒนา?
Howiecamp

111

ฉันคิดว่ามันไม่ได้มีความหมายอะไรกับคุณเลย แต่สำหรับการอ้างอิงสำหรับคนที่หยุดโดย

การทดสอบประสิทธิภาพ - SortedList เทียบกับ SortedDictionary เทียบกับพจนานุกรมกับ Hashtable

การจัดสรรหน่วยความจำ:

ทดสอบประสิทธิภาพการใช้หน่วยความจำ

เวลาที่ใช้ในการใส่:

เวลาที่ใช้สำหรับใส่

เวลาสำหรับการค้นหารายการ:

เวลาในการค้นหารายการ


น่าสนใจมากที่รายการเรียงลำดับมีการค้นหาที่รวดเร็วกว่า hashtable ฉันคิดว่า hashtable คือ O (1) vs รายการที่เรียงลำดับ O (logn) เห็นได้ชัดว่า hashtable ดูด ฉันจะไม่ใช้มัน
John Henckel

@JohnHenckel ไม่รายการเรียงลำดับมีการค้นหาที่ช้ากว่า ค่าสัมประสิทธิ์ประสิทธิภาพที่ใหญ่กว่าหมายถึงประสิทธิภาพที่ดีขึ้นและการใช้หน่วยความจำที่ดีขึ้น ดังนั้นรายการที่เรียงมีการใช้หน่วยความจำที่ดีที่สุดตามแผนภูมิ แต่มันดูดในพื้นที่อื่น ๆ เช่นการแทรกและการค้นหา
C0DEF52

31

ความแตกต่างระหว่าง Hashtable และพจนานุกรม

พจนานุกรม:

  • พจนานุกรมส่งคืนข้อผิดพลาดหากเราพยายามหากุญแจที่ไม่มีอยู่
  • พจนานุกรมเร็วกว่า Hashtable เพราะไม่มีการชกมวยและไม่ตีออก
  • พจนานุกรมเป็นประเภททั่วไปซึ่งหมายความว่าเราสามารถใช้กับประเภทข้อมูลใด ๆ

Hashtable:

  • Hashtable ส่งกลับค่า null ถ้าเราพยายามค้นหาคีย์ที่ไม่มีอยู่
  • Hashtable ช้ากว่าพจนานุกรมเพราะต้องใช้การชกมวยและไม่ตีกล่อง
  • Hashtable ไม่ใช่ประเภททั่วไป

24

ข้อแตกต่างที่สำคัญอีกประการหนึ่งคือประเภท Hashtable รองรับผู้อ่านหลายคนที่ไม่ล็อคและตัวเขียนเดียวในเวลาเดียวกันขณะที่ Dictionary ไม่รองรับ


8
พจนานุกรมที่เกิดขึ้นพร้อมกันจะให้การสนับสนุน (.Net 4.0)
ทมิฬมารัน

1
ฉันไม่แน่ใจว่าฉันเข้าใจคำตอบนี้หรือไม่ ดูที่นี่msdn.microsoft.com/en-us/library/…มีข้อความระบุว่า "เพื่อสนับสนุนนักเขียนหลายคนการดำเนินการทั้งหมดบน Hashtable จะต้องทำผ่าน wrapper ที่ส่งคืนโดยวิธีการซิงโครไนซ์โดยที่ไม่มีเธรดที่อ่านวัตถุ Hashtable " ดูเหมือนว่าจะทำให้ฟีเจอร์ "ตัวอ่านหลายตัวที่ไม่ต้องล็อค" นั้นไร้ประโยชน์ดังนั้นเราจึงกลับไปล็อคการเข้าถึง Hashtable ทั้งหมดเช่นเดียวกับพจนานุกรม
RenniePet

16

บทความ MSDN: " Dictionary<TKey, TValue>คลาสที่มีฟังก์ชันการทำงานเหมือนกับHashtableคลาส A Dictionary<TKey, TValue> ของชนิดเฉพาะ (นอกเหนือจากObject) มีประสิทธิภาพที่ดีกว่า Hashtableสำหรับประเภทค่าเนื่องจากองค์ประกอบHashtableของชนิดObjectและดังนั้นมวยและ unboxing มักจะเกิดขึ้นถ้าเก็บหรือ การดึงค่าประเภท "

ลิงก์: http://msdn.microsoft.com/en-us/library/4yh14awz(v=vs.90).aspx


11

ทั้งสองเป็นคลาสเดียวกันอย่างมีประสิทธิภาพ (คุณสามารถดูการถอดแยกชิ้นส่วน) HashTable ถูกสร้างขึ้นครั้งแรกก่อนที่. Net จะมี generics อย่างไรก็ตามพจนานุกรมเป็นคลาสทั่วไปและให้ประโยชน์ในการพิมพ์ที่ดี ฉันจะไม่ใช้ HashTable เนื่องจากพจนานุกรมไม่มีค่าใช้จ่ายในการใช้


8

ความแตกต่างที่สำคัญอีกอย่างหนึ่งก็Hashtableคือความปลอดภัยของเธรด Hashtableได้สร้างขึ้นในความปลอดภัยของเธรดอ่าน / เดี่ยวนักเขียน (MR / SW) หลายซึ่งหมายความว่าHashtableช่วยให้หนึ่งตัวเขียนร่วมกับผู้อ่านหลายคนโดยไม่ต้องล็อค ในกรณีที่Dictionaryไม่มีความปลอดภัยของเธรดถ้าคุณต้องการความปลอดภัยของเธรดคุณต้องใช้การซิงโครไนซ์ของคุณเอง

หากต้องการรายละเอียดเพิ่มเติม:

Hashtableให้ความปลอดภัยของเธรดผ่านคุณสมบัติการซิงโครไนซ์ซึ่งจะส่งคืน wrapper ที่ปลอดภัยสำหรับการทำงาน เสื้อคลุมทำงานโดยการล็อคคอลเลกชันทั้งหมดในทุกการดำเนินการเพิ่มหรือลบ ดังนั้นแต่ละเธรดที่พยายามเข้าถึงคอลเลกชันจะต้องรอการเลี้ยวเพื่อล็อคหนึ่งครั้ง สิ่งนี้ไม่สามารถปรับขนาดได้และอาจทำให้ประสิทธิภาพลดลงอย่างมากสำหรับคอลเลกชันขนาดใหญ่ นอกจากนี้การออกแบบไม่ได้รับการปกป้องอย่างสมบูรณ์จากสภาพการแข่งขัน

เรียน NET Framework 2.0 คอลเลกชันชอบ List<T>, Dictionary<TKey, TValue>ฯลฯ ไม่ให้ตรงกันด้ายใด ๆ รหัสผู้ใช้ต้องมีการซิงโครไนซ์ทั้งหมดเมื่อมีการเพิ่มหรือลบรายการในหลายเธรดพร้อมกันหากคุณต้องการความปลอดภัยในการพิมพ์เช่นกันสำหรับความปลอดภัยของเธรดให้ใช้คลาสการรวบรวมพร้อมกันใน. NET Framework อ่านเพิ่มเติมที่นี่


3

พจนานุกรมมีข้อดีของการเป็นประเภททั่วไปซึ่งทำให้พิมพ์ปลอดภัยและเร็วขึ้นเนื่องจากขาดความจำเป็นในการชกมวย ตารางเปรียบเทียบต่อไปนี้(สร้างขึ้นโดยใช้คำตอบที่พบในโพสต์คำถาม SO ที่คล้ายกัน) แสดงเหตุผลบางประการที่สนับสนุนพจนานุกรมบนตารางแฮช (หรือในทางกลับกัน)


1

หากคุณสนใจเกี่ยวกับการอ่านที่มักจะส่งคืนวัตถุตามลำดับที่พวกเขาถูกแทรกลงในพจนานุกรมคุณอาจจะดู

OrderedDictionary - ค่าสามารถเข้าถึงได้ผ่านดัชนีจำนวนเต็ม (ตามลำดับที่เพิ่มรายการ) SortedDictionary - รายการจะถูกจัดเรียงโดยอัตโนมัติ


0

พจนานุกรมเร็วกว่า hashtable เนื่องจากพจนานุกรมเป็นประเภททั่วไปที่แข็งแกร่ง Hashtable ช้าลงเนื่องจากใช้วัตถุเป็นชนิดข้อมูลซึ่งนำไปสู่การชกมวยและการเลิกทำกล่อง


2
phase9studios.com/post/2008/01/08/DictionaryVSHashTable.aspx โปรดอ่านความคิดเห็นด้านล่างบทความ
Arvand

4
@Arvand Link broken - ขายโดเมน
RenniePet
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.