NET 4.0. و یک GAC جدید
دیتابیسهای شیءگرا
معرفی سایت dotnet-tricks
سفارشی کردن ASP.NET Identity در MVC 5
یک به روز رسانی عمومی دات نت 4 است.
public static void PrintSum(int a, int b) { Console.WriteLine("Sum of a {0} b {1} is {2}", a, b, a + b); }
Console::WriteLine(string, object, object, object)
روشی برای نمایان ساختن تخصیصهای حافظهی نهان در ویژوال استودیو
اگر از ReSharper استفاده میکنید، افزونهی «Heap Allocations Viewer» آن و یا اگر از VS 2015 و Roslyn استفاده کنید، افزونهی «Roslyn Clr Heap Allocation Analyzer» آن، سبب نمایان شدن allocationهای مخفی میشوند. برای مثال قطعه کد فوق یک چنین نمایشی را پیدا میکند:
در اینجا در ذیل هر سه موردی که عملیات boxing allocation رخ داده، یک خط قرمز کشیده است. یکی از روشهایی که میتواند boxing allocation فوق را حذف کند، بکار گیری متد ToString بر روی مقادیر int است:
همانطور که مشاهده میکنید، اینبار دیگر خبری از خطوط قرمز، ذیل پارامترهای متد Console.WriteLine نیست. باید دقت داشت که ToString نیز سبب تخصیص حافظه میشود، اما اینبار دیگر int32 آن بر روی heap ذخیره نمیگردد. به عبارتی هر دو حالت سبب تخصیص حافظهی یک رشتهی جدید میشوند؛ اما در حالت اول علاوه بر این شیء جدید، شیء int32 نیز بر روی heap ذخیره میگردد.
تشخیص تخصیص اشیاء مخفی با افزونههای Heap Allocations Viewer
نمونهی دیگر پر کاربرد این نوع بهینه سازیها را در مثال ذیل میتوان مشاهده کرد:
public static void PrintA(int a) { Console.WriteLine("a is " + a); }
اینبار یک خط زرد رنگ ظاهر شده به همراه یک خط قرمز رنگ. خط قرمز رنگ را پیشتر بررسی کردیم و علت وجودی آن Boxing allocation ایی است که رخ میدهد. خط زرد رنگ در ذیل + ظاهر شدهاست و عنوان میکند که عملیات جمع زدن رشتهها، سبب تخصیص حافظهی یک شیء جدید میشود. رشتهها در دات نت immutable هستند. به همین جهت هر تغییری در آنها، سبب تخصیص یک شیء جدید میشود. بنابراین در همین مثال ساده، دو تخصیص حافظهی مخفی وجود دارند. مورد جمع زدن را با بکارگیری string.Format و مشکل boxing را با ToString میتوان برطرف کرد:
public static void PrintA(int a) { Console.WriteLine("a is {0}", a.ToString()); }
منابع دیگری که سبب تخصیصهای حافظهی مخفی میشوند
تا اینجا دو مورد از منابع متداول تخصیصهای حافظهی مخفی را بررسی کردیم. اما این لیست شامل موارد ذیل نیز میشود:
1) فراخوانی متدهایی با پارامترهایی از نوع param همیشه سبب تخصیص حافظهای جهت تشکیل یک آرایهی در برگیرندهی پارامترهای ارسالی میشود.
2) متدهایی که پارامتر از نوع IEnumerable دارند:
public static int Sum(IEnumerable<int> list) { var sum = 0; foreach (var number in list) { sum += number; } return sum; }
برای حل این مشکل فقط کافی است IEnumerable را با List تعویض کنید.
3) کار با LINQ نیز سبب تخصیصهای حافظهی قابل توجهی است. برای مثال در کد پایهی Roslyn، برای رسیدن به حداکثر کارآیی، بسیاری از الگوریتمها را با روشهای غیر LINQ پیاده سازی کردهاند. البته برای تیمی مانند Roslyn رسیدن به یک چنین کارآیی جهت رقابت با سایر محصولات مشابه ضروری بودهاست و گرنه در بسیاری از کارهای متداول، استفاده از LINQ به خوانایی هر چه بیشتر کدها کمک شایانی میکند.
برای مطالعهی بیشتر
Roslyn code base – performance lessons - part 2
Unusual Ways of Boosting Up App Performance. Boxing and Collections
On performance in .NET
NET Standard. در حقیقت یک قرار داد است که سکوهای کاری مختلف دات نتی مانند Full .NET Framework ، Xamarin ، Mono ، UWP و غیره میتوانند آنرا پیاده سازی کنند. یک نمونهی دیگر این پیاده سازیها نیز NET Core. است. برای مثال دات نت 4.6.1، استاندارد و قرار داد شمارهی 2 دات نت را پیاده سازی میکند. به همین صورت NET Core 2.0. نیز پیاده سازی کنندهی این استاندارد شماره 2 است.
«اما» باید درنظر داشت که دات نت استاندارد، بیش از یک قرار داد چیزی نیست و پیاده سازی کنندگان آن میتوانند سطح بیشتری را نسبت به این قرار داد نیز لحاظ کنند. برای مثال دات نت 4.6.1 شامل سطح API بیشتری از دات نت استاندارد 2 است.
با تغییرات اخیر، اکنون NuGet میتواند کتابخانههای مبتنی بر NET Standard 2. را در برنامههای مبتنی بر سکوهای کاری که آنرا پیاده سازی میکنند، بدون مشکل اضافه کند. برای مثال میتوان اسمبلیهای دات نت 4.6.1 را به برنامههای ASP.NET Core 2.0 اضافه کرد (کاری که در نگارش 1x آن به صورت مستقیم میسر نیست) و یا میتوان اسمبلیهای کامپایل شدهی برای دات نت استاندارد 2 را به برنامههای مبتنی بر دات نت 4.6.1 اضافه کرد.
«اما» باید درنظر داشت که امکان اضافه کردن یک بستهی نیوگت از یک کتابخانهی نوشته شدهی برای دات نت کامل در برنامههای دات نت Core به معنای تضمینی برای کار کردن آن در زمان اجرا نخواهد بود. از این جهت که دات نت کامل، به همراه قسمتهایی است که در NET Standard. وجود خارجی ندارند. بنابراین اگر کتابخانهی استفاده شده صرفا این API مشترک را هدف قرار دادهاست، هم قابلیت اتصال و هم قابلیت اجرا را خواهد داشت؛ اما اگر برای مثال کسی بستهی NServiceBus را به پروژهی ASP.NET Core 2.0 اضافه کند، بدون مشکل کامپایل خواهد شد. اما از آنجائیکه این کتابخانه از MSMQ استفاده میکند که خارج از میدان دید این استاندارد است، در زمان اجرا با شکست مواجه خواهد شد.