Code generation tricks

anonymous anonymous at example.com
Tue Jul 23 10:23:13 PDT 2013


On Sunday, 21 July 2013 at 17:24:11 UTC, JS wrote:
> This seems to be a somewhat efficient string splitter
>
> http://dpaste.dzfl.pl/4307aa5f

I probably shouldn't have done this, but I wanted to know what 
that abomination actually does, so I reduced it (code below). In 
the end, all it does is accepting both char and string 
separators, something rather simple when you have static if.

Some comments on the result:

* I think the fiddling with i and r.length is silly, but it had 
some impact on performance, so I left it in.

* Likewise, I'd rather just use std.algorithm.startsWith and not 
distinguish between char and string separators in split. Again, 
performance was slightly worse.

And here it is:

inout(char)[][] split(Separators ...)(inout(char)[] s, Separators 
separators)
{
     size_t i = 0, oldj = 0;
     inout(char)[][] r;

     for(size_t j = 0; j < s.length; j++)
     {
         foreach(si, S; Separators)
         {
             immutable sep = separators[si];

             static if(is(S : char))
             {
                 auto slice = s[j];
                 enum seplen = 1;
             }
             else static if(is(S : const(char)[]))
             {
                 auto slice = s[j .. min(s.length, j + 
sep.length)];
                 immutable seplen = sep.length;
             }
             else static assert(false);

             if(slice == sep)
             {
                 if(r.length <= i) r.length += 5;
                 if(j != 0) r[i++] = s[oldj .. j];
                 j += seplen;
                 oldj = j;
             }
         }
     }

     if(oldj < s.length)
     {
         auto tail = s[oldj .. $];
         if(tail.length > 0)
         {
             if(r.length <= i) r.length++;
             r[i++] = tail;
         }
     }

     r.length = i;
     return r;
}


More information about the Digitalmars-d-learn mailing list