Home > Mobile >  Anonymous type vs tuple in Linq query, performance considerations
Anonymous type vs tuple in Linq query, performance considerations

Time:09-24

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 its FriendNames contains an entry that does not appear as a Name of another Exemplar in our exampleData
  • If an invalid Exemplar is found, write out it's UniqueId and its invalid FriendNames

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

  • Related