.NET HashTable Vs Dictionary - Apakah Kamus bisa secepat ini?


276

Saya mencoba mencari tahu kapan dan mengapa menggunakan Kamus atau HashTable. Saya telah melakukan sedikit pencarian di sini dan telah menemukan orang-orang berbicara tentang kelebihan generik dari Kamus yang saya sepenuhnya setujui, yang mengarahkan keuntungan tinju dan unboxing untuk sedikit peningkatan kinerja.

Tetapi saya juga telah membaca Kamus tidak akan selalu mengembalikan objek dalam urutan yang dimasukkan, hal itu diurutkan. Di mana sebagai HashTable akan. Seperti yang saya pahami ini mengarah ke HashTable yang jauh lebih cepat untuk beberapa situasi.

Pertanyaan saya sebenarnya, seperti apa situasi itu? Apakah saya salah dalam asumsi saya di atas? Situasi apa yang mungkin Anda gunakan untuk memilih satu di atas yang lain, (ya yang terakhir agak ambigu).


5
Saya tidak ingin membenarkan ini, tetapi karma Anda adalah 7.777 dan saya tidak ingin menjadi orang yang mengacaukan itu untuk Anda.
CaptainMarvel

Jawaban:


298

System.Collections.Generic.Dictionary<TKey, TValue>dan System.Collections.Hashtablekelas keduanya mempertahankan struktur data tabel hash secara internal. Tak satu pun dari mereka yang menjamin menjaga urutan barang.

Mengesampingkan masalah tinju / unboxing, sebagian besar waktu, mereka harus memiliki kinerja yang sangat mirip.

Perbedaan struktural utama di antara mereka adalah bahwa Dictionarybergantung pada rantai (menjaga daftar item untuk setiap kotak hash table) untuk menyelesaikan tabrakan sedangkan Hashtablemenggunakan rehashing untuk resolusi tabrakan (ketika tabrakan terjadi, mencoba fungsi hash lain untuk memetakan kunci ke ember) .

Ada sedikit manfaat menggunakan Hashtablekelas jika Anda menargetkan untuk .NET Framework 2.0+. Ini secara efektif dianggap usang oleh Dictionary<TKey, TValue>.


21
@ Jon- Chaining dan rehashing dibahas secara mendalam di sini- msdn.microsoft.com/en-us/library/ms379571(VS.80).aspx
RichardOD

Terima kasih semuanya. Baru saja menemukan halaman itu ketika Richard mempostingnya ... Akan bertanya tentang Chaining tetapi situs MSDN sebenarnya membantu!
Jon

6
@Mehrdad - Yang tidak jelas bagi saya tentang bagaimana tabrakan diselesaikan adalah ini: jika beberapa kunci dapat menghasilkan hash yang sama, maka bagaimana Anda memastikan Anda mendapatkan nilai yang tepat pada pencarian, yaitu bagaimana fungsi tahu elemen mana yang harus kembali? Dalam msdn.microsoft.com/en-us/library/ms379571%28VS.80%29.aspx itu mengatakan, "Daripada mengecam jika terjadi tabrakan, seperti yang dilakukan dengan kelas Hashtable, Kamus hanya rantai setiap tabrakan ke daftar ember. " Apakah ini berarti bahwa ketika menggunakan Kamus, tabrakan bukanlah sesuatu yang harus dikhawatirkan oleh pengembang?
Howiecamp

6
@ Howiecamp: Ini tidak jauh berbeda dari Hashtable. Tabel hash menyimpan 3 buah informasi dalam entri: hash kunci, kunci itu sendiri, dan nilai. Untuk item dengan hash yang sama, harus melintasi daftar untuk menemukan item dengan kunci yang sama dan mengembalikan nilainya. Ini juga cukup benar Hashtable. Sebagai pengembang menggunakan Dictionarynormal, Anda tidak perlu khawatir tentang hal itu.
Mehrdad Afshari

@Mehrdad Untuk memperjelas, kedua objek Hashtable dan Kamus menyimpan kunci itu sendiri, dan keduanya juga menyembunyikan tabrakan dari pengembang?
Howiecamp

111

Saya kira itu tidak berarti apa-apa bagi Anda sekarang. Tapi hanya untuk referensi bagi orang yang mampir

Uji Kinerja - SortedList vs. SortedDictionary vs. Kamus vs. Hashtable

Alokasi memori:

Tes kinerja penggunaan memori

Waktu yang digunakan untuk memasukkan:

Waktu yang digunakan untuk memasukkan

Waktu untuk mencari item:

Saatnya mencari item


Sangat menarik bahwa daftar yang diurutkan memiliki pencarian LEBIH CEPAT dari pada hashtable. Saya pikir hashtable adalah O (1) vs daftar diurutkan O (logn). Rupanya hashtable menyebalkan. Saya tidak akan pernah menggunakannya.
John Henckel

