0

Looking for better algorithm / technique for replacing strings in a string variable. I have to loop through an unknown number of database records and for each one, I need to replace some text in a string variable. Right now it looks like this, but there has to be a better way:

using (eds ctx = new eds())
{
    string targetText = "This is a sample string with words that will get replaced based on data pulled from the database";

    List<parameter> lstParameters = ctx.ciParameters.ToList();
    foreach (parameter in lstParameters)
    {
        string searchKey = parameter.searchKey;
        string newValue = parameter.value;
        targetText = targetText.Replace(searchKey, newValue);
    }
}

From my understanding this is not good because I'm over writing the targetText variable, over and over in the loop. However, I'm not sure how structure the find and replace...

Appreciate any feedback.

Thomas Ficker
  • 49
  • 1
  • 7
  • You are concerned about performance or the fact that it is possible that some replaced value is replace again (`"asd".Replace("a", "s").Replace("s", "d")`)?. – Prusse Jul 20 '15 at 15:38

3 Answers3

4

there has to be a better way

Strings are immutable - you can't "change" them - all you can do is create a new string and replace the variable value (which is not as bad as you think). You could try using a StringBuilder as other suggest, but it's not 100% guaranteed to improve your performance.

You could change your algorithm to loop through the "words" in targetText, see if there's a match in parameters , take the "replacement" value and build up a new string, but I suspect the extra lookups will cost more than recreating the string value multiple times.

In any case, two important principles of performance improvement should be considered:

  • Start with the slowest part of your app first - you may see some improvement but if it does not improve the overall performance significantly then it doesn't matter that much
  • The only way to know if a particular change will improve your performance (and by how much) is to try it both ways and measure it.
D Stanley
  • 149,601
  • 11
  • 178
  • 240
  • Why isn`t in certain conditions a StringBuilder.Replace() a good alternative? It is mutable and the overhead might not always be a problem. Please correct me if I´m wrong – Marc Wittmann Jul 20 '15 at 15:48
  • @MarcWittmann It may be, and I will amend my answer to make it less absolute. – D Stanley Jul 20 '15 at 15:52
0

StringBuilder will have less memory overhead and better performance, especially on large strings. String.Replace() vs. StringBuilder.Replace()

using (eds ctx = new eds())
{
    string targetText = "This is a sample string with words that will get replaced based on data pulled from the database";

    var builder = new StringBuilder(targetText);

    List<parameter> lstParameters = ctx.ciParameters.ToList();
    foreach (parameter in lstParameters)
    {
        string searchKey = parameter.searchKey;
        string newValue = parameter.value;
        targetText = builder.Replace(searchKey, newValue);
    }
}
Community
  • 1
  • 1
Daniel Luberda
  • 7,374
  • 1
  • 32
  • 40
0

Actually, there is a better answer, assuming you're doing a large number of replacements. You can use a StringBuilder. As you know, strings are immutable. So as you said, you're creating strings over and over again in your loop.

If you convert your string to a StringBuilder

StringBuilder s = new StringBuilder(s, s.Length*2); // Adjust the capacity based on how much bigger you think the string will get due to replacements. The more accurate your estimate, the better this will perform.

  foreach (parameter in lstParameters)
    {
        s.Replace(parameter.searchKey, parameter.value);
    }
  string targetString = s.ToString();

Now a caveat, if your list only has 2-3 items in it, this might not be any better. The answer to this question provides a nice analysis of the performance improvement you can expect to see.

Community
  • 1
  • 1
dmeglio
  • 2,830
  • 1
  • 19
  • 24