Re: StringBuilder Extension: IsQuotedBy

Sébastien Lorion <[email protected]> Fri, 15 Feb 2008 14:24:47 -0500
Newsgroups gmane.comp.windows.devel.dotnet.clr
Message-ID <[email protected]>
Sure ... I was conforming to original signatures. With one char,
reversing also becomes irrelevant.

About that, Brady, I never ever got the demand to support a multi-char
delimiter and I have never saw that in other CSV-like parsers.

Sébastien

On 2/15/08, Greg Young <[email protected]> wrote:
> Getting back to my original comment (which applies greatly here) ...
>
>  IsQuotedBy needs to be special cased for a single char ... Most of the
>  time it will be called with only 1 char (think quotes :)) and doing a
>  simpler ...
>
>  return string[0] == char && string[length - 1] == char
>
>  will be orders of magnitude faster ...
>
>
>  Cheers,
>
>  Greg
>
>
>  On Fri, Feb 15, 2008 at 11:10 AM, Sébastien Lorion
>  <[email protected]> wrote:
>  > 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(R)  http://www.develop.com
>  >
>  >  View archives and manage your subscription(s) at http://discuss.develop.com
>  >
>
>
>
>
> --
>
> Studying for the Turing test
>
>  ===================================
>
> 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