I know it’s impossible to use return and yield return in the same method.
This is the code that I would like to optimize:
public IEnumerable<TItem> GetItems(int data)
{
if (this.isSingleSet)
{
return this.singleSet; // is IEnumerable per-se
}
else
{
int index = this.GetSet(data);
foreach(TKey key in this.keySets[index])
{
yield return this.items[key];
}
}
}
Important: I know this code doesn’t compile. It’s the code I have to optimize.
There are two ways that I know of that would make this method working:
-
convert
yield returnpart:... else { int index = this.GetSet(data); return this.keySets[index].Select(key => this.items[key]); } -
convert
returnpart:if (this.isSingleSet) { foreach(TItem item in this.singleSet) { yield return item; } } else ...
But there’s a big speed difference between the two. Using only return statements (in other words using Select()) is much much slower (like 6 times slower) to yield return conversion.
Question
Is there any other way that comes to your mind how to write this method? Do you have any other suggestions information that would be valuable to performance discrepancy?
Additional info
I was measuring speed of the two methods by using stopwatch around a for loop.
Stopwatch s = new Stopwatch();
s.Start();
for(int i = 0; i < 1000000; i++)
{
GetItems(GetRandomData()).ToList();
}
s.Stop();
Console.WriteLine(s.ElapsedMilliseconds);
Each of these were loops were run in separate processes so there was could be no performance influence by garbage collection or anything else.
- I’ve run the program with one method version then
- Closed it
- Rewrote the method and run it again.
Did this few times to see reliable performance difference…
Use two functions. The outer, called by clients, function does all the non-lazy bits (like parameter validation) that you don’t want to delay. The private worker does the lazy bits: