Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Will the compiler optimize away creating this list twice?

public SharpQuery Add(params HtmlNode[] elements)
{
    var nodes = new List<HtmlNode>(_context.Count + elements.Length);
    nodes.AddRange(_context);
    nodes.AddRange(elements);
    return new SharpQuery(nodes, this);
}

public SharpQuery(IEnumerable<HtmlNode> nodes, SharpQuery previous = null)
{
    if (nodes == null) throw new ArgumentNullException("nodes");
    _previous = previous;
    _context = new List<HtmlNode>(nodes);
}

I've got a whole bunch of functions that create a new List<T>, add a bunch of nodes to it, then pass it off to that constructor, which takes the list, and creates yet another new list with it.

Is the compiler smart enough to figure out it doesn't really need to create the list twice?

like image 606
mpen Avatar asked Dec 28 '22 05:12

mpen


2 Answers

It isn't a case of being "smart enough" - the compiler does what it is told; you are telling it to create multiple lists: it will create multiple lists.

However, since you release them promptly they should get collected fairly cleanly, hopefully gen-0. So unless you are doing this in a tight loop, I wouldn't get too excited about it.

If you want to avoid the lists, you might consider LINQ Concat, which allows you to append sequences without any extra lists / collections / etc.

like image 54
Marc Gravell Avatar answered Jan 07 '23 12:01

Marc Gravell


If you tell it to create a new object, it will create a new object. I don't think there is an optimization that would replace a constructor call with a cast and an assigment - the compiler must know way too much about what the constructor does to be able to optimize it this way.

Technically, you could do it yourself - _context = (List<HtmlNode>)nodes; - that's what you want the compiler to do. Or, better, _context = nodes as List<HtmlNode> ?? new List<HtmlNode>(nodes).
But in either case the list might be modified outside of your class, so you must be sure it doesn't cause unexpected behaviour.

So far, it smells of premature optimization. Your code looks fine, and I wouldn't change anything before seeing an actual performance problem here.

like image 29
VladV Avatar answered Jan 07 '23 10:01

VladV