Site: گاهنوشت امین مصباحی
Source: https://mesbahi.net/fa/blog/1403/09/08/nuget-slowness
⚠️ Article content is partial (Telegram Instant View delivered in segments).

🤔 تا حالا براتون سوال شده که چرا بعضی شرکتها توی مصاحبه فنیشون اینقدر روی مسایل ساختمانداده و الگوریتم تکیه دارن؟ (اداییها رو نمیگم 😁 درست و حسابیها رو میگم)
دیروز یه خبر توی فیدها اومد مبنی بر مشکل کُندی NuGet و ماجرای حل کردنش توی داتنت ۹. شاید بگید به من چه؟! من مصرفکننده هستم و خوب و بدش پای مایکروسافته. اصلنشم من احساس کندی نکردم...
توی دل خبر، کلی درس بود، من تا جایی که فرصت کردم امشب (دیشبِ وقتی که شما اینو میخونید 😁) توی گیتهاب و اینور و اونور دنبال سرنخ گشتم. سعی کردم به زبون ساده بدون اینکه توی جزییات خستهکننده بشه، داستان رو بنویسم. پاسخ پرسش اولم توی متن هست...
اگر دوست داشتید بخونید و نظرتون رو بگید
پینوشت: قابلیت instant view تلگرام روی دسکتاپ و iOS برای متون راستبه چپ باگ داره، قبلا توی گیتهاب طرح کردم و تعدادیش برطرف شد، پیگیر هستم تا بقیهاش هم حل بشه. شاید و شاید به زودی در قالب خبرنامه برخی مطالب و لینکهای مفید روزانه رو هم داشته باشیم...
🖼️ Photo
شاید شما هم امروز توی وبلاگ داتنت یا پُستهای شبکههای اجتماعی، تیتر «Dramatically faster package restores with .NET 9’s new NuGet resolver» رو دیده باشید، راستش پُست خیلی واضح نبود، من کمی به issueهای مرتبطش توی گیتهاب سرک کشیدم و تا دقیقتر داستان رو متوجه شم. این مطلب در راستای همین موضوعه!
مایکروسافت توی NET 9. و با 6.12 NuGet عملکرد فرایند Restore بستهها رو بهبود داد و مدعی افزایش سرعت ۱۵ برابری شد. این پیشرفت، نتیجه بازطراحی کامل الگوریتم مدیریت وابستگیها توی NuGet بود، که بعد از سالها ناکارآمدی توی پروژههای بزرگ به یکی از گلوگاههای اصلی توسعه تبدیل شده بود. حالا این مطلب، بررسی دقیق مشکلات اولیه، چگونگی شناسایی و حلشون، و تاثیر این تغییراته…
چرا سرعت Restore مهمه؟
توی اکوسیستم داتنت NuGet وظیفه مدیریت وابستگیها رو به عهده داره. هر بار که روی یه پروژهی داتنتی کار میکنیم، موقع توسعه، اجرا یا تست، دستور dotnet restore بهطور خودکار اجرا میشه تا وابستگیها رو بررسی و در صورت نیاز دانلود کنه. این فرآیند علاوه بر دانلود کتابخانهها، شامل بررسی سازگاری نسخهها و شناسایی آسیبپذیریهای امنیتی هم میشه؛ دقت کنید که یک بسته خودش میتونه وابسته به بستههای دیگهای باشه و اون بستهها خودشون وابسته به بستههای دیگهای و این روند میتونه خیلی تو در تو بشه…
توی پروژههای کوچیک، این عملیات سریع و بدون مشکل انجام میشه. اما وقتی پای پروژههای بزرگ و پیچیده با هزاران وابستگی به میون میاد، عملکرد این فرآیند به شدت کند میشه. توی برخی پروژههای داخلی مایکروسافت، زمان Restore به بیش از ۳۰ دقیقه میرسیده!! (من ردی از این پروژهها پیدا نکردم ولی شاید بشه به Dynamics 365 یا شیرپوینت یا اکسچینج فکر کرد) این موضوع باعث اتلاف وقت و کاهش بهرهوری توسعهدهندهها میشده و نیاز به بازنگری توی این فرآیند رو ضروری میکرده.
مشکل از کجا شروع شده؟
مایکروسافت توی فرآیند مهاجرت هزاران پروژه از NET Framework. به NET Core.، با مشکلات عمدهای توی عملکرد NuGet روبهرو شد. تیم توسعهدهندهها متوجه میشن دلیل این معطلیها و طولانی شدن Restore ها از ناکارآمدی الگوریتم مدیریت وابستگیها بوده.
الگوریتم قبلی:
الگوریتم قدیمی برای هر وابستگی، یک گراف بزرگ شامل چندمیلیون نود ایجاد میکرد. گرافی که نه تنها خیلی پیچیده بود، بلکه برای حل هر تعارض یا بررسی هر وابستگی، بارها از روی گراف عبور میکرد!! به عنوان مثال، توی پروژهای با بیش از ۲۵۰۰ ماژول، این گراف شامل ۱.۶ میلیون نود میشده و زمان Restore به حدود ۱۵ دقیقه میرسیده!
راهحل: بازطراحی الگوریتم
مهندسهای مایکروسافت تصمیم میگیرن تا الگوریتم مدیریت وابستگیها رو از پایه دوباره طراحی کنن. هدف این بود که:
- گراف وابستگیها کوچیکتر و سادهتر بشه.
- تعداد عبورهای مکرر از گراف کم بشه.
- عملکرد کلی بهبود پیدا کنه، بدون تغییر توی نتایج نهایی.
ویژگیهای الگوریتم جدید:
- کاهش تعداد نودها: توی پروژهای مشابه، گراف وابستگی از ۱.۶ میلیون نود به ۱,۲۰۰ نود کاهش پیدا میکنه.
- حل تعارض در زمان ساخت گراف: به جای عبورهای مکرر، تعارضها همزمان با ساخت گراف حل میشن.
- صرفهجویی در منابع سیستم: روش جدید باعث کاهش مصرف حافظه و پردازش میشه.
نتیجه: زمان Restore توی همون پروژهی بزرگ از ۱۵ دقیقه به ۲ دقیقه کاهش پیدا میکنه. این تغییر برای پروژههای بزرگ یک نقطه عطف محسوب میشه.
چالشها و مشکلات جانبی
هر تغییر بزرگی با چالشهای خاص خودش همراهه. الگوریتم جدید هم توی برخی موارد باعث بروز مشکلاتی شد:
- دانلود بستههای اضافی: توی بعضی سناریوها، نسخههای قدیمی یک بسته که دیگه استفاده نمیشن هم دانلود میشن! برای مثال، بسته jQuery.Validation به نسخهای از jQuery وابسته بوده که دیگه توی مخزن موجود نبوده، و فرآیند Restore با خطای “verify the package exists” متوقف میشده.
- راهحل موقت: برای رفع این مشکلات، مایکروسافت گزینهای ارائه داده که توسعهدهندهها بتونن با تنظیم RestoreUseLegacyDependencyResolver=true به الگوریتم قدیمی برگردن. البته این کار با هزینه کاهش سرعت همراه میشه.
نکات فنی و ابزارهای بررسی
مایکروسافت ابزارهایی برای بررسی تفاوتهای بین الگوریتم جدید و قدیمی ارائه کرده و میتونیم با مقایسه فایلهای project.assets.json در دو حالت، تفاوتها را ببینیم. به این ترتیب، میشه تشخیص داد که که آیا مشکلات، ناشی از الگوریتم جدیده یا نه.
آینده NuGet و NET.
این تغییر بهعنوان بخشی از یک استراتژی کلی برای بهبود عملکرد داتنت معرفی شده که با توجه به بازخوردهای اولیه، تیم NuGet قصد دارن الگوریتم رو بهبود بدن و مشکلات گزارششده رو زودتر برطرف کنن. از طرفی مایکروسافت توسعهدهندهها رو تشویق میکنه تا با گزارش مشکلات توی گیتهاب، به بهبودش کمک کنن.