มีความแตกต่างในทางปฏิบัติจริงระหว่าง a SortedList<TKey,TValue>
และ a SortedDictionary<TKey,TValue>
หรือไม่? มีสถานการณ์ใดบ้างที่คุณจะใช้อย่างใดอย่างหนึ่งโดยเฉพาะ
SortedList<TKey,TValue>
มากกว่าหนึ่งSortedList<T>
? ทำไมมันไม่ใช้IList<T>
?
มีความแตกต่างในทางปฏิบัติจริงระหว่าง a SortedList<TKey,TValue>
และ a SortedDictionary<TKey,TValue>
หรือไม่? มีสถานการณ์ใดบ้างที่คุณจะใช้อย่างใดอย่างหนึ่งโดยเฉพาะ
SortedList<TKey,TValue>
มากกว่าหนึ่งSortedList<T>
? ทำไมมันไม่ใช้IList<T>
?
คำตอบ:
ใช่ - คุณสมบัติด้านประสิทธิภาพแตกต่างกันอย่างมีนัยสำคัญ มันอาจจะเป็นการดีกว่าถ้าจะเรียกพวกเขาSortedList
และSortedTree
สะท้อนให้เห็นถึงการดำเนินการอย่างใกล้ชิดยิ่งขึ้น
ดูเอกสาร MSDN สำหรับแต่ละรายการ ( SortedList
, SortedDictionary
) เพื่อดูรายละเอียดของประสิทธิภาพสำหรับการทำงานที่แตกต่างกันในไซต์ที่ต่างกัน นี่เป็นบทสรุปที่ดี (จากSortedDictionary
เอกสาร):
SortedDictionary<TKey, TValue>
ระดับทั่วไปเป็นต้นไม้ค้นหาแบบทวิภาคกับ O (log n) การดึงที่ n คือจำนวนขององค์ประกอบในพจนานุกรม ในสิ่งนี้มันคล้ายกับSortedList<TKey, TValue>
คลาสทั่วไป คลาสที่สองมีโมเดลวัตถุที่คล้ายกันและทั้งสองมีการดึงข้อมูล O (log n) โดยที่ทั้งสองคลาสต่างกันคือการใช้หน่วยความจำและความเร็วในการแทรกและการลบ:
SortedList<TKey, TValue>
SortedDictionary<TKey, TValue>
ใช้หน่วยความจำน้อยกว่า
SortedDictionary<TKey, TValue>
มีการแทรกได้เร็วขึ้นและการกำจัดการดำเนินงานสำหรับข้อมูลที่ไม่ได้เรียงลำดับ, O (log n) เมื่อเทียบกับ O (n)SortedList<TKey, TValue>
สำหรับถ้ารายการที่มีประชากรทั้งหมดในครั้งเดียวจากข้อมูลที่เรียงลำดับจะเร็วกว่า
SortedList<TKey, TValue>
SortedDictionary<TKey, TValue>
( SortedList
จริง ๆ แล้วรักษาอาร์เรย์ที่เรียงลำดับแทนที่จะใช้ทรีมันยังคงใช้การค้นหาแบบไบนารีเพื่อค้นหาองค์ประกอบ)
นี่คือมุมมองแบบตารางถ้ามันช่วย ...
จากมุมมองของประสิทธิภาพ :
+------------------+---------+----------+--------+----------+----------+---------+
| Collection | Indexed | Keyed | Value | Addition | Removal | Memory |
| | lookup | lookup | lookup | | | |
+------------------+---------+----------+--------+----------+----------+---------+
| SortedList | O(1) | O(log n) | O(n) | O(n)* | O(n) | Lesser |
| SortedDictionary | n/a | O(log n) | O(n) | O(log n) | O(log n) | Greater |
+------------------+---------+----------+--------+----------+----------+---------+
* Insertion is O(1) for data that are already in sort order, so that each
element is added to the end of the list (assuming no resize is required).
จากมุมมองการใช้งาน :
+------------+---------------+----------+------------+------------+------------------+
| Underlying | Lookup | Ordering | Contiguous | Data | Exposes Key & |
| structure | strategy | | storage | access | Value collection |
+------------+---------------+----------+------------+------------+------------------+
| 2 arrays | Binary search | Sorted | Yes | Key, Index | Yes |
| BST | Binary search | Sorted | No | Key | Yes |
+------------+---------------+----------+------------+------------+------------------+
ในการแปลความหมายคร่าวๆหากคุณต้องการประสิทธิภาพแบบดิบSortedDictionary
อาจเป็นทางเลือกที่ดีกว่า หากคุณต้องการค่าใช้จ่ายหน่วยความจำที่น้อยกว่าและการดึงดัชนีที่SortedList
เหมาะควรดีกว่า ดูคำถามนี้สำหรับข้อมูลเพิ่มเติมเกี่ยวกับเวลาที่จะใช้
คุณสามารถอ่านเพิ่มเติมได้ที่นี่ , ที่นี่ , ที่นี่ , ที่นี่และที่นี่
BDictionary<Key,Value>
ใน LoycCoreSortedDictionary
แทน
BDictionary
ทั่วไปแล้วจะช้ากว่าSortedDictionary
ยกเว้นขนาดที่ใหญ่มาก แต่จะเร็วกว่าSortedList
หากมีมากกว่า 700 รายการ การใช้หน่วยความจำควรสูงกว่าSortedList
(ต่ำกว่าSortedDictionary
) เพียงเล็กน้อยเท่านั้นเนื่องจากการใช้อาร์เรย์ในใบไม้ของต้นไม้
ฉันถอดรหัสตัวสะท้อนแสงแบบเปิดเพื่อดูสิ่งนี้เนื่องจากดูเหมือนจะสับสนSortedList
เล็กน้อย ในความเป็นจริงไม่ได้เป็นต้นไม้ค้นหาแบบทวิภาค, มันเป็นความเรียง (โดยกุญแจ) อาร์เรย์ของคู่ค่าคีย์ นอกจากนี้ยังมีTKey[] keys
ตัวแปรที่เรียงลำดับซิงค์กับคู่คีย์ - ค่าและใช้ในการค้นหาแบบไบนารี
นี่คือที่มาบางส่วน (กำหนดเป้าหมาย. NET 4.5) เพื่อสำรองการอ้างสิทธิ์ของฉัน
สมาชิกส่วนตัว
// Fields
private const int _defaultCapacity = 4;
private int _size;
[NonSerialized]
private object _syncRoot;
private IComparer<TKey> comparer;
private static TKey[] emptyKeys;
private static TValue[] emptyValues;
private KeyList<TKey, TValue> keyList;
private TKey[] keys;
private const int MaxArrayLength = 0x7fefffff;
private ValueList<TKey, TValue> valueList;
private TValue[] values;
private int version;
SortedList.ctor (IDictionary, IComparer)
public SortedList(IDictionary<TKey, TValue> dictionary, IComparer<TKey> comparer) : this((dictionary != null) ? dictionary.Count : 0, comparer)
{
if (dictionary == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.dictionary);
}
dictionary.Keys.CopyTo(this.keys, 0);
dictionary.Values.CopyTo(this.values, 0);
Array.Sort<TKey, TValue>(this.keys, this.values, comparer);
this._size = dictionary.Count;
}
SortedList.Add (TKey, TValue): void
public void Add(TKey key, TValue value)
{
if (key == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}
int num = Array.BinarySearch<TKey>(this.keys, 0, this._size, key, this.comparer);
if (num >= 0)
{
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_AddingDuplicate);
}
this.Insert(~num, key, value);
}
SortedList.RemoveAt (int): void
public void RemoveAt(int index)
{
if ((index < 0) || (index >= this._size))
{
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_Index);
}
this._size--;
if (index < this._size)
{
Array.Copy(this.keys, index + 1, this.keys, index, this._size - index);
Array.Copy(this.values, index + 1, this.values, index, this._size - index);
}
this.keys[this._size] = default(TKey);
this.values[this._size] = default(TValue);
this.version++;
}
ตรวจสอบหน้า MSDN สำหรับ SortedList :
จากข้อสังเกต:
SortedList<(Of <(TKey, TValue>)>)
ระดับทั่วไปเป็นต้นไม้ค้นหาแบบทวิภาคกับO(log n)
การดึงที่n
เป็นจำนวนขององค์ประกอบในพจนานุกรม ในสิ่งนี้มันคล้ายกับSortedDictionary<(Of <(TKey, TValue>)>)
คลาสทั่วไป คลาสที่สองมีโมเดลวัตถุที่คล้ายกันและทั้งสองมีO(log n)
การดึงข้อมูล โดยที่ทั้งสองคลาสต่างกันคือการใช้หน่วยความจำและความเร็วในการแทรกและการลบ:
SortedList<(Of <(TKey, TValue>)>)
SortedDictionary<(Of <(TKey, TValue>)>)
ใช้หน่วยความจำน้อยกว่า
SortedDictionary<(Of <(TKey, TValue>)>)
มีการแทรกได้เร็วขึ้นและการกำจัดการดำเนินงานสำหรับข้อมูลที่ไม่ได้เรียงลำดับ,O(log n)
ตรงข้ามกับการสำหรับO(n)
SortedList<(Of <(TKey, TValue>)>)
ถ้ารายการที่มีประชากรทั้งหมดในครั้งเดียวจากข้อมูลที่เรียงลำดับจะเร็วกว่า
SortedList<(Of <(TKey, TValue>)>)
SortedDictionary<(Of <(TKey, TValue>)>)
นี่เป็นภาพที่แสดงให้เห็นว่าการแสดงเปรียบเทียบกันอย่างไร
พอมีการพูดในหัวข้อแล้ว แต่เพื่อให้ง่ายนี่คือสิ่งที่ฉันทำ
พจนานุกรมที่จัดเรียงควรใช้เมื่อ -
ในอีกด้านหนึ่งรายการที่เรียงลำดับควรใช้เมื่อ -
หวังว่านี่จะช่วยได้ !!
การเข้าถึงดัชนี (กล่าวถึงที่นี่) เป็นความแตกต่างในทางปฏิบัติ หากคุณต้องการเข้าถึงตัวตายตัวแทนหรือผู้บุกเบิกคุณต้องใช้ SortedList SortedDictionary ไม่สามารถทำเช่นนั้นได้ดังนั้นคุณจึงถูก จำกัด ด้วยวิธีการใช้การเรียงลำดับ (ลำดับแรก / ก่อน)