Kapan lebih baik menggunakan Tuple versus KeyValuePair?

90

Saya biasanya menggunakan KeyValuePair<TKey,TValue>tipe setiap kali saya memiliki data yang terkait dengan pasangan dalam arti bahwa satu adalah kunci bagi yang lain. Jika datanya tidak terkait maka Tuple<T1,T2>jenisnya lebih masuk akal dan saya akan melakukannya.

Sekarang saya baru saja membaca artikel ini tentang mengapa umumnya menghindari KeyValuePair<TKey,TValue>dan memilih Tuple<T1,T2>. Argumen utama adalah manfaat kinerja Tuple<T1,T2>.

Di luar kinerja, adakah alasan KVP menjadi pilihan yang lebih baik daripada Tuple<T1,T2>?

Nick Gotch
sumber
4
A KeyValuePairadalah kunci dan nilai, a Tuple<T1,T2>hanyalah sepasang nilai yang sama . Anda juga bisa bertanya: "mengapa saya harus menggunakan List<Class>jika saya dapat menggunakan Dictionary<A,B>".
Tim Schmelter
4
Benar, tetapi dalam hal ini Anda dapat menggunakan kunci untuk mencari data. Itu berarti sesuatu. Dalam hal ini, nama hanyalah semantik, tidak berarti apa-apa (bagi prosesor.)
Nick Gotch
1
Tupel bukanlah sepasang nilai yang sama, tetapi beberapa jenis yang sama. Mungkin ini terlihat sebagai nitpicking, tetapi misalnya C memang memiliki konstruksi gabungan untuk representasi berbeda dari nilai yang sama. :)
Jonas

Jawaban:

65

Yah, jenisnya bisa dianggap nama yang buruk, untuk satu. KeyValuePair seperti yang dinamai harus mewakili kunci dan nilai. Bagaimana jika kedua objek Anda sebenarnya bukan kunci dan nilai, hanya dua hal? Jika saya melihat metode atau properti yang memiliki tipe KeyValuePair<TKey, TValue>, saya berharap nilai KVP menjadi kunci dan nilai. Ini benar-benar hanya masalah mengkomunikasikan niat dan menjelaskan kepada diri Anda sendiri di masa depan, atau mungkin anggota tim lainnya. Tupel tidak menunjukkan asosiasi semacam itu.

Tupel juga memudahkan untuk menambahkan nilai lain, menjadikannya 3-tupel (atau triplet, bagaimanapun Anda ingin menyebutnya). Beberapa bahasa NET, seperti F #, memiliki sintaks khusus di sekitar tupel juga.

Untuk perspektif implementasi, Tuplebanyak hal KeyValuePairtidak. Tupel sebanding, mereka mengimplementasikan antarmuka IComparabledan IStructuralEquatable, sehingga memudahkan untuk membandingkan dua tupel.

vcsjones.dll
sumber
1
Saya menemukan cara yang sulit bahwa Anda dapat memasukkan KeyValuePairs ke dalam kamus tetapi tidak akan pernah mendapatkan hasil saat itu.
MKesper
3
Selain itu, C # 7.0 baru mendukung sintaks baru yang lebih sederhana untuk Tuple, membuatnya lebih mudah dan berkinerja untuk digunakan daripada KeyValuePairs. visualstudiomagazine.com/articles/2017/01/01/…
Jacob Stamm
1
Selain itu, kemampuan untuk menamai parameter dalam tuple memudahkan konsumen untuk memahami untuk apa parameter tersebut digunakan. Dalam generik seperti KVP, itu benar-benar tebakan siapa pun - kecuali jika didokumentasikan secara khusus di suatu tempat - apa kuncinya seharusnya "menjadi" - yaitu bukan jenisnya tetapi apa hal dunia nyata itu, seperti nama pengaturan, sosial nomor keamanan, dll.
rory
40

KeyValuePairadalah struct dan Tuplemerupakan kelas.

Itulah perbedaan utama yang mempengaruhi bagaimana objek disalin baik dengan referensi maupun nilai.

dan karenanya Tuple<T1,T2>ketika diedarkan hanya menggunakan "4byte" di OS 32bit, sedangkan KeyValuePair<K,V>membutuhkan lebih banyak berdasarkan "K dan V"

Bagaimanapun membandingkan Tuple dan KeyValuePair bukanlah ide yang baik (tidak masuk akal bagi saya) karena keduanya memiliki tujuan yang berbeda.

