Imagine that we have the following methods (pseudo C#):
static IEnumerable<T> Iterator<T>()
{
switch (SomeCondition)
{
case CaseA:
yield return default(T);
case CaseB:
yield return default(T);
yield return default(T);
case CaseC:
yield return default(T);
default:
break;
}
}
static IEnumerable<T> Array<T>()
{
switch (SomeCondition)
{
case CaseA:
return new[] { default(T) };
case CaseB:
return new[] { default(T), default(T) };
case CaseC:
return new[] { default(T) };
default:
break;
}
}
Which one will consume less memory (and less GC cycles) if we have many calls to similar like this methods? Does it make sense to write your own Enumerable/Enumerator in order to implement this kind of Enumerable.Once() scenario?
This one is faster than both the others:
static T[] Array<T>()
{
switch (SomeCondition)
{
case CaseA:
return new[1];
case CaseB:
return new[2];
case CaseC:
return new[1];
default:
break;
}
}
But it really isn't going to matter much.
It depends on the T. A large struct, strings, or byte arrays, for example, would do better with an iterator. But in general, for one or two items the array is probably smaller.
But that misses the point. The whole reason it's faster is because the problem space is so small as to be not significant to performance: one or two item sequences are unlikely to be the driving factor for the performance of your app. In that scenario, rather than performance I would be much more worried about other factors like clarity, maintainability, and creating good habits.
Of those, you could argue that the array is clearer or cleaner, because programmers who have not yet encountered iterators can still understand it easily. Personally, I prefer the yield iterator, because I want to be in the habit of reaching for iterators before arrays because iterators tend to have better performance characteristics, and I want to encourage the same habit in others.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With