جستجوی جایگزین برای دیکشنری (Dictionary) و هشست (HashSet) در داتنت 9
نویسنده: وحید نصیری
تاریخ: ۱۴۰۳/۱۲/۲۷ ۰۸:۲۹
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
ToString بود. این تبدیل باعث تخصیص حافظه اضافی میشد که عملکرد را کاهش میداد.GetAlternateLookup() و ساختار AlternateLookup<T>، امکان جستجوی مستقیمی را با استفاده از ReadOnlySpan<char> را فراهم کرده است. این کار از تخصیص حافظهی اضافی جلوگیری میکند و عملکرد را بهبود میبخشد. مثال:var dic = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase) {
{ "Paul", 11 },
{ "John", 22 },
{ "Jack", 33 }
};
// .NET 9 : GetAlternateLookup()
Dictionary<string, int>.AlternateLookup<ReadOnlySpan<char>> lookup = dic.GetAlternateLookup<ReadOnlySpan<char>>();AlternateLookup<T>: یک ساختار فقط خواندنی عمومی (public readonly struct) است که به عنوان یک کلید جایگزین برای جستجو در دیکشنری (Dictionary) و هشست (HashSet) عمل میکند. این ساختار از ویژگی «ضد محدودیت عمومی» (generic anti-constraint) سیشارپ 13.0 به نام «مجاز بودن ref struct» (allows ref struct) استفاده میکند که امکان استفاده از انواع دادهای مانند ReadOnlySpan<char> را فراهم میکند. مثال:public readonly struct AlternateLookup<TAlternateKey> where TAlternateKey : notnull, allows ref struct
IAlternateEqualityComparer<in TAlternate, T>: یک رابط (interface) است که برای مقایسه کلیدهای جایگزین با کلیدهای اصلی استفاده میشود. این رابط متدهایی مانند Equals() و GetHashCode() را برای مقایسه و محاسبه کد درهمسازی (hash code) کلیدهای جایگزین فراهم میکند. مثال:namespace System.Collections.Generic {
public interface IAlternateEqualityComparer<in TAlternate, T>
where TAlternate : allows ref struct
where T : allows ref struct
{
T Create(TAlternate alternate);
bool Equals(TAlternate alternate, T other);
int GetHashCode(TAlternate alternate);
}
}SpanSplitEnumerator<T>: یک ساختار (struct) است که برای تقسیم رشتهها به بخشهای کوچکتر با استفاده از ReadOnlySpan<char> استفاده میشود. این ساختار نیز از ویژگی «مجاز بودن ref struct» (allows ref struct) استفاده میکند. مثال:public static SpanSplitEnumerator<T> Split<T>( this ReadOnlySpan<T> source, T separator)
ReadOnlySpan<char> در مقایسه با جستجوی معمولی با رشته، عملکرد را به طور قابل توجهی بهبود میبخشد و از تخصیص حافظه اضافی جلوگیری میکند.| متد (Method) | شمارش (Count) | میانگین (Mean) | تخصیص یافته (Allocated) |
| AlternateLookup_WithReadOnlySpan | 100 | 9.477 میکروثانیه | - |
| RegularLookup_WithString | 100 | 11.579 میکروثانیه | 9600 بایت |
OrdinalIgnoreCaseComparer، این مقایسهکنندهها باید رابط IAlternateEqualityComparer<in TAlternate, T> را پیادهسازی کنند.IAlternateEqualityComparer را برای انواع دادهای خود ایجاد کنند.internal class PersonComparer : IEqualityComparer<Person>, IAlternateEqualityComparer<Guid, Person> {
private PersonComparer() { }
internal static PersonComparer Instance { get; } = new PersonComparer();
// IAlternateEqualityComparer<Guid, Person> impl
public Person Create(Guid id) {
// In this sample, don't try to retrieve a Person object from its id
throw new NotImplementedException();
}
}Span<T>، عملکرد جستجو در دیکشنری (Dictionary) و هشست (HashSet) را بهبود میبخشد و از تخصیص حافظه اضافی جلوگیری میکند. این قابلیت به ویژه برای برنامههای کاربردی با عملکرد بالا که با رشتههای بزرگ سروکار دارند، مفید است.