diff --git a/AutoQuery.sln b/AutoQuery.sln
index 73d8502..3586283 100644
--- a/AutoQuery.sln
+++ b/AutoQuery.sln
@@ -26,6 +26,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoQueryApiDemo", "sample\
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoQuery.AspNetCore.Tests", "test\AutoQuery.AspNetCore.Tests\AutoQuery.AspNetCore.Tests.csproj", "{A9125D44-3F97-4251-85F7-B28D07FA7B2D}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "sandbox", "sandbox", "{75B3287A-5C54-494A-B646-72CFBF9E2FB2}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoQuery.Benchmark", "sandbox\AutoQuery.Benchmark\AutoQuery.Benchmark.csproj", "{6F332D4E-4C59-40C7-836F-C7344FD9ACD5}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -56,6 +60,10 @@ Global
{A9125D44-3F97-4251-85F7-B28D07FA7B2D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A9125D44-3F97-4251-85F7-B28D07FA7B2D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A9125D44-3F97-4251-85F7-B28D07FA7B2D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6F332D4E-4C59-40C7-836F-C7344FD9ACD5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6F332D4E-4C59-40C7-836F-C7344FD9ACD5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6F332D4E-4C59-40C7-836F-C7344FD9ACD5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6F332D4E-4C59-40C7-836F-C7344FD9ACD5}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -67,6 +75,7 @@ Global
{AEAB6CC3-1A1D-450D-A368-6A3BAF82A4DE} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{BF0093CA-57E3-4D5F-91B9-46898DFDD0C1} = {E97A2640-E7C7-4C4B-B3E2-311C1B9FDAA4}
{A9125D44-3F97-4251-85F7-B28D07FA7B2D} = {5730CC15-795B-43C9-802C-18B3E19B7E22}
+ {6F332D4E-4C59-40C7-836F-C7344FD9ACD5} = {75B3287A-5C54-494A-B646-72CFBF9E2FB2}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {8FA10855-B537-4BAA-BB5B-6C0FB0BA6F42}
diff --git a/README.md b/README.md
index 18701b0..7008b71 100644
--- a/README.md
+++ b/README.md
@@ -12,6 +12,12 @@
- **Pagination and Sorting**: Built-in support for pagination and sorting.
- **ASP.NET Core Integration**: Middleware support for easy integration into ASP.NET Core projects.
+## Benchmark
+
+The benchmark results provide an overview of `AutoQuery`'s performance in handling dynamic queries and filtering. These results can help evaluate its suitability for various application scenarios.
+
+
+
## Installation
### AutoQuery
diff --git a/imgs/benchmarks.jpg b/imgs/benchmarks.jpg
new file mode 100644
index 0000000..80d1664
Binary files /dev/null and b/imgs/benchmarks.jpg differ
diff --git a/sandbox/AutoQuery.Benchmark/AutoQuery.Benchmark.csproj b/sandbox/AutoQuery.Benchmark/AutoQuery.Benchmark.csproj
new file mode 100644
index 0000000..dd9c7e0
--- /dev/null
+++ b/sandbox/AutoQuery.Benchmark/AutoQuery.Benchmark.csproj
@@ -0,0 +1,20 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+ false
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sandbox/AutoQuery.Benchmark/BenchmarkConfig.cs b/sandbox/AutoQuery.Benchmark/BenchmarkConfig.cs
new file mode 100644
index 0000000..eecfcad
--- /dev/null
+++ b/sandbox/AutoQuery.Benchmark/BenchmarkConfig.cs
@@ -0,0 +1,18 @@
+using BenchmarkDotNet.Configs;
+using BenchmarkDotNet.Diagnosers;
+using BenchmarkDotNet.Environments;
+using BenchmarkDotNet.Jobs;
+
+namespace AutoQuery.Benchmark;
+
+internal class BenchmarkConfig : ManualConfig
+{
+ public BenchmarkConfig()
+ {
+ AddDiagnoser(MemoryDiagnoser.Default);
+ AddJob(Job.ShortRun
+ .WithWarmupCount(1)
+ .WithIterationCount(1)
+ .WithRuntime(CoreRuntime.Core80));
+ }
+}
diff --git a/sandbox/AutoQuery.Benchmark/Benchmarks/QueryPerformance.cs b/sandbox/AutoQuery.Benchmark/Benchmarks/QueryPerformance.cs
new file mode 100644
index 0000000..68ee312
--- /dev/null
+++ b/sandbox/AutoQuery.Benchmark/Benchmarks/QueryPerformance.cs
@@ -0,0 +1,80 @@
+using AutoQuery.Abstractions;
+using AutoQuery.Extensions;
+using BenchmarkDotNet.Attributes;
+using System.Linq.Dynamic.Core;
+using System.Reflection;
+
+namespace AutoQuery.Benchmark.Benchmarks;
+
+[Config(typeof(BenchmarkConfig))]
+public class QueryPerformance
+{
+ private List _autoQueryTestData = null!;
+ private List _dynamicLinqTestData = null!;
+ private QueryProcessor _queryProcessor = null!;
+
+ [GlobalSetup]
+ public void Setup()
+ {
+ _queryProcessor = new QueryProcessor();
+ _queryProcessor.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
+ _autoQueryTestData = Enumerable.Range(1, 10000)
+ .Select(i => new TestData { Id = i, Name = $"Name{i}", Age = i % 100 })
+ .ToList();
+ _dynamicLinqTestData = Enumerable.Range(1, 10000)
+ .Select(i => new TestData { Id = i, Name = $"Name{i}", Age = i % 100 })
+ .ToList();
+ }
+
+ [Benchmark]
+ public void FilterSortSelectPageWithAutoQuery()
+ {
+ var queryOptions = new TestQueryOptions
+ {
+ Name = "Name5000",
+ Sort = "Age",
+ Fields = "Id,Name",
+ Page = 1,
+ PageSize = 10
+ };
+
+ _autoQueryTestData.AsQueryable().ApplyQueryPaged(_queryProcessor, queryOptions);
+ }
+
+ [Benchmark]
+ public void FilterSortSelectPageWithDynamicLinq()
+ {
+ _dynamicLinqTestData.AsQueryable()
+ .Where("Name == @0", "Name5000")
+ .OrderBy("Age")
+ .Select("new (Id, Name)")
+ .Skip(0)
+ .Take(10)
+ .ToDynamicList();
+ }
+
+ public class UserQueryConfiguration : IFilterQueryConfiguration
+ {
+ public void Configure(FilterQueryBuilder builder)
+ {
+ builder.Property(q => q.Name, d => d.Name)
+ .HasEqual();
+ }
+ }
+
+ public class TestData
+ {
+ public int Id { get; set; }
+ public string Name { get; set; } = null!;
+ public int Age { get; set; }
+ }
+
+ public class TestQueryOptions : IQueryPagedOptions
+ {
+ public string? Name { get; set; }
+ public string? Fields { get; set; }
+ public string? Sort { get; set; }
+ public int? Page { get; set; }
+ public int? PageSize { get; set; }
+ }
+}
diff --git a/sandbox/AutoQuery.Benchmark/Program.cs b/sandbox/AutoQuery.Benchmark/Program.cs
new file mode 100644
index 0000000..7f18f99
--- /dev/null
+++ b/sandbox/AutoQuery.Benchmark/Program.cs
@@ -0,0 +1,4 @@
+using BenchmarkDotNet.Running;
+using System.Reflection;
+
+BenchmarkSwitcher.FromAssembly(Assembly.GetEntryAssembly()!).Run(args);
\ No newline at end of file