@JohnHenckel tidak, daftar yang diurutkan memiliki pencarian lebih lambat. Koefisien kinerja yang lebih besar berarti kinerja yang lebih baik dan penggunaan memori yang lebih baik. Jadi, daftar yang diurutkan memiliki penggunaan memori terbaik menurut bagan tetapi menyebalkan di daerah lain seperti memasukkan dan mencari.
C0DEF52

31

Perbedaan antara Hashtable dan Kamus

Kamus:

  • Kamus mengembalikan kesalahan jika kami mencoba menemukan kunci yang tidak ada.
  • Kamus lebih cepat daripada Hashtable karena tidak ada tinju dan unboxing.
  • Kamus adalah tipe umum yang artinya kita dapat menggunakannya dengan tipe data apa pun.

Hashtable:

  • Hashtable mengembalikan null jika kami mencoba menemukan kunci yang tidak ada.
  • Hashtable lebih lambat daripada kamus karena membutuhkan tinju dan unboxing.
  • Hashtable bukan tipe generik,

24

Perbedaan penting lainnya adalah bahwa tipe Hashtable mendukung banyak pembaca bebas kunci dan satu penulis pada saat yang sama, sedangkan Kamus tidak.


8
Concurrent Dictionary akan mendukung (.Net 4.0)
Tamilmaran

1
Saya tidak yakin apakah saya mengerti jawaban ini. Melihat di sini msdn.microsoft.com/en-us/library/... ia mengatakan "Untuk mendukung banyak penulis semua operasi pada Hashtable harus dilakukan melalui pembungkus yang dikembalikan oleh metode Disinkronkan, asalkan tidak ada utas membaca objek Hashtable. " Itu tampaknya membuat fitur "multi-pembaca bebas-kunci" sangat tidak berguna, jadi kita kembali harus mengunci semua akses ke Hashtable, seperti halnya dengan Kamus.
RenniePet

16

Artikel MSDN: " Dictionary<TKey, TValue>Kelas memiliki fungsi yang sama dengan Hashtablekelas. A Dictionary<TKey, TValue> dari tipe tertentu (selain Object) memiliki kinerja yang lebih baik daripada Hashtabletipe nilai karena elemen-elemennya Hashtablebertipe Objectdan, oleh karena itu, tinju dan unboxing biasanya terjadi jika menyimpan atau mengambil tipe nilai ".

Tautan: http://msdn.microsoft.com/en-us/library/4yh14awz(v=vs.90).aspx


11

Keduanya secara efektif adalah kelas yang sama (Anda dapat melihat pembongkaran). HashTable dibuat terlebih dahulu sebelum .Net memiliki obat generik. Kamus, bagaimanapun, adalah kelas generik dan memberi Anda manfaat mengetik yang kuat. Saya tidak akan pernah menggunakan HashTable karena Kamus tidak memberi biaya apa pun untuk Anda gunakan.


8

Perbedaan penting lainnya Hashtableadalah benang aman. Hashtabletelah dibangun di beberapa pembaca / penulis tunggal (MR / SW) keselamatan benang yang berarti Hashtablememungkinkan SATU penulis bersama dengan banyak pembaca tanpa mengunci. Dalam hal Dictionarytidak ada keamanan ulir, jika Anda membutuhkan pengaman ulir Anda harus menerapkan sinkronisasi Anda sendiri.

Untuk menguraikan lebih lanjut:

Hashtable, berikan keamanan benang melalui properti Synchronized, yang mengembalikan pembungkus aman di sekitar koleksi. Pembungkus bekerja dengan mengunci seluruh koleksi pada setiap operasi tambah atau hapus. Oleh karena itu, setiap utas yang mencoba mengakses koleksi harus menunggu gilirannya mengambil satu kunci. Ini tidak dapat diskalakan dan dapat menyebabkan penurunan kinerja yang signifikan untuk koleksi besar. Selain itu, desainnya tidak sepenuhnya terlindungi dari kondisi balapan.

Kelas-kelas .NET Framework 2.0 koleksi suka List<T>, Dictionary<TKey, TValue>, dll tidak menyediakan sinkronisasi thread; kode pengguna harus memberikan semua sinkronisasi ketika item ditambahkan atau dihapus pada banyak utas secara bersamaan. Jika Anda memerlukan keamanan jenis juga keamanan utas, gunakan kelas koleksi berbarengan dalam .NET Framework. Bacaan lebih lanjut di sini.


3

Kamus memiliki keuntungan menjadi tipe generik, yang membuatnya menjadi tipe yang aman dan sedikit lebih cepat karena kurangnya kebutuhan untuk tinju. Tabel perbandingan berikut (dibangun menggunakan jawaban yang ditemukan di pos pertanyaan SO serupa ) menggambarkan beberapa alasan lain yang mendukung kamus lebih dari tabel hash (atau sebaliknya).


1

Jika Anda ingin membaca yang akan selalu mengembalikan objek sesuai urutannya yang dimasukkan ke dalam Kamus, Anda dapat melihatnya

OrderedDictionary - nilai dapat diakses melalui indeks integer (berdasarkan urutan penambahan item) SortedDictionary - item diurutkan secara otomatis


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.