From 63bc9f1fd5444f342ea9e6d4172d1c193563ff0d Mon Sep 17 00:00:00 2001 From: Thom Lamb Date: Tue, 23 Jun 2026 10:26:13 -0500 Subject: [PATCH] feat: Introduce object mapper benchmarking project This project provides a comparative analysis of popular .NET object-to-object mapping libraries, including AutoMapper, TinyMapper, Mapster, and Mapperly, against a hand-written and a generated manual mapper. It uses BenchmarkDotNet to measure performance and memory allocation when mapping a complex Spotify album DTO structure. --- MappersBenchmarks.sln | 25 +++ MappersBenchmarks/Benchmarks.cs | 100 +++++++++ MappersBenchmarks/ManualMapper.cs | 213 ++++++++++++++++++ MappersBenchmarks/MapperlyMapper.cs | 137 ++++++++++++ MappersBenchmarks/MappersBenchmarks.csproj | 18 ++ MappersBenchmarks/Models/SpotifyAlbum.cs | 83 +++++++ MappersBenchmarks/Models/SpotifyAlbumDto.cs | 130 +++++++++++ MappersBenchmarks/Program.cs | 4 + MappersBenchmarks/TestData.cs | 230 ++++++++++++++++++++ 9 files changed, 940 insertions(+) create mode 100644 MappersBenchmarks.sln create mode 100644 MappersBenchmarks/Benchmarks.cs create mode 100644 MappersBenchmarks/ManualMapper.cs create mode 100644 MappersBenchmarks/MapperlyMapper.cs create mode 100644 MappersBenchmarks/MappersBenchmarks.csproj create mode 100644 MappersBenchmarks/Models/SpotifyAlbum.cs create mode 100644 MappersBenchmarks/Models/SpotifyAlbumDto.cs create mode 100644 MappersBenchmarks/Program.cs create mode 100644 MappersBenchmarks/TestData.cs diff --git a/MappersBenchmarks.sln b/MappersBenchmarks.sln new file mode 100644 index 0000000..89116a3 --- /dev/null +++ b/MappersBenchmarks.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.33516.290 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MappersBenchmarks", "MappersBenchmarks\MappersBenchmarks.csproj", "{D9BBFC12-AE56-4065-8CCE-CC6E7549690B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D9BBFC12-AE56-4065-8CCE-CC6E7549690B}.Debug|Any CPU.ActiveCfg = Release|Any CPU + {D9BBFC12-AE56-4065-8CCE-CC6E7549690B}.Debug|Any CPU.Build.0 = Release|Any CPU + {D9BBFC12-AE56-4065-8CCE-CC6E7549690B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D9BBFC12-AE56-4065-8CCE-CC6E7549690B}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {3771561C-97D9-4E09-96A2-141DE855B85D} + EndGlobalSection +EndGlobal diff --git a/MappersBenchmarks/Benchmarks.cs b/MappersBenchmarks/Benchmarks.cs new file mode 100644 index 0000000..d1ce225 --- /dev/null +++ b/MappersBenchmarks/Benchmarks.cs @@ -0,0 +1,100 @@ +using AutoMapper; +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Order; +using MappersBenchmarks.Models; +using Mapster; + +namespace MappersBenchmarks; + +[MemoryDiagnoser(false)] +[Orderer(SummaryOrderPolicy.FastestToSlowest)] +public class Benchmarks +{ + private readonly SpotifyAlbumDto _spotifyAlbumDto = TestData.ExampleAlbum; + private readonly IMapper _autoMapper; + private readonly MapperlyMapper _mapperlyMapper; + + public Benchmarks() + { + //Automapper Configuration + var mapperConfig = new MapperConfiguration(cfg => + { + cfg.CreateMap(); + cfg.CreateMap(); + cfg.CreateMap(); + cfg.CreateMap(); + cfg.CreateMap(); + cfg.CreateMap(); + cfg.CreateMap(); + cfg.CreateMap(); + cfg.CreateMap(); + cfg.CreateMap(); + cfg.CreateMap(); + cfg.CreateMap(); + cfg.CreateMap(); + cfg.CreateMap(); + cfg.CreateMap(); + cfg.CreateMap(); + }); + _autoMapper = mapperConfig.CreateMapper(); + + //TinyMapper Configuration + Nelibur.ObjectMapper.TinyMapper.Bind(); + Nelibur.ObjectMapper.TinyMapper.Bind(); + Nelibur.ObjectMapper.TinyMapper.Bind(); + Nelibur.ObjectMapper.TinyMapper.Bind(); + Nelibur.ObjectMapper.TinyMapper.Bind(); + Nelibur.ObjectMapper.TinyMapper.Bind(); + Nelibur.ObjectMapper.TinyMapper.Bind(); + Nelibur.ObjectMapper.TinyMapper.Bind(); + Nelibur.ObjectMapper.TinyMapper.Bind(); + Nelibur.ObjectMapper.TinyMapper.Bind(); + Nelibur.ObjectMapper.TinyMapper.Bind(); + Nelibur.ObjectMapper.TinyMapper.Bind(); + Nelibur.ObjectMapper.TinyMapper.Bind(); + Nelibur.ObjectMapper.TinyMapper.Bind(); + Nelibur.ObjectMapper.TinyMapper.Bind(); + Nelibur.ObjectMapper.TinyMapper.Bind(); + + // Mapperly + _mapperlyMapper = new MapperlyMapper(); + + //Mapster don't need configuration + } + + [Benchmark] + public SpotifyAlbum AutoMapper() + { + return _autoMapper.Map(_spotifyAlbumDto); + } + + [Benchmark] + public SpotifyAlbum TinyMapper() + { + return Nelibur.ObjectMapper.TinyMapper.Map(_spotifyAlbumDto); + } + + [Benchmark] + public SpotifyAlbum Mapster() + { + return _spotifyAlbumDto.Adapt(); + } + + [Benchmark] + public SpotifyAlbum Mapperly() + { + return _mapperlyMapper.Map(_spotifyAlbumDto); + } + + [Benchmark] + public SpotifyAlbum MappingGenerator() + { + return _spotifyAlbumDto.Generated_Map(); + } + + [Benchmark] + public SpotifyAlbum ManualMapper() + { + return _spotifyAlbumDto.My_Map(); + } +} diff --git a/MappersBenchmarks/ManualMapper.cs b/MappersBenchmarks/ManualMapper.cs new file mode 100644 index 0000000..ab8eba3 --- /dev/null +++ b/MappersBenchmarks/ManualMapper.cs @@ -0,0 +1,213 @@ +using MappersBenchmarks.Models; + +namespace MappersBenchmarks; + +public static class MappingGeneratorMapper +{ + public static SpotifyAlbum Generated_Map(this SpotifyAlbumDto spotifyAlbumDto) + { + return new SpotifyAlbum + { + AlbumType = spotifyAlbumDto.AlbumType, + Artists = spotifyAlbumDto.Artists.Select(spotifyAlbumDtoArtist => new Artist + { + ExternalUrls = new ExternalUrls + { + Spotify = spotifyAlbumDtoArtist.ExternalUrls.Spotify + }, + Href = spotifyAlbumDtoArtist.Href, + Id = spotifyAlbumDtoArtist.Id, + Name = spotifyAlbumDtoArtist.Name, + Type = spotifyAlbumDtoArtist.Type, + Uri = spotifyAlbumDtoArtist.Uri + }).ToArray(), + AvailableMarkets = spotifyAlbumDto.AvailableMarkets, + Copyrights = spotifyAlbumDto.Copyrights.Select(spotifyAlbumDtoCopyright => new Copyright + { + Text = spotifyAlbumDtoCopyright.Text, + Type = spotifyAlbumDtoCopyright.Type + }).ToArray(), + ExternalIds = new ExternalIds + { + Upc = spotifyAlbumDto.ExternalIds.Upc + }, + ExternalUrls = new ExternalUrls + { + Spotify = spotifyAlbumDto.ExternalUrls.Spotify + }, + Genres = spotifyAlbumDto.Genres, + Href = spotifyAlbumDto.Href, + Id = spotifyAlbumDto.Id, + Images = spotifyAlbumDto.Images.Select(spotifyAlbumDtoImage => new Image + { + Height = spotifyAlbumDtoImage.Height, + Url = spotifyAlbumDtoImage.Url, + Width = spotifyAlbumDtoImage.Width + }).ToArray(), + Name = spotifyAlbumDto.Name, + Popularity = spotifyAlbumDto.Popularity, + ReleaseDate = spotifyAlbumDto.ReleaseDate, + ReleaseDatePrecision = spotifyAlbumDto.ReleaseDatePrecision, + Tracks = new Tracks + { + Href = spotifyAlbumDto.Tracks.Href, + Items = spotifyAlbumDto.Tracks.Items.Select(spotifyAlbumDtoTracksItem => new Item + { + Artists = spotifyAlbumDtoTracksItem.Artists.Select(spotifyAlbumDtoTracksItemArtist => new Artist + { + ExternalUrls = new ExternalUrls + { + Spotify = spotifyAlbumDtoTracksItemArtist.ExternalUrls.Spotify + }, + Href = spotifyAlbumDtoTracksItemArtist.Href, + Id = spotifyAlbumDtoTracksItemArtist.Id, + Name = spotifyAlbumDtoTracksItemArtist.Name, + Type = spotifyAlbumDtoTracksItemArtist.Type, + Uri = spotifyAlbumDtoTracksItemArtist.Uri + }).ToArray(), + AvailableMarkets = spotifyAlbumDtoTracksItem.AvailableMarkets, + DiscNumber = spotifyAlbumDtoTracksItem.DiscNumber, + DurationMs = spotifyAlbumDtoTracksItem.DurationMs, + Explicit = spotifyAlbumDtoTracksItem.Explicit, + ExternalUrls = new ExternalUrls + { + Spotify = spotifyAlbumDtoTracksItem.ExternalUrls.Spotify + }, + Href = spotifyAlbumDtoTracksItem.Href, + Id = spotifyAlbumDtoTracksItem.Id, + Name = spotifyAlbumDtoTracksItem.Name, + PreviewUrl = spotifyAlbumDtoTracksItem.PreviewUrl, + TrackNumber = spotifyAlbumDtoTracksItem.TrackNumber, + Type = spotifyAlbumDtoTracksItem.Type, + Uri = spotifyAlbumDtoTracksItem.Uri + }).ToArray(), + Limit = spotifyAlbumDto.Tracks.Limit, + Next = spotifyAlbumDto.Tracks.Next, + Offset = spotifyAlbumDto.Tracks.Offset, + Previous = spotifyAlbumDto.Tracks.Previous, + Total = spotifyAlbumDto.Tracks.Total + }, + Type = spotifyAlbumDto.Type, + Uri = spotifyAlbumDto.Uri + }; + } + + public static SpotifyAlbum My_Map(this SpotifyAlbumDto spotifyAlbumDto) + { + var result = new SpotifyAlbum + { + AlbumType = spotifyAlbumDto.AlbumType, + AvailableMarkets = spotifyAlbumDto.AvailableMarkets, + ExternalIds = new ExternalIds + { + Upc = spotifyAlbumDto.ExternalIds.Upc + }, + ExternalUrls = new ExternalUrls + { + Spotify = spotifyAlbumDto.ExternalUrls.Spotify + }, + Genres = spotifyAlbumDto.Genres, + Href = spotifyAlbumDto.Href, + Id = spotifyAlbumDto.Id, + Name = spotifyAlbumDto.Name, + Popularity = spotifyAlbumDto.Popularity, + ReleaseDate = spotifyAlbumDto.ReleaseDate, + ReleaseDatePrecision = spotifyAlbumDto.ReleaseDatePrecision, + Type = spotifyAlbumDto.Type, + Uri = spotifyAlbumDto.Uri, + Artists = new Artist[spotifyAlbumDto.Artists.Length] + }; + + for (var i = 0; i < spotifyAlbumDto.Artists.Length; i++) + { + var artistDto = spotifyAlbumDto.Artists[i]; + result.Artists[i] = new Artist + { + ExternalUrls = new ExternalUrls + { + Spotify = artistDto.ExternalUrls.Spotify + }, + Href = artistDto.Href, + Id = artistDto.Id, + Name = artistDto.Name, + Type = artistDto.Type, + Uri = artistDto.Uri + }; + } + + result.Copyrights = new Copyright[spotifyAlbumDto.Copyrights.Length]; + for (var i = 0; i < spotifyAlbumDto.Copyrights.Length; i++) + { + var copyrightDto = spotifyAlbumDto.Copyrights[i]; + result.Copyrights[i] = new Copyright + { + Text = copyrightDto.Text, + Type = copyrightDto.Type + }; + } + + result.Images = new Image[spotifyAlbumDto.Images.Length]; + for (var i = 0; i < spotifyAlbumDto.Images.Length; i++) + { + var imageDto = spotifyAlbumDto.Images[i]; + result.Images[i] = new Image + { + Height = imageDto.Height, + Url = imageDto.Url, + Width = imageDto.Width + }; + } + + result.Tracks = new Tracks + { + Href = spotifyAlbumDto.Tracks.Href, + Limit = spotifyAlbumDto.Tracks.Limit, + Next = spotifyAlbumDto.Tracks.Next, + Offset = spotifyAlbumDto.Tracks.Offset, + Previous = spotifyAlbumDto.Tracks.Previous, + Total = spotifyAlbumDto.Tracks.Total, + Items = new Item[spotifyAlbumDto.Tracks.Items.Length] + }; + + for (var i = 0; i < spotifyAlbumDto.Tracks.Items.Length; i++) + { + var itemDto = spotifyAlbumDto.Tracks.Items[i]; + result.Tracks.Items[i] = new Item(); + var item = result.Tracks.Items[i]; + item.AvailableMarkets = itemDto.AvailableMarkets; + item.DiscNumber = itemDto.DiscNumber; + item.DurationMs = itemDto.DurationMs; + item.Explicit = itemDto.Explicit; + item.ExternalUrls = new ExternalUrls + { + Spotify = itemDto.ExternalUrls.Spotify + }; + item.Href = itemDto.Href; + item.Id = itemDto.Id; + item.Name = itemDto.Name; + item.PreviewUrl = itemDto.PreviewUrl; + item.TrackNumber = itemDto.TrackNumber; + item.Type = itemDto.Type; + item.Uri = itemDto.Uri; + + item.Artists = new Artist[itemDto.Artists.Length]; + for (var j = 0; j < itemDto.Artists.Length; j++) + { + var artistDto = itemDto.Artists[j]; + item.Artists[i] = new Artist + { + ExternalUrls = new ExternalUrls + { + Spotify = artistDto.ExternalUrls.Spotify + }, + Href = artistDto.Href, + Id = artistDto.Id, + Name = artistDto.Name, + Type = artistDto.Type, + Uri = artistDto.Uri + }; + } + } + return result; + } +} diff --git a/MappersBenchmarks/MapperlyMapper.cs b/MappersBenchmarks/MapperlyMapper.cs new file mode 100644 index 0000000..0a2d4ca --- /dev/null +++ b/MappersBenchmarks/MapperlyMapper.cs @@ -0,0 +1,137 @@ +using MappersBenchmarks.Models; +using Riok.Mapperly.Abstractions; + +namespace MappersBenchmarks +{ + [Mapper] + public partial class MapperlyMapper + { + + public partial SpotifyAlbum Map(SpotifyAlbumDto spotifyAlbumDto); + + //public partial SpotifyAlbum Map(SpotifyAlbumDto spotifyAlbum) + //{ + // var newItem = new SpotifyAlbum() + // { + // AlbumType = spotifyAlbum.AlbumType, + // TotalTracks = spotifyAlbum.TotalTracks, + // AvailableMarkets = spotifyAlbum.AvailableMarkets, + // ExternalUrls = Map(spotifyAlbum.ExternalUrls), + // Href = spotifyAlbum.Href, + // Id = spotifyAlbum.Id, + // //Images = Map(spotifyAlbum.Images), + // Name = spotifyAlbum.Name, + // ReleaseDate = spotifyAlbum.ReleaseDate, + // ReleaseDatePrecision = spotifyAlbum.ReleaseDatePrecision, + // Restrictions = Map(spotifyAlbum.Restrictions), + // Type = spotifyAlbum.Type, + // Uri = spotifyAlbum.Uri, + // //Copyrights = Map(spotifyAlbum.Copyrights), + // //ExternalIds = Map(spotifyAlbum.ExternalIds), + // //Genres = Map(spotifyAlbum.Genres), + // Label = spotifyAlbum.Label, + // Popularity = spotifyAlbum.Popularity, + // //Artists = Map(spotifyAlbum.Artists), + // //Tracks = Map(spotifyAlbum.Tracks), + // }; + + // return newItem; + //} + + /* + private partial List Map(IList source) + { + var destination = new List(); + + if (source == null) return null; + + foreach (var item in source) + { + destination.Add(item); + } + + return destination; + } + + private partial string[] Map(IList source) + { + var destination = new List(); + + if (source == null) return null; + + foreach (var item in source) + { + destination.Add(item); + } + + return destination.ToArray(); + } + + private partial Image Map(ImageDto item) + { + if (item == null) return null; + + var newItem = new Image() + { + Url = item.Url, + Height = item.Height, + Width = item.Width, + }; + + return newItem; + } + + private partial ExternalUrl Map(ExternalUrlDto item) + { + if (item == null) return default; + + var newItem = new ExternalUrl() + { + Spotify = item.Spotify, + }; + + return newItem; + } + + private partial Restriction Map(RestrictionDto item) + { + if (item == null) return null; + + var newItem = new Restriction() + { + Reason = item.Reason, + }; + + return newItem; + } + + private partial ExternalId Map(ExternalIdDto item) + { + if (item == null) return null; + + var newItem = new ExternalId() + { + Isrc = item.Isrc, + Ean = item.Ean, + Upc = item.Upc, + }; + + return newItem; + } + + private partial List Map(IEnumerable source) + { + var destination = new List(); + + if (source == null) return null; + + foreach (var item in source) + { + destination.Add(item); + } + + return destination; + } + */ + } +} diff --git a/MappersBenchmarks/MappersBenchmarks.csproj b/MappersBenchmarks/MappersBenchmarks.csproj new file mode 100644 index 0000000..8bc5067 --- /dev/null +++ b/MappersBenchmarks/MappersBenchmarks.csproj @@ -0,0 +1,18 @@ + + + + Exe + net7.0 + enable + enable + + + + + + + + + + + diff --git a/MappersBenchmarks/Models/SpotifyAlbum.cs b/MappersBenchmarks/Models/SpotifyAlbum.cs new file mode 100644 index 0000000..5e6d178 --- /dev/null +++ b/MappersBenchmarks/Models/SpotifyAlbum.cs @@ -0,0 +1,83 @@ +namespace MappersBenchmarks.Models; + +public class SpotifyAlbum +{ + public string AlbumType { get; set; } + public Artist[] Artists { get; set; } + public string[] AvailableMarkets { get; set; } + public Copyright[] Copyrights { get; set; } + public ExternalIds ExternalIds { get; set; } + public ExternalUrls ExternalUrls { get; set; } + public object[] Genres { get; set; } + public string Href { get; set; } + public string Id { get; set; } + public Image[] Images { get; set; } + public string Name { get; set; } + public long Popularity { get; set; } + public string ReleaseDate { get; set; } + public string ReleaseDatePrecision { get; set; } + public Tracks Tracks { get; set; } + public string Type { get; set; } + public string Uri { get; set; } +} + +public class Tracks +{ + public string Href { get; set; } + public Item[] Items { get; set; } + public long Limit { get; set; } + public object Next { get; set; } + public long Offset { get; set; } + public object Previous { get; set; } + public long Total { get; set; } +} + +public class Item +{ + public Artist[] Artists { get; set; } + public string[] AvailableMarkets { get; set; } + public long DiscNumber { get; set; } + public long DurationMs { get; set; } + public bool Explicit { get; set; } + public ExternalUrls ExternalUrls { get; set; } + public string Href { get; set; } + public string Id { get; set; } + public string Name { get; set; } + public string PreviewUrl { get; set; } + public long TrackNumber { get; set; } + public string Type { get; set; } + public string Uri { get; set; } +} + +public class Image +{ + public long Height { get; set; } + public string Url { get; set; } + public long Width { get; set; } +} + +public class ExternalIds +{ + public string Upc { get; set; } +} + +public class Copyright +{ + public string Text { get; set; } + public string Type { get; set; } +} + +public class Artist +{ + public ExternalUrls ExternalUrls { get; set; } + public string Href { get; set; } + public string Id { get; set; } + public string Name { get; set; } + public string Type { get; set; } + public string Uri { get; set; } +} + +public class ExternalUrls +{ + public string Spotify { get; set; } +} diff --git a/MappersBenchmarks/Models/SpotifyAlbumDto.cs b/MappersBenchmarks/Models/SpotifyAlbumDto.cs new file mode 100644 index 0000000..3a78946 --- /dev/null +++ b/MappersBenchmarks/Models/SpotifyAlbumDto.cs @@ -0,0 +1,130 @@ +using System.Text.Json.Serialization; + +namespace MappersBenchmarks.Models; + +public class SpotifyAlbumDto +{ + [JsonPropertyName("album_type")] public string AlbumType { get; set; } + + [JsonPropertyName("artists")] public ArtistDto[] Artists { get; set; } + + [JsonPropertyName("available_markets")] + public string[] AvailableMarkets { get; set; } + + [JsonPropertyName("copyrights")] public CopyrightDto[] Copyrights { get; set; } + + [JsonPropertyName("external_ids")] public ExternalIdsDto ExternalIds { get; set; } + + [JsonPropertyName("external_urls")] public ExternalUrlsDto ExternalUrls { get; set; } + + [JsonPropertyName("genres")] public object[] Genres { get; set; } + + [JsonPropertyName("href")] public string Href { get; set; } + + [JsonPropertyName("id")] public string Id { get; set; } + + [JsonPropertyName("images")] public ImageDto[] Images { get; set; } + + [JsonPropertyName("name")] public string Name { get; set; } + + [JsonPropertyName("popularity")] public long Popularity { get; set; } + + [JsonPropertyName("release_date")] public string ReleaseDate { get; set; } + + [JsonPropertyName("release_date_precision")] + public string ReleaseDatePrecision { get; set; } + + [JsonPropertyName("tracks")] public TracksDto Tracks { get; set; } + + [JsonPropertyName("type")] public string Type { get; set; } + + [JsonPropertyName("uri")] public string Uri { get; set; } +} + +public class TracksDto +{ + [JsonPropertyName("href")] public string Href { get; set; } + + [JsonPropertyName("items")] public ItemDto[] Items { get; set; } + + [JsonPropertyName("limit")] public long Limit { get; set; } + + [JsonPropertyName("next")] public object Next { get; set; } + + [JsonPropertyName("offset")] public long Offset { get; set; } + + [JsonPropertyName("previous")] public object Previous { get; set; } + + [JsonPropertyName("total")] public long Total { get; set; } +} + +public class ItemDto +{ + [JsonPropertyName("artists")] public ArtistDto[] Artists { get; set; } + + [JsonPropertyName("available_markets")] + public string[] AvailableMarkets { get; set; } + + [JsonPropertyName("disc_number")] public long DiscNumber { get; set; } + + [JsonPropertyName("duration_ms")] public long DurationMs { get; set; } + + [JsonPropertyName("explicit")] public bool Explicit { get; set; } + + [JsonPropertyName("external_urls")] public ExternalUrlsDto ExternalUrls { get; set; } + + [JsonPropertyName("href")] public string Href { get; set; } + + [JsonPropertyName("id")] public string Id { get; set; } + + [JsonPropertyName("name")] public string Name { get; set; } + + [JsonPropertyName("preview_url")] public string PreviewUrl { get; set; } + + [JsonPropertyName("track_number")] public long TrackNumber { get; set; } + + [JsonPropertyName("type")] public string Type { get; set; } + + [JsonPropertyName("uri")] public string Uri { get; set; } +} + +public class ImageDto +{ + [JsonPropertyName("height")] public long Height { get; set; } + + [JsonPropertyName("url")] public string Url { get; set; } + + [JsonPropertyName("width")] public long Width { get; set; } +} + +public class ExternalIdsDto +{ + [JsonPropertyName("upc")] public string Upc { get; set; } +} + +public class CopyrightDto +{ + [JsonPropertyName("text")] public string Text { get; set; } + + [JsonPropertyName("type")] public string Type { get; set; } +} + +public class ArtistDto +{ + [JsonPropertyName("external_urls")] public ExternalUrlsDto ExternalUrls { get; set; } + + [JsonPropertyName("href")] public string Href { get; set; } + + [JsonPropertyName("id")] public string Id { get; set; } + + [JsonPropertyName("name")] public string Name { get; set; } + + [JsonPropertyName("type")] public string Type { get; set; } + + [JsonPropertyName("uri")] public string Uri { get; set; } +} + +public class ExternalUrlsDto +{ + [JsonPropertyName("spotify")] public string Spotify { get; set; } +} diff --git a/MappersBenchmarks/Program.cs b/MappersBenchmarks/Program.cs new file mode 100644 index 0000000..ed0617d --- /dev/null +++ b/MappersBenchmarks/Program.cs @@ -0,0 +1,4 @@ +using BenchmarkDotNet.Running; +using MappersBenchmarks; + +BenchmarkRunner.Run(); diff --git a/MappersBenchmarks/TestData.cs b/MappersBenchmarks/TestData.cs new file mode 100644 index 0000000..fb92e83 --- /dev/null +++ b/MappersBenchmarks/TestData.cs @@ -0,0 +1,230 @@ +using MappersBenchmarks.Models; + +namespace MappersBenchmarks; + +public static class TestData +{ + public static SpotifyAlbumDto ExampleAlbum = new SpotifyAlbumDto + { + AlbumType = "album", + Artists = new[] + { + new ArtistDto + { + ExternalUrls = new ExternalUrlsDto + { + Spotify = "https://open.spotify.com/artist/o8fn439te8tgeu" + }, + Href = "https://api.spotify.com/v1/artists/j9t8w5t549jw4i", + Id = "r8eht9778tjh34w8t4", + Name = "Nick Chapsas", + Type = "artist", + Uri = "spotify:artist:r8eht9778tjh34w8t4" + } + }, + AvailableMarkets = new[] + { + "AD", + "AR", + "AT", + "AU", + "BE", + "BG", + "BO", + "BR", + "CA", + "CH", + "CL", + "CO", + "CR", + "CY", + "CZ", + "DE", + "DK", + "DO", + "EC", + "EE", + "ES", + "FI", + "FR", + "GB", + "GR", + "GT", + "HK", + "HN", + "HU", + "IE", + "IS", + "IT", + "LI", + "LT", + "LU", + "LV", + "MC", + "MT", + "MX", + "MY", + "NI", + "NL", + "NO", + "NZ", + "PA", + "PE", + "PH", + "PT", + "PY", + "RO", + "SE", + "SG", + "SI", + "SK", + "SV", + "TW", + "UY" + }, + Copyrights = new[] + { + new CopyrightDto + { + Text = "(P) 2000 Sony Music Entertainment Inc.", + Type = "P" + } + }, + ExternalIds = new ExternalIdsDto + { + Upc = "4873965873469874" + }, + ExternalUrls = new ExternalUrlsDto + { + Spotify = "https://open.spotify.com/album/98etu0j9r54yjr9y0oj" + }, + Genres = Array.Empty(), + Href = "https://api.spotify.com/v1/albums/98etu0j9r54yjr9y0oj", + Id = "984rjyj940y549", + Images = new[] + { + new ImageDto + { + Height = 69, + Width = 420, + Url = "https://i.scdn.co/image/gunejg4e95g9u54g0w94" + }, + new ImageDto + { + Height = 69, + Width = 420, + Url = "https://i.scdn.co/image/5e675t6u856t" + }, + new ImageDto + { + Height = 69, + Width = 420, + Url = "https://i.scdn.co/image/56rur65ur6" + } + }, + Name = "Keep coding", + Popularity = 69, + ReleaseDate = "1969", + ReleaseDatePrecision = "year", + Tracks = new TracksDto + { + Href = "https://api.spotify.com/v1/albums/e67u567ue567/tracks?offset=0&limit=50", + Items = new[] + { + new ItemDto + { + Artists = new[] + { + new ArtistDto + { + ExternalUrls = new ExternalUrlsDto + { + Spotify = "https://open.spotify.com/artist/43y654ry64rs56y4w" + }, + Href = "https://api.spotify.com/v1/artists/h8w79tr8e9th", + Id = "h3r34ai8o7ht8goiu8a", + Name = "Nick Chapsas", + Type = "artist", + Uri = "spotify:artist:w6456ywe5y6r6yr" + } + }, + DiscNumber = 1, + DurationMs = 42069, + Explicit = false, + Name = "Cmon this is too long", + TrackNumber = 1, + Type = "track", + ExternalUrls = new ExternalUrlsDto + { + Spotify = "spotify:artist:w6456ywe5y6r6yr" + }, + PreviewUrl = "https://p.scdn.co/mp3-preview/3y487th43f98t8347ht89734h98tfh3498frth", + Uri = "spotify:track:t8e4t98h4w5ht4i", + AvailableMarkets = new[] + { + "AD", + "AR", + "AT", + "AU", + "BE", + "BG", + "BO", + "BR", + "CA", + "CH", + "CL", + "CO", + "CR", + "CY", + "CZ", + "DE", + "DK", + "DO", + "EC", + "EE", + "ES", + "FI", + "FR", + "GB", + "GR", + "GT", + "HK", + "HN", + "HU", + "IE", + "IS", + "IT", + "LI", + "LT", + "LU", + "LV", + "MC", + "MT", + "MX", + "MY", + "NI", + "NL", + "NO", + "NZ", + "PA", + "PE", + "PH", + "PT", + "PY", + "RO", + "SE", + "SG", + "SI", + "SK", + "SV", + "TW", + "UY" + } + } + }, + Limit = 50, + Offset = 0, + Total = 13 + } + }; +}