I'd ignore that suggestion, as this SO question/answer this SO question/answer demonstrates a performance improvement with .Where().First()
over .First()
.
I'd ignore that suggestion, as this SO question/answer demonstrates a performance improvement with .Where().First()
over .First()
.
I'd ignore that suggestion, as this SO question/answer demonstrates a performance improvement with .Where().First()
over .First()
.
I played with your code quite a bit, and found a way to help performance a bit - this won't help the OutOfMemoryException
with larger sets, but I got {1,2,3} to run twice faster by replacing these lines:
var listMinusOneObject = ints.Select(x => x).ToList(); listMinusOneObject.Remove(listMinusOneObject.Where(x => x == number).First());
With this (seems to produce the same output):
var listMinusOneObject = ints.Where(x => x != number);
and then changing the signatures to take an IEnumerable<int>
instead of a List<int>
: the ToList()
call you have there is costing quite a lot.
I played with your code quite a bit, and found a way to help performance a bit - this won't help the OutOfMemoryException
with larger sets, but I got {1,2,3} to run twice faster by replacing these lines:
var listMinusOneObject = ints.Select(x => x).ToList(); listMinusOneObject.Remove(listMinusOneObject.Where(x => x == number).First());
With this (seems to produce the same output):
var listMinusOneObject = ints.Where(x => x != number);
and then changing the signatures to take an IEnumerable<int>
instead of a List<int>
: the ToList()
call you have there is costing quite a lot.
Pasting your code exactly as is into my IDE, ReSharper gives the following warnings and suggestions:
List<List<int>> returnResult = new List<List<int>>();
Use implicitly typed local variable declaration
I'd also rename returnResult
to just result
, so:
var result = new List<List<int>>();
var newList = new List<int>();
newList.Add(number);
Use collection initializer
Each item in a collection initializer calls Add
on the list, so this is equivalent:
var newList = new List<int> {number};
listMinusOneObject.Remove(listMinusOneObject.Where(x => x == number).First());
Replace with single call to First(..)
I'd ignore that suggestion, as this SO question/answer demonstrates a performance improvement with .Where().First()
over .First()
.
if (listMinusOneObject.Count() > 0)
Use method Any()
That I'd do. Count()
will iterate every item in the list, only to compare against 0; Any()
will return true
as soon as it finds 1 item in the list:
if (listMinusOneObject.Any())
When a foreach
loop can be converted to a LINQ statement, ReSharper is very good at pointing it out. So I replaced your for
loops with foreach
loops (removed the number
declaration/assignment):
var distinctInts = ints.Distinct().ToList();
foreach(var number in distinctInts)
{
var newList = new List<int> {number};
returnResult.Add(newList);
var listMinusOneObject = ints.Select(x => x).ToList();
listMinusOneObject.Remove(listMinusOneObject.Where(x => x == number).First());
if (listMinusOneObject.Any())
{
_GetAllCombinationsOfAllSizes(listMinusOneObject, newList, ref returnResult);
}
}
and
var distinctInts = ints.Distinct().ToList();
foreach (var number in distinctInts)
{
var newList = growingList.ToList();
newList.Add(number);
returnResult.Add(newList);
var listMinusOneObject = ints.Select(x => x).ToList();
listMinusOneObject.Remove(listMinusOneObject.Where(x => x == number).First());
if (listMinusOneObject.Any())
{
_GetAllCombinationsOfAllSizes(listMinusOneObject, newList, ref returnResult);
}
}
And as I expected, ReSharper doesn't suggest anything. Why is that so?
LINQ stands for Language-INtegrated Query. Querying objects does not usually involve side-effects, and this is precisely what's going on in your loops' bodies: you're not querying a List<int>
, you're iterating it. A foreach
loop does that.
That was just cosmetics and minor adjustments (some of which may have a positive impact on performance); there's a lot to be said about your algorithm, I'll leave that to another reviewer.