Daniel Earwicker Daniel Earwicker - 1 month ago 13
C# Question

Optimizing Aggregate for String Concatenation

Update - for those of a facetious frame of mind, you can assume that Aggregate still produces the normal result whatever function is passed to it, including in the case being optimized.

I wrote this program to build a long string of integers from 0 to 19999 separate by commas.

using System;
using System.Linq;
using System.Diagnostics;

namespace ConsoleApplication5
{
class Program
{
static void Main(string[] args)
{
const int size = 20000;

Stopwatch stopwatch = new Stopwatch();

stopwatch.Start();
Enumerable.Range(0, size).Select(n => n.ToString()).Aggregate((a, b) => a + ", " + b);
stopwatch.Stop();

Console.WriteLine(stopwatch.ElapsedMilliseconds + "ms");
}
}
}


When I run it, it says:

5116ms


Over five seconds, terrible. Of course it's because the whole string is being copied each time around the loop.

But what if make one very small change indicated by the comment?

using System;
using System.Linq;
using System.Diagnostics;

namespace ConsoleApplication5
{
using MakeAggregateGoFaster; // <---- inserted this

class Program
{
static void Main(string[] args)
{
const int size = 20000;

Stopwatch stopwatch = new Stopwatch();

stopwatch.Start();
Enumerable.Range(0, size).Select(n => n.ToString()).Aggregate((a, b) => a + ", " + b);
stopwatch.Stop();

Console.WriteLine(stopwatch.ElapsedMilliseconds + "ms");
}
}
}


Now when I run it, it says:

42ms


Over 100x faster.

Question



What's in the MakeAggregateGoFaster namespace?

Update 2: Wrote up my answer here.

Answer

You are 'overriding' System.Linq.Aggregate with your own extension method in namespace MakeAggregateGoFaster.

Perhaps specialised on IEnumerable<string> and making use of a StringBuilder?

Maybe taking an Expression<Func<string, string, string>> instead of a Func<string, string, string> so it can analyse the expression tree and compile some code that uses StringBuilder instead of calling the function directly?

Just guessing.