Khi nào sử dụng Tuple tốt hơn so với KeyValuePair?


90

Tôi thường sử dụng KeyValuePair<TKey,TValue>kiểu này bất cứ khi nào tôi có dữ liệu có liên quan đến cặp theo nghĩa rằng cái này là chìa khóa cho cái kia. Nếu dữ liệu không liên quan thì Tuple<T1,T2>loại có ý nghĩa hơn và tôi sẽ đi với điều đó.

Bây giờ tôi chỉ đọc bài viết này về lý do tại sao nói chung nên tránh KeyValuePair<TKey,TValue>và thích hơn Tuple<T1,T2>. Đối số chính là lợi ích hiệu suất của Tuple<T1,T2>.

Hiệu suất bên ngoài, có lý do nào KVP sẽ là lựa chọn tốt hơn a Tuple<T1,T2>?


4
A KeyValuePairlà một khóa và một giá trị, a Tuple<T1,T2>chỉ là một cặp giá trị bằng nhau . Bạn cũng có thể hỏi: "tại sao tôi nên sử dụng List<Class>nếu tôi có thể sử dụng Dictionary<A,B>".
Tim Schmelter

4
Đúng, nhưng trong trường hợp đó, bạn có thể sử dụng chìa khóa để tra cứu dữ liệu. Nó có nghĩa là gì đó. Trong trường hợp này, những cái tên chỉ là ngữ nghĩa, họ làm bất cứ điều gì không bình (bộ xử lý.)
Nick Gotch

1
Một bộ giá trị không phải là một cặp giá trị bằng nhau, mà là một số loại bằng nhau. Có thể điều này được coi là nitpicking, nhưng ví dụ: C có cấu trúc liên hợp cho các biểu diễn khác nhau có giá trị bằng nhau. :)
Jonas

Câu trả lời:


65

Chà, loại có thể được coi là kém tên tuổi, đối với một loại. KeyValuePair như được đặt tên phải đại diện cho một khóa và một giá trị. Điều gì sẽ xảy ra nếu hai đối tượng của bạn không thực sự là một khóa và một giá trị, chỉ là hai thứ? Nếu tôi thấy một phương thức hoặc thuộc tính có kiểu KeyValuePair<TKey, TValue>, tôi sẽ mong đợi các giá trị của KVP là một khóa và một giá trị. Đây thực sự chỉ là vấn đề truyền đạt ý định và làm rõ điều đó với chính bạn trong tương lai hoặc có thể là các thành viên khác trong nhóm. Một bộ giá trị không chỉ ra kiểu liên kết đó.

Tuples cũng giúp bạn dễ dàng thêm một giá trị khác, biến nó thành một bộ 3 (hoặc bộ ba, tuy nhiên bạn muốn gọi nó). Một số ngôn ngữ .NET, như F #, cũng có cú pháp đặc biệt xung quanh các bộ giá trị.

Đối với quan điểm thực hiện, Tuplenhiều thứ KeyValuePairkhông. Các bộ giá trị có thể so sánh được, chúng triển khai các giao diện IComparableIStructuralEquatable, do đó, việc so sánh hai bộ giá trị dễ dàng hơn.


1
Tôi đã tìm ra cách khó mà bạn có thể đưa KeyValuePairs vào từ điển nhưng sẽ không bao giờ nhận được kết quả sau đó.
MKesper

3
Ngoài ra, C # 7.0 mới hỗ trợ cú pháp mới, đơn giản hơn cho Tuples, làm cho chúng dễ dàng hiệu quả hơn nhiều so với KeyValuePairs. visualstudiomagazine.com/articles/2017/01/01/…
Jacob Stamm

1
Ngoài ra, khả năng đặt tên các tham số trong các bộ giá trị giúp người tiêu dùng dễ dàng hiểu chúng được sử dụng để làm gì. Trong một cách chung chung như KVP, đó thực sự là suy đoán của bất kỳ ai - trừ khi nó được ghi lại cụ thể ở đâu đó - khóa được cho là "là" - nghĩa là không phải loại của nó mà là thứ trong thế giới thực, như tên đặt, số bảo mật, v.v.
rory.ap 21/12/18

40

KeyValuePairlà cấu trúc và Tuplelà một lớp.

Đó là sự khác biệt chính ảnh hưởng đến cách các đối tượng được sao chép cho dù bằng tham chiếu hay giá trị.

và do đó Tuple<T1,T2>khi được truyền xung quanh chỉ sử dụng "4byte" trong hệ điều hành 32bit, trong khi KeyValuePair<K,V>yêu cầu nhiều hơn dựa trên "K và V"

Nhưng dù sao thì việc so sánh Tuple và KeyValuePair không phải là một ý kiến ​​hay (không hợp lý với tôi) vì cả hai đều phục vụ mục đích khác nhau.


