diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 98cd2b6b..74b43087 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "husky": { - "version": "0.7.2", + "version": "0.8.0", "commands": [ "husky" ], diff --git a/.github/workflows/publush.yml b/.github/workflows/publush.yml index 3ff40f8f..f3f56133 100644 --- a/.github/workflows/publush.yml +++ b/.github/workflows/publush.yml @@ -17,7 +17,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v3 with: - dotnet-version: 9.0.x + dotnet-version: 10.0.x - name: Restore dependencies run: dotnet restore - name: Build diff --git a/.github/workflows/pullRequest.yml b/.github/workflows/pullRequest.yml index 8c40637f..732289af 100644 --- a/.github/workflows/pullRequest.yml +++ b/.github/workflows/pullRequest.yml @@ -14,7 +14,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v3 with: - dotnet-version: 9.0.x + dotnet-version: 10.0.x - name: Restore dependencies run: dotnet restore - name: Build diff --git a/benchmark/Benchmark.csproj b/benchmark/Benchmark.csproj index 3bc89c8b..55bbd04e 100644 --- a/benchmark/Benchmark.csproj +++ b/benchmark/Benchmark.csproj @@ -2,17 +2,17 @@ Exe - net8.0 + net10.0 Benchmarks - + - - - + + + diff --git a/benchmark/Program.cs b/benchmark/Program.cs index c82d2311..7516c972 100644 --- a/benchmark/Program.cs +++ b/benchmark/Program.cs @@ -7,8 +7,8 @@ public class Program { private static void Main() { - // BenchmarkRunner.Run(); - BenchmarkRunner.Run(); + BenchmarkRunner.Run(); + //BenchmarkRunner.Run(); // BenchmarkRunner.Run(); // BenchmarkRunner.Run(); // BenchmarkRunner.Run(); diff --git a/docs/.vitepress/configs/version.ts b/docs/.vitepress/configs/version.ts index a89605d9..97602ca8 100644 --- a/docs/.vitepress/configs/version.ts +++ b/docs/.vitepress/configs/version.ts @@ -1 +1 @@ -export const version: string = '2.17.0' +export const version: string = '2.17.1' diff --git a/docs/pages/guide/index.md b/docs/pages/guide/index.md index 5308d56e..5877c020 100644 --- a/docs/pages/guide/index.md +++ b/docs/pages/guide/index.md @@ -32,25 +32,29 @@ To provide a better understanding of Gridify's functionality, we have prepared a ## Performance -Filtering is the most expensive feature in Gridify. -The following benchmark compares filtering in various popular dynamic LINQ libraries. -Interestingly, Gridify outperforms even Native LINQ in terms of speed. -It's worth mentioning that other features like Pagination and Sorting in Gridify have minimal impact on performance. - -| Method | Mean | Error | StdDev | Ratio | Allocated | Alloc Ratio | -|------------------|-------------:|------------:|------------:|-------:|------------:|------------:| -| Gridify | 599.8 us | 2.76 us | 2.45 us | 0.92 | 36.36 KB | 1.11 | -| Native_LINQ | 649.9 us | 2.55 us | 2.38 us | 1.00 | 32.74 KB | 1.00 | -| DynamicLinq | 734.8 us | 13.90 us | 13.01 us | 1.13 | 119.4 KB | 3.65 | -| Sieve | 1,190.9 us | 7.41 us | 6.93 us | 1.83 | 53.05 KB | 1.62 | -| Fop | 2,637.6 us | 8.59 us | 7.61 us | 4.06 | 321.57 KB | 9.82 | -| CSharp_Scripting | 216,863.8 us | 4,295.66 us | 6,021.92 us | 336.64 | 23660.26 KB | 722.71 | +Filtering remains the most expensive operation in Gridify. +In .NET 8, Gridify was slightly faster than native LINQ, but with .NET 10 improvements to LINQ itself, +native performance has caught up. +The latest benchmark shows Gridify performing nearly identically to native LINQ, +while still clearly ahead of other dynamic LINQ libraries. +Pagination and sorting continue to have minimal performance impact. + +| Method | Mean | Error | StdDev | Ratio | RatioSD | Allocated | Alloc Ratio | +|---------------------- |-----------:|----------:|----------:|-------:|--------:|------------:|------------:| +| Native_LINQ | 1.049 ms | 0.0047 ms | 0.0041 ms | 1.00 | 0.01 | 32.02 KB | 1.00 | +| Gridify | 1.079 ms | 0.0071 ms | 0.0066 ms | 1.03 | 0.01 | 34.76 KB | 1.09 | +| Gridify_WithoutMapper | 1.090 ms | 0.0074 ms | 0.0069 ms | 1.04 | 0.01 | 40.37 KB | 1.26 | +| Sieve | 1.216 ms | 0.0103 ms | 0.0097 ms | 1.16 | 0.01 | 44.21 KB | 1.38 | +| DynamicLinq | 1.284 ms | 0.0088 ms | 0.0082 ms | 1.22 | 0.01 | 92.42 KB | 2.89 | +| Fop | 4.749 ms | 0.0445 ms | 0.0416 ms | 4.53 | 0.04 | 284.77 KB | 8.89 | +| CSharp_Scripting | 224.708 ms | 4.4534 ms | 7.5621 ms | 214.24 | 7.17 | 23303.11 KB | 727.67 | ::: details -BenchmarkDotNet v0.13.10, Windows 11 (10.0.22621.2715/22H2/2022Update/SunValley2) -12th Gen Intel Core i7-12800H, 1 CPU, 20 logical and 14 physical cores -.NET SDK 8.0.100 -[Host] : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2 +BenchmarkDotNet v0.15.6, Windows 11 (10.0.26200.7171) +AMD Ryzen 7 7800X3D 4.20GHz, 1 CPU, 8 logical and 8 physical cores +.NET SDK 10.0.100 +[Host] : .NET 10.0.0 (10.0.0, 10.0.25.52411), X64 RyuJIT x86-64-v4 +DefaultJob : .NET 10.0.0 (10.0.0, 10.0.25.52411), X64 RyuJIT x86-64-v4 This Benchmark is available [Here](https://github.com/alirezanet/Gridify/blob/master/benchmark/LibraryComparisionFilteringBenchmark.cs) diff --git a/src/Gridify.Elasticsearch/Gridify.Elasticsearch.csproj b/src/Gridify.Elasticsearch/Gridify.Elasticsearch.csproj index ad4d608d..ed09d822 100644 --- a/src/Gridify.Elasticsearch/Gridify.Elasticsearch.csproj +++ b/src/Gridify.Elasticsearch/Gridify.Elasticsearch.csproj @@ -1,7 +1,7 @@ Gridify.Elasticsearch - 2.17.0 + 2.17.1 Alireza Sabouri; Dzmitry Koush Gridify (Elasticsearch), Easy way to apply Filtering, Sorting, and Pagination using text-based data. https://github.com/alirezanet/Gridify @@ -13,7 +13,7 @@ true snupkg README.md - net6.0;netstandard2.0;netstandard2.1;net7.0;net8.0;net9.0 + net10.0;netstandard2.0;netstandard2.1;net8.0;net9.0 default enable diff --git a/src/Gridify.EntityFramework/Gridify.EntityFramework.csproj b/src/Gridify.EntityFramework/Gridify.EntityFramework.csproj index 5779efe9..b7ab2aea 100644 --- a/src/Gridify.EntityFramework/Gridify.EntityFramework.csproj +++ b/src/Gridify.EntityFramework/Gridify.EntityFramework.csproj @@ -1,7 +1,7 @@ Gridify.EntityFramework - 2.17.0 + 2.17.1 Alireza Sabouri TuxTeam Gridify (EntityFramework), Easy and optimized way to apply Filtering, Sorting, and Pagination using text-based data. @@ -14,7 +14,7 @@ true snupkg README.md - net6.0;netstandard2.0;netstandard2.1;net7.0;net8.0;net9.0 + net10.0;netstandard2.0;netstandard2.1;net8.0;net9.0 default enable @@ -25,7 +25,7 @@ - + @@ -34,16 +34,13 @@ - - - - - - + + + diff --git a/src/Gridify/Gridify.csproj b/src/Gridify/Gridify.csproj index b52c07de..bbdbb2e5 100644 --- a/src/Gridify/Gridify.csproj +++ b/src/Gridify/Gridify.csproj @@ -2,7 +2,7 @@ Gridify - 2.17.0 + 2.17.1 Alireza Sabouri TuxTeam Gridify, Easy and optimized way to apply Filtering, Sorting, and Pagination using text-based data. @@ -18,7 +18,7 @@ snupkg true README.md - net6.0;netstandard2.0;netstandard2.1;net7.0;net8.0;net9.0 + net10.0;netstandard2.0;netstandard2.1;net8.0;net9.0 @@ -26,34 +26,30 @@ - - - - - - + + - - + + - - + + - + - + - + - + diff --git a/test/EntityFrameworkIntegrationTests/EntityFrameworkIntegrationTests.cs.csproj b/test/EntityFrameworkIntegrationTests/EntityFrameworkIntegrationTests.cs.csproj index bce77abb..6ba04c77 100644 --- a/test/EntityFrameworkIntegrationTests/EntityFrameworkIntegrationTests.cs.csproj +++ b/test/EntityFrameworkIntegrationTests/EntityFrameworkIntegrationTests.cs.csproj @@ -1,16 +1,16 @@ - net9.0 + net10.0 enable - - - - - + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/EntityFrameworkPostgreSqlIntegrationTests/EntityFrameworkPostgreSqlIntegrationTests.csproj b/test/EntityFrameworkPostgreSqlIntegrationTests/EntityFrameworkPostgreSqlIntegrationTests.csproj index e89d400a..29cce7fa 100644 --- a/test/EntityFrameworkPostgreSqlIntegrationTests/EntityFrameworkPostgreSqlIntegrationTests.csproj +++ b/test/EntityFrameworkPostgreSqlIntegrationTests/EntityFrameworkPostgreSqlIntegrationTests.csproj @@ -1,17 +1,17 @@ - net9.0 + net10.0 enable enable - - - - - - + + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/EntityFrameworkPostgreSqlIntegrationTests/PR266Tests.cs b/test/EntityFrameworkPostgreSqlIntegrationTests/PR266Tests.cs index 5d779401..c0e37d91 100644 --- a/test/EntityFrameworkPostgreSqlIntegrationTests/PR266Tests.cs +++ b/test/EntityFrameworkPostgreSqlIntegrationTests/PR266Tests.cs @@ -24,38 +24,39 @@ public void ISO_Should_Convert_ToUTC() [Fact] public void ISO_Should_ShowcaseDifferentConversions_LocalToUtc() { - var localOffset = TimeZoneInfo.Local.GetUtcOffset(DateTime.Now); - - var localDt = DateTime.Parse("2025-03-31T02:54:09Z"); + var localDt = DateTime.Parse("2025-03-31T02:54:09Z"); // parsed as Local, value adjusted from Z Assert.Equal(DateTimeKind.Local, localDt.Kind); - // Past behavior. Kind becomes Utc, but time is not converted. + // Past behavior: flips Kind only var utcDtWrong = DateTime.SpecifyKind(localDt, DateTimeKind.Utc); Assert.Equal(DateTimeKind.Utc, utcDtWrong.Kind); Assert.Equal(localDt, utcDtWrong); - // Current behavior. Kind becomes Utc, and time is converted. + // Current behavior: converts to UTC using offset at that moment var utcDtCorrect = localDt.ToUniversalTime(); Assert.Equal(DateTimeKind.Utc, utcDtCorrect.Kind); - Assert.Equal(localDt.Subtract(localOffset), utcDtCorrect); + + var offsetAtThatTime = TimeZoneInfo.Local.GetUtcOffset(localDt); + Assert.Equal(localDt - offsetAtThatTime, utcDtCorrect); } [Fact] public void ISO_Should_ShowcaseDifferentConversions_UtcToLocal() { - var localOffset = TimeZoneInfo.Local.GetUtcOffset(DateTime.Now); - var utcDt = DateTime.Parse("2025-03-31T02:54:09Z").ToUniversalTime(); Assert.Equal(DateTimeKind.Utc, utcDt.Kind); - // Past behavior. Kind becomes Local, but time is not converted. + // Past behavior: flips Kind only var localDtWrong = DateTime.SpecifyKind(utcDt, DateTimeKind.Local); Assert.Equal(DateTimeKind.Local, localDtWrong.Kind); Assert.Equal(utcDt, localDtWrong); - // Current behavior. Kind becomes Local, and time is converted. + // Current behavior: converts to Local using offset at that moment var localDtCorrect = utcDt.ToLocalTime(); Assert.Equal(DateTimeKind.Local, localDtCorrect.Kind); - Assert.Equal(utcDt.Add(localOffset), localDtCorrect); + + var offsetAtThatTime = TimeZoneInfo.Local.GetUtcOffset(utcDt); // offset for that UTC instant + Assert.Equal(utcDt + offsetAtThatTime, localDtCorrect); } + } diff --git a/test/EntityFrameworkSqlProviderIntegrationTests/EntityFrameworkSqlProviderIntegrationTests.csproj b/test/EntityFrameworkSqlProviderIntegrationTests/EntityFrameworkSqlProviderIntegrationTests.csproj index 6f8844a2..34acea84 100644 --- a/test/EntityFrameworkSqlProviderIntegrationTests/EntityFrameworkSqlProviderIntegrationTests.csproj +++ b/test/EntityFrameworkSqlProviderIntegrationTests/EntityFrameworkSqlProviderIntegrationTests.csproj @@ -1,18 +1,18 @@ - net9.0 + net10.0 EntityFrameworkIntegrationTests.cs - - - - + + + + - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/EntityFrameworkSqlProviderIntegrationTests/GridifyEntityFrameworkSqlTests.cs b/test/EntityFrameworkSqlProviderIntegrationTests/GridifyEntityFrameworkSqlTests.cs index 6c6c210c..126939ec 100644 --- a/test/EntityFrameworkSqlProviderIntegrationTests/GridifyEntityFrameworkSqlTests.cs +++ b/test/EntityFrameworkSqlProviderIntegrationTests/GridifyEntityFrameworkSqlTests.cs @@ -40,8 +40,8 @@ public void ApplyFiltering_GeneratedSqlShouldCreateParameterizedQuery_SqlServerP var actual = _dbContext.Users.ApplyFiltering("name = vahid").ToQueryString(); - Assert.StartsWith("DECLARE @__Value", actual); - Assert.StartsWith("DECLARE @__name", expected); + Assert.StartsWith("DECLARE @Value", actual); + Assert.StartsWith("DECLARE @name", expected); } @@ -52,10 +52,10 @@ public void ApplyFiltering_GreaterThanBetweenTwoStringsInEF_SqlServerProvider_En { GridifyGlobalConfiguration.EnableEntityFrameworkCompatibilityLayer(); var sb = new StringBuilder(); - sb.AppendLine("DECLARE @__Value_0 nvarchar(4000) = N'h';"); + sb.AppendLine("DECLARE @Value nvarchar(4000) = N'h';"); sb.AppendLine("SELECT [u].[Id], [u].[CreateDate], [u].[FkGuid], [u].[Name], [u].[shadow1]"); sb.AppendLine("FROM [Users] AS [u]"); - sb.AppendLine("WHERE [u].[Name] > @__Value_0"); + sb.AppendLine("WHERE [u].[Name] > @Value"); var actual = _dbContext.Users.ApplyFiltering("name > h").ToQueryString(); Assert.True(string.Compare( @@ -169,9 +169,9 @@ public void DictionaryMappingWithWhereStatement() var actual = actualQuery.ToQueryString(); // assert - Assert.Equal(expected, actual.Replace(" @__Value_0", " @__user_Name_0")); + Assert.Equal(expected, actual.Replace(" @Value", " @user_Name")); } - + [Fact] public void ApplyFiltering_NestedProperty() { @@ -182,6 +182,6 @@ public void ApplyFiltering_NestedProperty() var expected = _dbContext.Users.Where(q => q.Groups.Any(g => g.Users.Any(u => u.Name == name))).ToQueryString(); var actual = _dbContext.Users.ApplyFiltering("groups.users.name = test", gm).ToQueryString(); - Assert.Equal(expected, actual.Replace("@__Value_0", "@__name_0")); + Assert.Equal(expected, actual.Replace("@Value", "@name")); } } diff --git a/test/EntityFrameworkSqlProviderIntegrationTests/Issue173Tests.cs b/test/EntityFrameworkSqlProviderIntegrationTests/Issue173Tests.cs index d1597564..001b4bd5 100644 --- a/test/EntityFrameworkSqlProviderIntegrationTests/Issue173Tests.cs +++ b/test/EntityFrameworkSqlProviderIntegrationTests/Issue173Tests.cs @@ -1,4 +1,4 @@ -using System.Linq; +using System.Linq; using Gridify; using Microsoft.EntityFrameworkCore; using xRetry; @@ -17,7 +17,7 @@ public void EF_ManyToManyQuery_ShouldNotThrow() // arrange GridifyGlobalConfiguration.EnableEntityFrameworkCompatibilityLayer(); - var group = new { Name = "test group" }; + var group = new { Name = "test group" }; var expected = _dbContext.Users.Where(u => u.Groups.Any(g => g.Name == group.Name)).ToQueryString(); // act @@ -28,7 +28,7 @@ public void EF_ManyToManyQuery_ShouldNotThrow() .ToQueryString(); // assert - Assert.Equal(expected, actual.Replace(" @__Value_0", " @__group_Name_0")); + Assert.Equal(expected, actual.Replace(" @Value", " @group_Name")); } [RetryFact] diff --git a/test/Gridify.Elasticsearch.Tests/Gridify.Elasticsearch.Tests.csproj b/test/Gridify.Elasticsearch.Tests/Gridify.Elasticsearch.Tests.csproj index a786781e..a7e3a29a 100644 --- a/test/Gridify.Elasticsearch.Tests/Gridify.Elasticsearch.Tests.csproj +++ b/test/Gridify.Elasticsearch.Tests/Gridify.Elasticsearch.Tests.csproj @@ -1,7 +1,7 @@ - net9.0 + net10.0 false latest enable @@ -9,10 +9,10 @@ - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/Gridify.Tests/Gridify.Tests.csproj b/test/Gridify.Tests/Gridify.Tests.csproj index 9459dccb..b906ec06 100644 --- a/test/Gridify.Tests/Gridify.Tests.csproj +++ b/test/Gridify.Tests/Gridify.Tests.csproj @@ -1,7 +1,7 @@ - net9.0 + net10.0 false latest enable @@ -9,12 +9,12 @@ - - - + + + - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive