- Accessibility improvements in narration, high contrast and focus control areas
- .NET Framework support for .NET Standard 2.0 and compiler features
- More secure SHA-2 support in ASP.NET and System.Messaging
- Configuration builders
- ASP.NET Execution step feature
- ASP.NET HttpCookie parsing
- Enhancements in Visual Tree for WPF applications
- Performance and reliability improvements
.Net Core 5.0 Preview 1.0 منتشر شد
Postsharp نسخه 4 منتشر شد
4x runtime performance enhancement on our NotifyPropertyChanged aspect.
Improved reliability and scope of our deadlock detection policy.
Dynamic advices: see IAdviceProvider, IntroduceInterface, ImportLocation, ImportMethod, IntroduceMethod.
Aspect Repository and Late Validation.
OnInstanceConstructed advice.
Faster advice state lookup: see DeclarationIdentifier.
Results and Impact
- Average Latency improved from 350ms to less than 250ms.
- CPU during peak time was [60–40%]. This dropped to [15–25%].
- AWS Cost Reduction by replacing Windows with Linux servers [by 45%]
- Apache benchmarking [89 vs. 57 req/s]: .NET Core — 89.68 requests / second. .NET Framework on Windows — 57.21 requests/second
- JMeter [Throughput — 142.9 vs. 60.5 per second]: .NET Core Solution: Hit 1000 requests on http://XXXX.redbus.pe/ , Throughput was 142.9/Sec. NET Framework on Windows: Hit 1000 requests on http://XXXX.redbus.pe/, Throughput was 60.5/Sec.
- Blazemeter [90% response time — 417ms vs. 1.09s]: .NET Core Solution: 90% Response time was 417ms. .NET Framework on Windows: 90% Response time was 1.09s.
froala/wysiwyg-editor 1.2.5 منتشر شد
دوران رنسانس NET.
First, the decoupling of .NET from Windows
Second, the newfound focus on CLR performance
Third, moving .NET’s tooling to a cross-platform model
Fourth, the .NET user base is embracing the OSS ecosystem as a whole
Fifth, in general the direction on .NET development is pushing users further down into the details of the stack
Sixth, Microsoft’s platform work being done out in the open
«از این پس حین استفاده از انواع و اقسام لیستها، آرایهها، IEnumerableها و امثال آنها، جهت بررسی خالی بودن یا نبودن آنها تنها از متد Any فراهم شده توسط LINQ استفاده نمائید.»
اکنون پس از سالها، قصد داریم صحت این مساله را با NET 5.0. بررسی کنیم که آیا هنوز هم متد Any، بهترین متد بررسی خالی بودن مجموعهها و آرایههای NET 5.0. است یا خیر؟
نحوهی بررسی کارآیی روشهای مختلف خالی بودن مجموعهها و آرایهها در C# 9.0
در ابتدا یک لیست، یک Enumerable و یک آرایه را به صورت زیر مقدار دهی میکنیم و هر سهی اینها میتوانند نال هم باشند:
private IList<int>? _idsList; private IEnumerable<int>? _idsEnumerable; private int[]? _idsArray; [GlobalSetup] public void Setup() { _idsEnumerable = Enumerable.Range(0, 10000); _idsList = _idsEnumerable.ToList(); _idsArray = _idsEnumerable.ToArray(); }
اکنون که C# 9.0 در اختیار ما است به همراه pattern matching و همچنین Null Conditional Operator و غیره، میتوان روشهای زیر را برای بررسی خالی بودن این مجموعهها و آرایهها بکار گرفت:
1- استفاده از Null coalescing برای بررسی نال بودن مجموعه و سپس استفاده از متد Any برای بررسی خالی بودن آن:
var list = _idsList ?? new List<int>(); if (list.Any() is false) { }
2- استفاده از pattern matching برای بررسی نال بودن مجموعه و سپس استفاده از متد Any برای بررسی خالی بودن آن:
if (_idsList is null || _idsList.Any() is false) { }
3- استفاده از روش سنتی مقایسهی مستقیم با null و سپس استفاده از متد Any برای بررسی خالی بودن آن:
if (_idsList == null || _idsList.Any() is false) { }
4- استفاده از Null Conditional Operator برای بررسی نال بودن و سپس استفاده از متد Any برای بررسی خالی بودن آن:
if (_idsList?.Any() is false) { }
5- استفاده از pattern matching برای بررسی مقدار خاصیت Count یک لیست یا آرایه. البته Enumerableها به همراه این خاصیت نیستند و یا باید آنها را به لیست و یا آرایه تبدیل کرد و یا میتوان متد ()Count آنها را فراخوانی نمود:
if (_idsList is { Count: > 0 } is false) { }
6- استفاده از Null Conditional Operator برای بررسی نال بودن و سپس استفاده از مقدار خاصیت Count لیست، برای بررسی خالی بودن آن:
if (_idsList?.Count == 0) { }
7- استفاده از روش سنتی مقایسهی مستقیم با null و سپس استفاده از مقدار خاصیت Count لیست، برای بررسی خالی بودن آن:
if (_idsList == null || _idsList.Count == 0) { }
کدهای کامل این بررسی به صورت زیر هستند: AnyCountBenchmark.zip
ابتدا ارجاعی به BenchmarkDotNet به برنامه اضافه شدهاست:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net5.0</TargetFramework> <Nullable>enable</Nullable> <TreatWarningsAsErrors>true</TreatWarningsAsErrors> </PropertyGroup> <ItemGroup> <PackageReference Include="BenchmarkDotNet" Version="0.12.1" /> </ItemGroup> </Project>
و سپس کدهای زیر، بررسی کارآیی روشهای مختلف تعیین خالی بودن مجموعهها را انجام میدهند:
using BenchmarkDotNet.Running; namespace AnyCountBenchmark { public static class Program { static void Main(string[] args) { #if DEBUG System.Console.WriteLine("Please set the project's configuration to Release mode first."); #else BenchmarkRunner.Run<Scenarios>(); #endif } } }
به همراه سناریوهای مختلف زیر:
using System; using System.Collections.Generic; using System.Linq; using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Jobs; using BenchmarkDotNet.Order; namespace AnyCountBenchmark { [SimpleJob(RuntimeMoniker.NetCoreApp50)] [Orderer(SummaryOrderPolicy.FastestToSlowest, MethodOrderPolicy.Declared)] [RankColumn] public class Scenarios { private IList<int>? _idsList; private IEnumerable<int>? _idsEnumerable; private int[]? _idsArray; [GlobalSetup] public void Setup() { _idsEnumerable = Enumerable.Range(0, 10000); _idsList = _idsEnumerable.ToList(); _idsArray = _idsEnumerable.ToArray(); } #region Any_With_Null_coalescing [Benchmark] public void List_Any_With_Null_coalescing() { var list = _idsList ?? new List<int>(); if (list.Any() is false) { } } [Benchmark] public void Array_Any_With_Null_coalescing() { var array = _idsArray ?? Array.Empty<int>(); if (array.Any() is false) { } } [Benchmark] public void Enumerable_Any_With_Null_coalescing() { var enumerable = _idsEnumerable ?? Enumerable.Empty<int>(); if (enumerable.Any() is false) { } } #endregion #region Any_With_Is_Null_Check [Benchmark] public void List_Any_With_Is_Null_Check() { if (_idsList is null || _idsList.Any() is false) { } } [Benchmark] public void Array_Any_With_Is_Null_Check() { if (_idsArray is null || _idsArray.Any() is false) { } } [Benchmark] public void Enumerable_Any_With_Is_Null_Check() { if (_idsEnumerable is null || _idsEnumerable.Any() is false) { } } #endregion #region Any_Any_With_Null_Equality_Check [Benchmark] public void List_Any_With_Null_Equality_Check() { if (_idsList == null || _idsList.Any() is false) { } } [Benchmark] public void Array_Any_With_Null_Equality_Check() { if (_idsArray == null || _idsArray.Any() is false) { } } [Benchmark] public void Enumerable_Any_With_Null_Equality_Check() { if (_idsEnumerable == null || _idsEnumerable.Any() is false) { } } #endregion #region Any_With_Null_Conditional_Operator [Benchmark] public void List_Any_With_Null_Conditional_Operator() { if (_idsList?.Any() is false) { } } [Benchmark] public void Array_Any_With_Null_Conditional_Operator() { if (_idsArray?.Any() is false) { } } [Benchmark] public void Enumerable_Any_With_Null_Conditional_Operator() { if (_idsEnumerable?.Any() is false) { } } #endregion #region Count_With_Pattern_Matching [Benchmark] public void List_Count_With_Pattern_Matching() { if (_idsList is { Count: > 0 } is false) { } } [Benchmark] public void Array_Length_With_Pattern_Matching() { if (_idsArray is { Length: > 0 } is false) { } } [Benchmark] public void Enumerable_Count_With_Pattern_Matching() { var list = _idsEnumerable?.ToList(); if (list is { Count: > 0 } is false) { } } #endregion #region Count_With_Null_Conditional_Operator [Benchmark] public void List_Count_With_Null_Conditional_Operator() { if (_idsList?.Count == 0) { } } [Benchmark] public void Array_Length_With_Null_Conditional_Operator() { if (_idsArray?.Length == 0) { } } [Benchmark] public void Enumerable_Count_With_Null_Conditional_Operator() { if (_idsEnumerable?.Count() == 0) { } } #endregion #region Count_With_Null_Equality_Check [Benchmark] public void List_Count_With_Null_Equality_Check() { if (_idsList == null || _idsList.Count == 0) { } } [Benchmark] public void Array_Length_With_Null_Equality_Check() { if (_idsArray == null || _idsArray.Length == 0) { } } [Benchmark] public void Enumerable_Count_With_Null_Equality_Check() { if (_idsEnumerable == null || _idsEnumerable.Count() == 0) { } } #endregion } }
نتایج حاصل:
- بررسی خالی بودن آرایهها، بسیار سریعتر از بررسی خالی بودن لیستها و این مورد نیز سریعتر از Enumerableها است.
- اگر از آرایهها و یا لیستها استفاده میکنید، بررسی خاصیت Length و یا خاصیت Count آنها، بسیار سریعتر از بکارگیری متد Any بر روی آنها است.
- اگر از Enumerableها استفاده میکنید، استفاده از متد Any بر روی آنها، بسیار سریعتر از بکارگیری متد ()Count و یا تبدیل آنها به لیست و سپس بررسی خاصیت Count آنها است.
- بررسی نال بودن با pattern matching یا همان is null، نسبت به روشی سنتی استفادهی از null ==، سریعتر است. علت آنرا در مطلب «روش ترجیح داده شدهی مقایسه مقادیر اشیاء با null از زمان C# 7.0 به بعد» میتوانید مطالعه کنید.
بنابراین برای بررسی خالی بودن آرایهها و لیستها، بهتر است از خاصیت Length و یا Count آنها استفاده کرد و برای Enumerableها از متد ()Any.
نگاهی به ویژگیهای احتمالی C# 9.0
.NET Core 1x
.NET Core 2x
.NET Core 3x
.NET 5x
.NET 3x
.NET 2x