2
Làm thế nào họ phục vụ một mục đích khác nhau? bạn vui lòng giải thích về nó.
OldSchool

1
@YakRangi keyvaluepair được sử dụng làm nơi chứa các khóa và giá trị trong từ điển, nếu không thì nó không có mục đích gì. Mặt khác, Tuple có thể được sử dụng để lưu trữ bất kỳ thành viên nào có liên quan với nhau. Ngoài ra với tuple bạn có thể lưu trữ nhiều thành viên kết hợp không chỉ 2.
Sriram Sakthivel

@SriramSakthivel Điều này có nghĩa là, câu trả lời cho câu hỏi OP là: không sử dụng KVP, trừ khi bạn đang duyệt Từ điển.
Alex Fainshtein

23

Bất chấp ngữ nghĩa, hiệu suất có thể là một yếu tố quan trọng khi bạn xem xét cả hai lựa chọn. Như đã đề cập trước đây, KeyValuePairlà một kiểu giá trị (struct), trong khi đó Tuple<>là một kiểu tham chiếu (lớp). Do đó, cái KeyValuePairđược cấp phát trên ngăn xếp và Tuple<>được cấp phát trên đống, và lựa chọn tối ưu thường được xác định bởi các đối số cổ điển của Phân bổ bộ nhớ ngăn xếp so với . Tóm lại, không gian ngăn xếp có giới hạn, nhưng nhìn chung có khả năng truy cập rất nhanh. Bộ nhớ heap lớn hơn nhiều nhưng hơi chậm hơn.

KeyValuePair<T1, T2>có thể là lựa chọn tốt hơn nếu cả hai khóa và giá trị loại là nguyên thủy (kiểu giá trị thích int, bool, double, vv) hoặc cấu trúc có kích thước nhỏ. Với các kiểu nguyên thủy trên ngăn xếp, việc phân bổ và phân bổ giao dịch diễn ra nhanh như chớp. Điều này thực sự có thể ảnh hưởng đến hiệu suất, đặc biệt là đối số để gọi phương thức đệ quy.

Mặt khác, Tuple<T1, T2>có thể là lựa chọn tốt hơn nếu một trong hai T1hoặc T2là các kiểu tham chiếu (như các lớp). Loại KeyValuePairchứa các con trỏ tới các kiểu tham chiếu (như kiểu khóa hoặc giá trị) sẽ đánh bại mục đích vì dù sao thì các đối tượng cũng cần được tra cứu trên heap.

Đây là điểm chuẩn mà tôi tìm thấy trực tuyến: Tuple so với KeyValuePair . Vấn đề duy nhất với điểm chuẩn này là họ đã thử nghiệm KeyValuePair<string, string>so với Tuple<string, string>stringkiểu này là một kiểu bất thường và đặc biệt trong .NET ở chỗ nó có thể hoạt động giống như kiểu giá trị và / hoặc kiểu tham chiếu tùy thuộc vào ngữ cảnh thực thi. Tôi tin rằng KeyValuePair<int, int>sẽ là một người chiến thắng rõ ràng chống lại Tuple<int, int>. Tuy nhiên, ngay cả với những khiếm khuyết, kết quả cho thấy sự khác biệt về hiệu suất có thể là đáng kể:

8,23 ns - Phân bổ Tuple
0,32 ns - Phân bổ KeyValuePair (nhanh hơn 25 lần!)

1,93 ns - Truyền Tuple dưới dạng đối số
2,57 ns - Truyền KeyValuePair làm đối số

1,91 ns - Return Tuple
6,09 ns - Return KeyValuePair

2,79 ns - Tải Tuple từ Danh sách
4,18 ns - Tải KeyValuePair từ Danh sách


0

Bạn thực sự hỏi sai câu hỏi, câu hỏi thích hợp đang sử dụng Lớp (Tuple) _ tốt hơn là Cấu trúc (KVP) trong trường hợp đó câu trả lời là bạn muốn sử dụng chúng để làm gì và câu trả lời được đưa ra ở đây Cấu trúc so với lớp


2
Anh ấy đã hỏi đúng câu hỏi. Câu hỏi về cách sử dụng nào tốt hơn được ngụ ý một cách rõ ràng.
Greg

@ Greg câu hỏi là đó là sô cô la tốt hơn hoặc soda, tuy nhiên các câu hỏi cụ thể là vô nghĩa và tốt hơn giải quyết như một câu hỏi chung về thực phẩm và đồ uống
MikeT

3
Câu hỏi defacto là "Khi nào tôi nên sử dụng Tuples Vs. KeyPairs?". Đây là một câu hỏi chính đáng. Tôi nghĩ rằng bạn chỉ đang bị mắc kẹt về ngữ nghĩa của từ "tốt hơn".
Greg
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.