fastest way to replace string in a template

2020-02-21 08:31发布

I have some template string

this is my {0} template {1} string

which I plan to put user values in using String.Format().

The string actually is longer so for readability I use:

this is my {goodName1} template {goodName2} string

And then String.Replace each parameter with its value.

How can I get the highest performance and readability?

Maybe I should not have this template in a file (as now) but dynamically build it by concatanating to a string builder and adding the params when required? Although it's less readable.

What's my other options?

9条回答
放荡不羁爱自由
2楼-- · 2020-02-21 08:36

My spontaneous solution would look like this:

string data = "This is a {template1} that is {template2}.";

Dictionary<string, string> replacements = new Dictionary<string, string>(){
    {"{template1}", "car"},
    {"{template2}", "red"},
};

foreach (string key in replacements.Keys)
{
    data = data.Replace(key, replacements[key]);
}
Console.WriteLine(data); // outputs "This is a car that is red."

I have used this kind of template replacements in several real-world projects and have never found it to be a performance issue. Since it's easy to use and understand, I have not seen any reason to change it a lot.

查看更多
趁早两清
3楼-- · 2020-02-21 08:36

BEWARE of getting bogged down with this type of thinking. Unless this code is running hundreds of time per minute and the template file is several K in size, it is more important to get it done. Do not waste a minute thinking about problems like this. In general, if you are doing a lot with string manipulations, then use a string builder. It even has a Replace method. But, why bother. When you are done, and IF you find that you have a performance problem, use PerfMon and fix the REAL bottlenecks at that time.

查看更多
Juvenile、少年°
4楼-- · 2020-02-21 08:39

Like anything, it depends. If the code is going to be called millions of times every day, then think about performance. If it's a few times a day then go for readability.

I've done some benchmarking between using normal (immutable) strings and StringBuilder. Until you start doing a huge amount in small bit of time, you don't need to worry about it too much.

查看更多
看我几分像从前
5楼-- · 2020-02-21 08:41

Just modified the above answer to the following:

    string data = "This is a {template1} that is {template2}.";

    Dictionary<string, string> replacements = new Dictionary<string, string>(){
        {"{template1}", "car"},
        {"{template2}", "red"},
    };

    data.Parse(replacements);

Extension method:

public static class Parser
{
    public static string Parse(this string template, Dictionary<string, string> replacements)
    {
        if (replacements.Count > 0)
        {
            template = replacements.Keys
                        .Aggregate(template, (current, key) => current.Replace(key, replacements[key]));
        }
        return template;
    }
}

Hope this helps.. :)

查看更多
你好瞎i
6楼-- · 2020-02-21 08:42

You can put the parameters in a dictionary and use the Regex.Replace method to replace all of the parameters in one replacement. That way the method scales well if the template string gets long or the number of parameters grows.

Example:

Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters.Add("goodName1", "asdf");
parameters.Add("goodName2", "qwerty");
string text = "this is my {goodName1} template {goodName2} string";
text = Regex.Replace(text, @"\{(.+?)\}", m => parameters[m.Groups[1].Value]);
查看更多
我欲成王,谁敢阻挡
7楼-- · 2020-02-21 08:50

The fastest way to do it is with a StringBuilder using individual calls to StringBuilder.Append(), like this:

string result = new StringBuilder("this is my ")
                 .Append(UserVar1)
                 .Append(" template ")
                 .Append(UserVar2)
                 .Append(" string")
                 .ToString();

I've thoroughly benchmarked the framework code, and this will be fastest. If you want to improve readability you could keep a separate string to show the user, and just use this in the background.

查看更多
登录 后发表回答