Re: StringBuilder Extension: IsQuotedBy

Sébastien Lorion <[email protected]> Fri, 15 Feb 2008 14:10:40 -0500
Newsgroups gmane.comp.windows.devel.dotnet.clr
Message-ID <[email protected]>
GC is taking cpu time, being on another thread does not change that.
The time spent collecting/compacting is less time spent doing real
work. If GC would spend 1 min for each gen0 collection, you would sure
see this as part of the cost.

About your second point, please compare below 2 simple implementations
of IsQuotedBy, both maintainable. The first one is around 10x faster.
That apparently insignificant change can make the difference between a
slow as molasses parser and a speedy one.

using System;
using System.Diagnostics;
using System.Text;

namespace ConsoleApplication1
{
  class Program
  {
    static void Main(string[] args)
    {
      const int IterationCount = 1000000;

      StringBuilder value = new StringBuilder("@asdf@");

      Stopwatch timer = new Stopwatch();

      timer.Start();
      for (int i = 0; i < IterationCount; i++)
      {
        IsQuotedBy(value, "@");
      }
      timer.Stop();
      Console.WriteLine(timer.ElapsedTicks);

      timer.Start();
      for (int i = 0; i < IterationCount; i++)
      {
        IsQuotedByWithAllocation(value, "@");
      }
      timer.Stop();
      Console.WriteLine(timer.ElapsedTicks);

      Console.ReadKey();
    }

    static bool IsQuotedBy(StringBuilder input, string quote)
    {
      if (input.Length < quote.Length * 2)
        return false;

      for (int i = 0; i < quote.Length; i++)
      {
        if (input[i] != quote[i])
          return false;
      }

      for (int i = quote.Length - 1; i >= 0; i--)
      {
        if (input[input.Length - i - 1] != quote[i])
          return false;
      }

      return true;
    }

    static bool IsQuotedByWithAllocation(StringBuilder input, string quote)
    {
      if (input.Length < quote.Length * 2)
        return false;

      for (int i = 0; i < quote.Length; i++)
      {
        if (input[i] != quote[i])
          return false;
      }

      string reverse = Reverse(quote);

      for (int i = 0; i < reverse.Length; i++)
      {
        if (input[input.Length - i - 1] != reverse[i])
          return false;
      }

      return true;
    }

    static string Reverse(string input)
    {
      StringBuilder reversed = new StringBuilder(input.Length);

      for (int i = input.Length - 1; i >= 0; i--)
        reversed.Append(input[i]);

      return reversed.ToString();
    }
  }
}


On 2/15/08, Peter Obiefuna <[email protected]> wrote:
> > Yes, I see that as one action because one cannot go without the other.
>  > But sure, StringBuilder has more than one benefits as you and others
>  > pointed out.
>  >
>  > Sébastien
>
>
>
> I am struggling with seeing object creation and destruction as "one action"
>  ... and then speculate on overall performance based on that 'seeing'. GC
>  work is not happening on my worker thread. It may be important in the grand
>  scheme but that's how far am willing to go.
>  I interpreted the original poster's use of StringBuilder as a 'given'. I
>  imagine he's in the middle of this justifiable 'string-building' exercise
>  and then comes upon a decision to look for delimiters. Arguing that creating
>  StringBuilder for the sake of creating a class would be out of scope and may
>  obfuscate the original problem.
>
>  A perhaps strident note I'd rather chip in here is that programmers who
>  target .NET CLR should focus on writing maintainable code as a major
>  architectural ideal. For that reason, creating a few more properly
>  refactored classes with a single-responsibility concept, in my opinion, is
>  of higher value than than shaving off a million nanoseconds from one task.
>  Putting this in perspective, these kinds of apps hop around networks quite
>  much and there's much to gain from focusing on maintainable code that lays
>  more emphasis on optimizing the way it moves around the network.
>  P
>
>  --------------------------------------------------
>  From: "Sébastien Lorion" <[email protected]>
>  Sent: Friday, February 15, 2008 8:11 AM
>
> To: <[email protected]>
>  Subject: Re: [DOTNET-CLR] StringBuilder Extension: IsQuotedBy
>
>
> > On 2/15/08, Frans Bouma <[email protected]> wrote:
>  >>         That initial size is to prevent memory fragmentation during
>  >> memcpy
>  >>  actions when the buffer needs to be resized. I don't see a relevance
>  >> with
>  >>  object creation speed and that parameter. I think the main reason the
>  >> string
>  >>  builder is there is to avoid having lots of objects to collect. I file
>  >> that
>  >>  kind of action under 'object destruction', not 'creation', though if you
>  >> see
>  >>  that as one action (as creating an object means it also has to be
>  >> collected at
>  >>  some point), you have a point.
>  >>
>  >>                 FB
>  >
>  > Yes, I see that as one action because one cannot go without the other.
>  > But sure, StringBuilder has more than one benefits as you and others
>  > pointed out.
>  >
>  > Sébastien
>  >
>
> > ===================================
>  > This list is hosted by DevelopMentor(R)  http://www.develop.com
>  >
>  > View archives and manage your subscription(s) at
>  > http://discuss.develop.com
>  >
>
>  ===================================
>  This list is hosted by DevelopMentor(R)  http://www.develop.com
>
>  View archives and manage your subscription(s) at http://discuss.develop.com
>


-- 
Sébastien
www.sebastienlorion.com

===================================
This list is hosted by DevelopMentor®  http://www.develop.com

View archives and manage your subscription(s) at http://discuss.develop.com