Sriram Sakthivel
sumber
2
Bagaimana mereka melayani tujuan yang berbeda? maukah Anda menjelaskannya.
OldSchool
1
@YakRangi keyvaluepair dimaksudkan untuk digunakan sebagai wadah untuk kunci dan nilai dalam kamus jika tidak, itu tidak memiliki tujuan. Di sisi lain, Tuple dapat digunakan untuk menyimpan semua anggota yang terkait secara sewenang-wenang. Juga dengan Tuple Anda dapat menyimpan banyak anggota yang digabungkan tidak hanya 2.
Sriram Sakthivel
@SriramSakthivel Artinya, jawaban untuk pertanyaan OP adalah: jangan gunakan KVP, kecuali Anda sedang menjelajahi Kamus.
Alex Fainshtein
23

Terlepas dari semantiknya, kinerja mungkin menjadi pertimbangan penting saat Anda mempertimbangkan kedua opsi tersebut. Seperti yang disebutkan sebelumnya, KeyValuePairadalah tipe nilai (struct), sedangkan Tuple<>adalah tipe referensi (kelas). Oleh karena itu, the KeyValuePairdialokasikan di stack dan Tuple<>dialokasikan di heap, dan pilihan optimal biasanya ditentukan oleh argumen klasik Stack vs. Heap Memory Allocation . Singkatnya, ruang tumpukan terbatas, tetapi umumnya memiliki akses yang sangat cepat. Memori heap jauh lebih besar tetapi agak lebih lambat.

KeyValuePair<T1, T2>mungkin menjadi pilihan yang lebih baik jika kedua kunci dan nilai jenis yang primitif (jenis nilai seperti int, bool, double, dll) atau struct dari ukuran kecil. Dengan tipe primitif pada stack, alokasi dan deallocation sangat cepat. Ini benar-benar dapat memengaruhi performa, terutama sebagai argumen untuk panggilan metode rekursif.

Di sisi lain, Tuple<T1, T2>kemungkinan adalah pilihan yang lebih baik jika salah satu T1atau T2tipe referensi (seperti kelas). A KeyValuePairyang berisi pointer ke jenis referensi (sebagai kunci atau tipe nilai) semacam mengalahkan tujuan karena objek tetap perlu dicari di heap.

Ini patokan yang saya temukan secara online: Tuple vs. KeyValuePair . Satu-satunya masalah dengan tolok ukur ini adalah bahwa mereka menguji KeyValuePair<string, string>vs. Tuple<string, string>, dan stringtipenya adalah tipe yang tidak biasa dan khusus dalam .NET yang dapat berperilaku seperti tipe nilai dan / atau tipe referensi tergantung pada konteks eksekusi. Saya yakin itu KeyValuePair<int, int>akan menjadi pemenang yang jelas melawan Tuple<int, int>. Meskipun terdapat kekurangan, namun, hasilnya menunjukkan bahwa perbedaan kinerja dapat menjadi signifikan:

8,23 ns - Alokasikan Tuple
0,32 ns - Alokasikan KeyValuePair (25x lebih cepat!)

1,93 ns - Lewati Tuple sebagai argumen
2,57 ns - Lulus KeyValuePair sebagai argumen

1,91 ns - Kembali Tuple
6,09 ns - Kembalikan KeyValuePair

2.79 ns - Muat Tuple dari Daftar
4.18 ns - Muat KeyValuePair dari Daftar

Saus Khusus
sumber
0

Anda benar-benar menanyakan pertanyaan yang salah, pertanyaan yang tepat adalah menggunakan Kelas (Tuple) _ lebih baik daripada Struct (KVP) dalam hal ini jawabannya adalah untuk apa Anda ingin menggunakannya dan jawabannya diberikan di sini Struktur versus kelas

MikeT
sumber
2
Dia menanyakan pertanyaan yang tepat. Pertanyaan tentang mana yang lebih baik untuk penggunaan apa yang tersirat secara eksplisit.
Greg
@Greg pertanyaannya adalah mana yang lebih baik cokelat atau soda, namun pertanyaan spesifiknya tidak ada gunanya dan lebih baik ditujukan sebagai pertanyaan umum tentang makanan dan minuman
MikeT
3
Pertanyaan defacto adalah "Kapan saya harus menggunakan Tuples Vs. KeyPairs?". Ini adalah pertanyaan yang sah. Saya pikir Anda hanya terjebak pada semantik dari kata "lebih baik".
Greg