جایگزینی آرایهها با HashSet برای سرعت بیشتر
نویسنده: وحید نصیری
تاریخ: ۱۴۰۴/۰۲/۱۵ ۰۷:۵۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
HashSet<T> میپردازد که با ارائه سرعت جستجوی بسیار بالاتر، میتواند به طور چشمگیری کارایی برنامههای داتنت را بهبود بخشد.Contains() در آرایهها برای یافتن یک عنصر خاص، مجبور است تکتک عناصر آرایه را از ابتدا تا انتها بررسی کند. این فرآیند، که پیچیدگی زمانی آن از مرتبه O(n) است (در آن n تعداد عناصر آرایه است)، به این معناست که با افزایش حجم دادهها، زمان مورد نیاز برای جستجو نیز به طور خطی افزایش مییابد. در سناریوهایی که عملیات جستجو بارها و بارها تکرار میشود، این امر میتواند منجر به کاهش محسوس سرعت و کارایی برنامه گردد.HashSet<T> یک ساختار دادهای مبتنی بر جدول درهمسازی (Hash Table) است. این ساختار دادهای با استفاده از تابع درهمسازی (Hash Function) و ذخیرهسازی عناصر در مکانهای خاصی بر اساس مقدار درهمسازی آنها، امکان دسترسی و جستجوی بسیار سریع عناصر را فراهم میکند. به طور متوسط، پیچیدگی زمانی عملیات Contains() در HashSet<T> از مرتبه O(1) است، به این معنی که زمان جستجو تقریباً مستقل از تعداد عناصر موجود در مجموعه است. این تفاوت در پیچیدگی زمانی، به ویژه در کار با مجموعههای بزرگ داده، تأثیر بسزایی در عملکرد برنامه خواهد داشت.HashSet<T> در شرایط زیر به طور خاص توصیه میشود:HashSet<T> به دلیل سرعت بالای جستجو، انتخاب بسیار مناسبی است.HashSet<T> به طور ذاتی از ذخیره عناصر تکراری جلوگیری میکند. اگر نیاز دارید مجموعهای از دادههای منحصربهفرد داشته باشید، HashSet<T> به صورت خودکار این اطمینان را فراهم میکند.HashSet<T> ترتیب درج عناصر را حفظ نمیکند. اگر ترتیب عناصر برای منطق برنامه شما مهم نیست، این ویژگی محدودیتی ایجاد نخواهد کرد.HashSet<T> میتواند بهبود قابل توجهی در کارایی ایجاد کند.// استفاده از آرایه
string[] fruitsArray = new string[] { "apple", "banana", "orange", /* ... یک میلیون آیتم */ "grape" };
bool foundInArray = fruitsArray.Contains("apple"); // O(n)
// استفاده از HashSet<T>
HashSet<string> fruitsSet = new HashSet<string>() { "apple", "banana", "orange", /* ... یک میلیون آیتم */ "grape" };
bool foundInSet = fruitsSet.Contains("apple"); // O(1)Contains() در HashSet<T> برای مجموعههای بزرگ داده بسیار سریعتر از آرایه عمل میکند.HashSet<T> به سادگی امکانپذیر است. با ایجاد یک نمونه جدید از HashSet<T> و ارسال آرایه به عنوان آرگومان سازنده (Constructor)، تمام عناصر آرایه به HashSet<T> اضافه شده و عناصر تکراری به طور خودکار حذف میشوند.string[] names = new string[] { "Raj", "Rahul", "Sneha", "Raj" };
HashSet<string> uniqueNames = new HashSet<string>(names); // تکراریها حذف خواهند شد.HashSet<T> ترتیب عناصر را حفظ نمیکند. اگر ترتیب برای شما مهم است، میتوانید از ساختارهای دادهای مانند SortedSet<T> (مجموعه مرتب شده) یا List<T> (لیست) استفاده کنید.GetHashCode() و Equals(): برای استفاده صحیح از HashSet<T> با انواع دادهای سفارشی (Custom Data Types)، ضروری است که متدهای GetHashCode() و Equals() در کلاس مربوطه به درستی پیادهسازی (Override) شوند. این متدها برای تعیین نحوه درهمسازی و مقایسه اشیاء در HashSet<T> استفاده میشوند.HashSet<T> ممکن است در مقایسه با آرایهها، مقدار کمی حافظه بیشتری مصرف کند. این امر به دلیل ساختار داخلی جدول درهمسازی و سربار (Overhead) مربوط به مدیریت آن است. با این حال، در بسیاری از موارد، مزایای عملکردی استفاده از HashSet<T> بر این افزایش جزئی در مصرف حافظه غلبه میکند.Customer (مشتری) دارید و میخواهید به طور مکرر بررسی کنید که آیا ایمیل یک مشتری در لیست سیاه (Blacklist) قرار دارد یا خیر.string[] blacklist = GetBlackListedEmails();
foreach(var customer in customers)
{
if (blacklist.Contains(customer.Email))
{
// انجام اقدام لازم
}
}HashSet<string> blacklistSet = new HashSet<string>(GetBlackListedEmails());
foreach(var customer in customers)
{
if (blacklistSet.Contains(customer.Email))
{
// انجام اقدام لازم
}
}HashSet<string> برای نگهداری لیست سیاه، به دلیل سرعت بالای عملیات Contains()، منجر به بهبود چشمگیر عملکرد در پردازش لیست مشتریان خواهد شد.Contains() داشتید، ابتدا در نظر بگیرید که آیا HashSet<T> میتواند جایگزین مناسبی باشد.HashSet<T> استفاده کنید.HashSet<T> بهترین انتخاب است.HashSet<T> میتواند راه حلی قدرتمند برای جلوگیری از مشکلات عملکردی باشد. با درک تفاوتهای کلیدی بین آرایهها و HashSet<T> و آگاهی از موارد استفاده مناسب برای هر کدام، توسعهدهندگان داتنت میتوانند تصمیمات آگاهانهتری در طراحی و پیادهسازی برنامههای خود بگیرند و کارایی و پاسخگویی آنها را به میزان قابل توجهی افزایش دهند. بنابراین، توصیه میشود که از امروز، در جاهایی که نیاز به سرعت و یکتایی دارید، با آرایهها خداحافظی کرده و به سوی سرعت با HashSet<T> حرکت کنید!