[stringtemplate-interest] Performance improvement in AutoIndentWriter

Terence Parr parrt at cs.usfca.edu
Fri Mar 20 11:53:58 PDT 2009


  interesting. So, the repeated IF statements inside my loop cost more  
than this double O(n) operation before the loop?

str.Contains( '\n' ) || str.Contains( '\r' )

and the replace operations?

Wow, that is not something I would expect to happen. I can take  
another look at this later
Ter

On Mar 17, 2009, at 11:24 AM, Sam Harwell wrote:

> In repeated profiling, I found that AutoIndentWriter.Write(string)  
> consumed just over 10% of the processing time. It was the most  
> expensive terminal function inside StringTemplate. I was able to cut  
> that better than in half by using faster string operations, and only  
> when necessary. Here is my code before and after the change.
>
> Before:
>
> public virtual int Write( string str )
> {
>     int n = 0;
>     int strLength = str.Length;
>     int newlineLength = _newline.Length;
>     for ( int i = 0; i < strLength; i++ )
>     {
>         char c = str[i];
>         // found \n or \r\n newline?
>         if ( c == '\r' || c == '\n' )
>         {
>             _atStartOfLine = true;
>             n += newlineLength; // wrote n more char
>             _writer.Write( _newline );
>             _charPosition = 0;
>             // skip an extra char upon \r\n
>             if ( ( c == '\r' && ( i + 1 ) < strLength && str[i+1] ==  
> '\n' ) )
>             {
>                 i++; // loop iteration i++ takes care of skipping  
> 2nd char
>             }
>             continue;
>         }
>         // normal character
>         // check to see if we are at the start of a line; need  
> indent if so
>         if ( _atStartOfLine )
>         {
>             n += Indent();
>             _atStartOfLine = false;
>         }
>         n++;
>         _writer.Write( c );
>         _charPosition++;
>     }
>     return n;
> }
>
>
> After:
>
> public virtual int Write( string str )
> {
>     if ( string.IsNullOrEmpty( str ) )
>     {
>         return 0;
>     }
>     else if ( str.Contains( '\n' ) || str.Contains( '\r' ) )
>     {
>         str = str.Replace( "\r\n", "\n" );
>         str = str.Replace( '\r', '\n' );
>         if ( _indents.Count > 1 )
>         {
>             string[] lines = str.Split( '\n' );
>             string indent = null;
>             for ( int i = 0; i < lines.Length; i++ )
>             {
>                 if ( ( i > 0 || _charPosition == 0 ) &&  
> lines[i].Length > 0 )
>                 {
>                     if ( indent == null )
>                     {
>                         indent = string.Join( string.Empty,  
> _indents.ToArray() );
>                         if ( indent.Length == 0 )
>                             break;
>                     }
>
>                     lines[i] = indent + lines[i];
>                 }
>             }
>
>             if ( lines.Length == 1 )
>             {
>                 str = lines[0];
>                 _charPosition += str.Length;
>             }
>             else
>             {
>                 str = string.Join( _newline, lines );
>                 _charPosition = lines[lines.Length - 1].Length;
>             }
>         }
>         else
>         {
>             if ( _newline != "\n" )
>                 str = str.Replace( "\n", _newline );
>             _charPosition = str.Length -  
> str.LastIndexOf( _newline[_newline.Length - 1] ) - 1;
>         }
>     }
>     else
>     {
>         if ( _charPosition == 0 && _indents.Count > 1 )
>         {
>             string indent = string.Join( string.Empty,  
> _indents.ToArray() );
>             str = indent + str;
>         }
>
>         _charPosition += str.Length;
>     }
>
>     Writer.Write( str );
>
>     _atStartOfLine = ( _charPosition == 0 );
>     return str.Length;
> }
>
> _______________________________________________
> stringtemplate-interest mailing list
> stringtemplate-interest at antlr.org
> http://www.antlr.org/mailman/listinfo/stringtemplate-interest



More information about the stringtemplate-interest mailing list