Roni
Roni

Reputation: 403

Does "string" = "string" cost more memory

As part of the refactor I make to this code, I've come across this snippet of code and I'm debating what's more correct / efficient?

Before:

string CutHeadAndTail(string pattern)
{
    if (pattern[0] == '*')
    {
        pattern = pattern.Substring(1);
    }
    if (pattern[pattern.Length - 1] == '*')
    {
        pattern = pattern.Substring(0, pattern.Length - 1);
    }
    return pattern;
}

After:

private string RemoveAllowedAstrisks(string pattern)
{
    pattern = pattern[0] == '*'?pattern.Substring(1): pattern;
    pattern = pattern[pattern.Length - 1] == '*' ? pattern.Substring(0, pattern.Length - 1) : pattern;

    return pattern;
}

What's better?
I am thinking about the line pattern = pattern[0] == '*'?pattern.Substring(1): pattern; Means, from readability point of view I prefer the second. But in the other hand, the meaning of this expression is the below two options:

  1. pattern[0]=='*' --> in such case pattern will changed to pattern.Substring(1)
  2. else --> pattern = pattern

While if I will choose the first way (ignoring the naming etc.) I have just the first option:

  1. if (pattern[0] == '*')
    {
       pattern = pattern.Substring(1);
    }
    
  2. return pattern;
    

The bottom line: Does the line pattern = pattern cost more memory?

Upvotes: 0

Views: 178

Answers (5)

dumetrulo
dumetrulo

Reputation: 1991

How about the following: calculate whether to trim a character from either front or back or both, and if so, return a substring, otherwise return the string itself.

string CutHeadAndTail(string pattern)
{
    var s = pattern[0] == '*' ? 1 : 0;
    var e = pattern[pattern.Length - 1] == '*' ? 1 : 0;
    return (s > 0 || e > 0) ?
        pattern.Substring(s, pattern.Length - s - e) :
        pattern;
}

Upvotes: 0

Martin Zikmund
Martin Zikmund

Reputation: 39072

I have checked the generated IL code to see what is created.

IL_000e: ldloc.0      // hello
IL_000f: ldc.i4.0     
IL_0010: callvirt     instance char [mscorlib]System.String::get_Chars(int32)
IL_0015: ldc.i4.s     42 // 0x2a
IL_0017: beq.s        IL_001c
IL_0019: ldloc.0      // hello
IL_001a: br.s         IL_0023
IL_001c: ldloc.0      // hello
IL_001d: ldc.i4.1     
IL_001e: callvirt     instance string [mscorlib]System.String::Substring(int32)
IL_0023: stloc.0      // hello

As you can see, the ldloc.0 is exectued in case the : branch of the logical statement is run (IL_0019). Right after that the code jumps to IL_0023 which executes the stloc.0.

This could be an issue with value types, but string is a reference type and such assignment does not affect the memory at all. To prove it, I have created a big string and run a few value = value assignments. The heap size never changed.

string hello = new string('a', 3202340);
hello = hello;
hello = hello;

Heap sizes

Upvotes: 0

Hans Z
Hans Z

Reputation: 4744

Probably best way to do this is via a regex

using System.Text.RegularExpressions;

...
private static Regex leadingTrailingAsterisks = new Regex("(^\\*)|(\\*$)");
private static string RemoveAllowedAsterisks(string pattern)
{
    return leadingTrailingAsterisks.Replace(pattern, "");
}

Upvotes: 0

Rufus L
Rufus L

Reputation: 37020

If you will allow trimming ALL * characters from the beginning and end of the string (like "**some string**"), then you can just do:

private string RemoveAllowedAstrisks(string pattern)
{
    return pattern?.Trim('*');
}

Upvotes: 1

Jonathan Wood
Jonathan Wood

Reputation: 67195

I prefer the first way because it is more simple and makes it easier for the compiler to make any optimizations.

To be truthful, I don't know if the compiler will optimize away pattern = pattern in the second approach. It might. Only speed tests will help you determine that.

Personally, I find the second approach more terse but not more readable. And I wouldn't write code that assigns a variable to itself if I didn't need to do that.

A more readable way would be to use string.Trim(), but I would consider that less efficient.

Upvotes: 0

Related Questions