Performance of Enumerable.Range vs for loop

.net, c#, enumerable, for-loop, performance

Solution

From the following test the `for` is more efficient: (in milliseconds it is +-3 ms difference - which is insignificant..)

var watch = System.Diagnostics.Stopwatch.StartNew();
var stringArra1y = Enumerable.Range(0, 4).Select(i => string.Empty).ToArray();
watch.Stop();
Console.WriteLine(watch.ElapsedTicks); //3305

watch = System.Diagnostics.Stopwatch.StartNew();
var stringArray2 = new string[4];
for (int i = 0; i < stringArray2.Length; i++)
{
    stringArray2[i] = string.Empty;
}
watch.Stop();
Console.WriteLine(watch.ElapsedTicks); //1

But you can instead of using `Enumerable.Range().Select` use `.Repeat`:

var watch = System.Diagnostics.Stopwatch.StartNew();
var stringArra1y = Enumerable.Repeat(string.Empty, 4).ToArray();
watch.Stop();
Console.WriteLine(watch.ElapsedTicks); //391

After saying the above notice that you are talking here about very small collections (4 items). In larger collections, and especially if you remove the `.ToArray()` it doesn't behave the same:

var watch = System.Diagnostics.Stopwatch.StartNew();
var stringArra1y = Enumerable.Repeat(string.Empty, 100000);
watch.Stop();
Console.WriteLine(watch.ElapsedTicks); //360


watch = System.Diagnostics.Stopwatch.StartNew();
var stringArray2 = new string[100000];
for (int i = 0; i < stringArray2.Length; i++)
{
    stringArray2[i] = string.Empty;
}
watch.Stop();
Console.WriteLine(watch.ElapsedTicks); //1335

But I fear with the Select at the end then I might be, in effect, loop twice

Looking though the Reference Source both the `.Range` and `Repeat` are implemented with a `yield return`:

static IEnumerable<int> RangeIterator(int start, int count) {
     for (int i = 0; i < count; i++) yield return start + i;
}

So it too id deffered executed, just like the `.Select` meaning it does not loop twice.

Not that the use of the `Stopwatch` returns different results each run but the overall idea is as presented above

IMO, especially in the case of small collections go for readability over hese minor performance improvements. When you already hit performance issues, only after getting the bigger fish (for instance nested `for` loops on `List<>` instead of using a `HashSet<>`), deal with stuff like this.

Problem

I wondered what the performance overhead is of using `Enumerable.Range` was against using a `foreach` loop. For example: ``` var stringArray = Enumerable.Range(0, 4).Select(i => string.Empty).ToArray(); ``` VS. ``` var stringArray = new string[4]; for (int i = 0; i < formatted.Length; i++) { stringArray[i] = string.Empty; } ``` I spotted these question: Why is Enumerable.Range faster than a direct yield loop? Enumerable.Range implementation Thoughts on foreach with Enumerable.Range vs traditional for loop But I fear with the `Select` at the end then I might be, in effect, loop twice. However I like the elegance of using the `Range` option.

Original source

Related problems