13
\$\begingroup\$

I need to prepend N spaces to a string to make it 10 characters in length. I came up with the following method, but since it is going to be called often, I want to ensure it is optimized. Could this be made more efficient?

public static string PrependSpaces(string str)
{
    StringBuilder sb = new StringBuilder();
    sb.Append(str);
    for (int i = 0; i < (10 - str.Length); i++)
    {
        sb.Insert(0, " ");
    }
    return sb.ToString();
}
\$\endgroup\$
14
\$\begingroup\$

If you need to prepend a number of characters to a string you might consider String.PadLeft().

For example:

string str = "abc123";
Console.WriteLine(str);
str = str.PadLeft(10);
Console.WriteLine(str);

Will produce:

abc123
    abc123

On the efficiency of your example, StringBuilder.Append() is more efficient than StringBuilder.Insert(), so you might try something like:

public static string PrependSpaces2(string str)
{
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < (10 - str.Length); i++)
    {
        sb.Append(" ");
    }
    sb.Append(str);
    return sb.ToString();
}

EDIT As svick suggested, Append(char, repeat) is simpler and faster on the order of the native Pad methods:

public static string PrependSpaces3(string str)
    StringBuilder sb = new StringBuilder();
    if((NUM - str.Length) > 0)
    {
        sb.Append(' ', (NUM - str.Length));
    }
    sb.Append(str);
    return sb.ToString();
}

Which when tested with this:

string str = "abc123";
Console.WriteLine("str: " + str);

int iterations = 100000;

string result = string.Empty;
Stopwatch s1 = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
    result = PrependSpaces(str);
}
s1.Stop();
Console.WriteLine(iterations + " calls to PrependSpaces took: {0:0.00 ms}", s1.Elapsed.TotalMilliseconds);

string result2 = string.Empty;
Stopwatch s2 = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
    result2 = PrependSpaces2(str);
}
s2.Stop();
Console.WriteLine(iterations + " calls to PrependSpaces2 took: {0:0.00 ms}", s2.Elapsed.TotalMilliseconds);

string result3 = string.Empty;
Stopwatch s3 = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
    result3 = str.PadLeft(NUM, ' ');
}
s3.Stop();
Console.WriteLine(iterations + " calls to String.PadLeft(" + NUM + ", ' ') took: {0:0.00 ms}", s3.Elapsed.TotalMilliseconds);

string result4 = string.Empty;
Stopwatch s4 = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
    result4 = PrependSpaces3(str);
}
s4.Stop();
Console.WriteLine(iterations + " calls to PrependSpaces3 took: {0:0.00 ms}", s3.Elapsed.TotalMilliseconds);

returns this (benchmarks for prepending 1000 characters):

str: abc123
100000 calls to PrependSpaces took: 20190.16 ms
100000 calls to PrependSpaces2 took: 1025.87 ms
100000 calls to String.PadLeft(1000, ' ') took: 84.32 ms
100000 calls to PrependSpaces3 took: 84.32 ms

for prepending 10 characters:

100000 calls to PrependSpaces took: 31.02 ms
100000 calls to PrependSpaces2 took: 11.41 ms
100000 calls to String.PadLeft(10, ' ') took: 4.53 ms
100000 calls to PrependSpaces3 took: 4.53 ms
\$\endgroup\$
  • 2
    \$\begingroup\$ Instead of the Append() loop, you can use sb.Append(' ', 10 - str.Length). \$\endgroup\$ – svick Nov 30 '13 at 3:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.