Optimizing Aggregate for String Concatenation [closed]

自闭症网瘾萝莉.ら 提交于 2019-12-02 20:37:35

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.

Why not use one of the other forms of Aggregate?

Enumerable.Range(0, size ).Aggregate(new StringBuilder(),
        (a, b) => a.Append(", " + b.ToString()),
        (a) => a.Remove(0,2).ToString());

You can specify any type for your seed, perform whatever formatting or custom calls are needed in the first lambda function and then customize the output type in the second lambda function. The built in features already provide the flexibility you need. My runs went from 1444ms to 6ms.

Not answering the question, but I think the standard patterns here are to use StringBuilder or string.Join:

string.join(", ",Enumerable.Range(0, size).Select(n => n.ToString()).ToArray())

The reason I asked if it was a puzzle was because a puzzle is allowed to sacrifice robustness in varying degrees as long as it satisfies the letter of the stated problem. With that in mind, here goes:

Solution 1 (runs instantly, problem doesn't validate):

public static string Aggregate(this IEnumerable<string> l, Func<string, string, string> f) {
     return "";
}

Solution 2 (runs about as fast as the problem requires, but ignores the delegate completely):

public static string Aggregate(this IEnumerable<string> l, Func<string, string, string> f) {
    StringBuilder sb = new StringBuilder();
    foreach (string item in l)
        sb.Append(", ").Append(item);
    return sb.Remove(0,2).ToString();
}

Well, that would depend entirely on what code is in the MageAggregateGoFaster namespace now wouldn't it?

This namespace is not part of the .NET runtime, so you've linked in some custom code.

Personally I would think that something that recognizes string concatenation or similar, and builds up a list, or similar, then allocates one big StringBuilder and uses Append.

A dirty solution would be:

namespace MakeAggregateGoFaster
{
    public static class Extensions
    {
        public static String Aggregate(this IEnumerable<String> source, Func<String, String, String> fn)
        {
            StringBuilder sb = new StringBuilder();
            foreach (String s in source)
            {
                if (sb.Length > 0)
                    sb.Append(", ");
                sb.Append(s);
            }

            return sb.ToString();
        }
    }
}

dirty because this code, while doing what you say you experience with your program, does not use the function delegate at all. It will, however, bring down the execution time from around 2800ms to 11ms on my computer, and still produce the same results.

Now, next time, perhaps you should ask a real question instead of just look how clever I am type of chest-beating?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!