This question is specifically in the context of in-memory data, and not related to query translation frameworks (eg. not related to Entity Framework and how it can and can't transcribe certain Linq queries).
Assuming we have an IEnumerable
containing type:
class Exemplar
{
public Guid UniqueId { get; set; }
public string Name { get; set; }
public string[] FriendNames { get; set; }
}
var exampleData = new List<Exemplar>(); // pretend I'm populated
and our business rules are something like:
- An
Exemplar
is invalid if itsFriendNames
contains an entry that does not appear as aName
of anotherExemplar
in ourexampleData
- If an invalid
Exemplar
is found, write out it'sUniqueId
and its invalidFriendNames
I'm used to writing Linq queries that use anonymous types as intermediate structures in the chain. For example:
var invalidExemplars =
exampleData
.Select(x =>
new
{
Id = x.UniqueId,
InvalidNames = x.FriendNames.Where(n => exampleData.All(d => d.Name != n)).ToArray()
})
.Where(x => x.InvalidNames.Any());
// added for completion, maybe irrelevant to the question
if (invalidExemplars.Any())
{
Console.WriteLine(string.Join(Environment.NewLine, invalidExemplars.Select(x => $"{x.Id}: [{ string.Join(",", x.InvalidNames)}]")));
}
But now with C# 7 we can instead use the new tuple shorthand instead of the anonymous type:
var invalidExemplars =
exampleData
.Select(x =>
(
Id: x.UniqueId,
InvalidNames: x.FriendNames.Where(n => exampleData.All(d => d.Name != n)).ToArray()
))
.Where(x => x.InvalidNames.Any());
My question is are there any performance differences between an intermediary anonymous type vs an intermediary tuple, and if so what are they?
Is there any reason (other than personal preference) to choose one over the other as an intermediary?
CodePudding user response:
There are some very subtle differences with Anonymous Types and Value Tuples.
- Equality
- Storage - heaps / stack
- Parameter naming
- Expression trees
- Syntax - Construction syntax, deconstruction etc
- Usage - how you can use them as method parameters etc
Since this question is about Intermediary usage, the Value Tuple will likely be heap allocated anyway because of LINQ, Expression Trees and ORMS are out of the equation. Then there is very little difference apart from equality and syntax, additionally the performance impact will be fairly unnoticeable. So the answer really comes down to pick your favourite.
Additional resources
Choosing between anonymous and tuple types
Tradeoffs
You might want to always use ValueTuple over Tuple, and anonymous types, but there are tradeoffs you should consider. The ValueTuple types are mutable, whereas Tuple are read-only. Anonymous types can be used in expression trees, while tuples cannot. The following table is an overview of some of the key differences.
KEY DIFFERENCES
Name | Access modifier | Type | Custom name | Deconstruction | Expression tree |
---|---|---|---|---|---|
Anonymous types | internal | class | ✔️ | ❌ | ✔️ |
Tuple | public | class | ❌ | ❌ | ✔️ |
ValueTuple | public | struct | ✔️ | ✔️ | ❌ |
Performance
Performance between these types depends on the scenario. The major impact involves the tradeoff between allocations and copying. In most scenarios, the impact is small. When major impacts could arise, measurements should be taken to inform the decision.
Further Reading