Skip to content

Commit 8e8edaa

Browse files
committed
ToArray vs ToList EF
1 parent 87740ad commit 8e8edaa

9 files changed

+157
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net8.0</TargetFramework>
6+
<LangVersion>preview</LangVersion>
7+
<ImplicitUsings>enable</ImplicitUsings>
8+
<Nullable>enable</Nullable>
9+
</PropertyGroup>
10+
11+
<ItemGroup>
12+
<PackageReference Include="BenchmarkDotNet" Version="0.14.0" />
13+
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.8" />
14+
</ItemGroup>
15+
16+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BenchmarkToArrayToListEF", "BenchmarkToArrayToListEF.csproj", "{9DFB9CE7-BB4E-4C07-9581-0B4123B1E641}"
4+
EndProject
5+
Global
6+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
7+
Debug|Any CPU = Debug|Any CPU
8+
Release|Any CPU = Release|Any CPU
9+
EndGlobalSection
10+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
11+
{9DFB9CE7-BB4E-4C07-9581-0B4123B1E641}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
12+
{9DFB9CE7-BB4E-4C07-9581-0B4123B1E641}.Debug|Any CPU.Build.0 = Debug|Any CPU
13+
{9DFB9CE7-BB4E-4C07-9581-0B4123B1E641}.Release|Any CPU.ActiveCfg = Release|Any CPU
14+
{9DFB9CE7-BB4E-4C07-9581-0B4123B1E641}.Release|Any CPU.Build.0 = Release|Any CPU
15+
EndGlobalSection
16+
EndGlobal
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using Microsoft.EntityFrameworkCore;
2+
3+
public class BlogContext : DbContext
4+
{
5+
public DbSet<BlogPost> BlogPosts { get; set; }
6+
7+
public BlogContext(DbContextOptions options)
8+
: base(options)
9+
{
10+
}
11+
12+
protected override void OnModelCreating(ModelBuilder modelBuilder)
13+
{
14+
modelBuilder.ApplyConfiguration(new BlogPostConfiguration());
15+
}
16+
}

BenchmarkToArrayToListEF/BlogPost.cs

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
public class BlogPost
2+
{
3+
public int Id { get; set; }
4+
public required string Title { get; set; }
5+
public required string Subtitle { get; set; }
6+
public DateTime PublishDate { get; set; }
7+
public int Likes { get; set; }
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using Microsoft.EntityFrameworkCore;
2+
using Microsoft.EntityFrameworkCore.Metadata.Builders;
3+
4+
public class BlogPostConfiguration : IEntityTypeConfiguration<BlogPost>
5+
{
6+
public void Configure(EntityTypeBuilder<BlogPost> builder)
7+
{
8+
builder.Property(b => b.Title)
9+
.HasMaxLength(4000)
10+
.IsRequired();
11+
12+
builder.Property(b => b.Subtitle)
13+
.HasMaxLength(4000)
14+
.IsRequired();
15+
}
16+
}
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
public static class DataSeeder
2+
{
3+
public static void Seed(BlogContext context, int numberOfPosts)
4+
{
5+
var blogPosts = new List<BlogPost>();
6+
for (var i = 1; i <= numberOfPosts; i++)
7+
{
8+
blogPosts.Add(new BlogPost
9+
{
10+
Title = $"Title {i}",
11+
Subtitle = $"Subtitle {i}",
12+
PublishDate = DateTime.Now.AddDays(-i),
13+
Likes = i
14+
});
15+
}
16+
17+
context.BlogPosts.AddRange(blogPosts);
18+
context.SaveChanges();
19+
}
20+
}

BenchmarkToArrayToListEF/Program.cs

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
using System.Data.Common;
2+
using BenchmarkDotNet.Attributes;
3+
using BenchmarkDotNet.Running;
4+
using Microsoft.Data.Sqlite;
5+
using Microsoft.EntityFrameworkCore;
6+
7+
[MemoryDiagnoser]
8+
public class ToArrayVsToListBenchmark
9+
{
10+
private BlogContext? _context;
11+
private DbConnection? _connection;
12+
13+
[GlobalSetup(Targets = [nameof(ToArrayAsyncBenchmark), nameof(ToListAsyncBenchmark)])]
14+
public void Setup()
15+
{
16+
_connection = CreateInMemoryConnection();
17+
var options = new DbContextOptionsBuilder()
18+
.UseSqlite(_connection)
19+
.Options;
20+
_context = new BlogContext(options);
21+
_context.Database.EnsureDeleted();
22+
_context.Database.EnsureCreated();
23+
24+
DataSeeder.Seed(_context, 10000);
25+
}
26+
27+
[Params(100, 1000, 10000)]
28+
public int NumberOfElements { get; set; }
29+
30+
[Benchmark]
31+
public async Task<List<BlogPost>> ToListAsyncBenchmark()
32+
{
33+
return await _context!.BlogPosts.Take(NumberOfElements).ToListAsync();
34+
}
35+
36+
[Benchmark]
37+
public async Task<BlogPost[]> ToArrayAsyncBenchmark()
38+
{
39+
return await _context!.BlogPosts.Take(NumberOfElements).ToArrayAsync();
40+
}
41+
42+
[GlobalCleanup]
43+
public void Cleanup()
44+
{
45+
_context?.Dispose();
46+
_connection?.Dispose();
47+
}
48+
49+
public static void Main() => BenchmarkRunner.Run<ToArrayVsToListBenchmark>();
50+
51+
private static SqliteConnection CreateInMemoryConnection()
52+
{
53+
var connection = new SqliteConnection(string.Empty);
54+
55+
connection.Open();
56+
57+
return connection;
58+
}
59+
}

BenchmarkToArrayToListEF/README.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# ToArray(Async) vs ToList(Async) in Entity Framework 8
2+
3+
When retrieving data from your database with **Entity Framework**, there are two major options: `ToArray` and `ToList`. Besides the different return type, is there any significant difference in performance between the two? Let's find out!
4+
5+
Found [here](https://steven-giesel.com/blogPost/4ec751cd-d773-44c2-996e-cc4ae9ae966c)

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Contains all of my examples from various blog posts. You can find a comprehensiv
44

55
| BlogPost | Publish Date |
66
| -------------------------------------------------------------------------------------------------------------- | ------------ |
7+
| [ToArray(Async) vs ToList(Async) in Entity Framework 8(BenchmarkToArrayToListEF/)] | 28.10.2024 |
78
| [How to test HttpClient inside API Tests](FakeHttpClient/) | 02.09.2024 |
89
| [Fluent API to await multiple calls and get their respective results](TaskWhenAllResult/) | 12.04.2024 |
910
| [An asynchronous lock free ring buffer for logging](LockFreeRingBuffer/) | 03.01.2024 |

0 commit comments

Comments
 (0)