Get Character At?

Derek Parnell derek at psych.ward
Wed Apr 25 05:48:41 PDT 2007


On Wed, 25 Apr 2007 13:41:25 +1000, Daniel Keep wrote:

> Incidentally, I don't suppose you know anything about the relative
> performance of your method up there ^^ and the one in my article down
> here vv:

It seems that your routine is about 3 times slower than the one I had
shown. Here is my test program ... I modified your routine slightly because
the idiom "if (x++ == n)" is a dangerous one as it is unclear if 'x' gets
incremented before or after the comparision. I changed it to be more clear.
I also changed my routine to output a dchar rather than a char[] and to
test for invalid position input.

//-----------------------------
import std.perf;
import std.stdio;
import std.utf;


 dchar getCharAt(T)(T pText, int pPos)
 {
       size_t lUTF_Index;
       uint   lStride;

       if (pPos < 0 || pPos >= pText.length)
        return dchar.init;
       // Firstly, find out where the character starts in the string.
       lUTF_Index = std.utf.toUTFindex(pText, pPos);

       // Then find out its width (in bytes)
       lStride = std.utf.stride(pText, lUTF_Index);

       // Return the character encoded in UTF format.
       return std.utf.toUTF32(
                pText[lUTF_Index .. lUTF_Index + lStride])[0];
}

dchar nthCharacter(T)(T string, int n)
{
    int curChar = 0;
    foreach( dchar cp ; string )
    {
        if( curChar == n )
            return cp;
        curChar++;
    }
    return dchar.init;
}

void main()
{
    char[] text = "a\ua034bcdefa\ua034bcdefa\ua034bcdefa\ua034bcdefg1"
                  "a\ua034bcdefa\ua034bcdefa\ua034bcdefa\ua034bcdefg2"
                  "a\ua034bcdefa\ua034bcdefa\ua034bcdefa\ua034bcdefg3"
                  "a\ua034bcdefa\ua034bcdefa\ua034bcdefa\ua034bcdefg4"
                  "a\ua034bcdefa\ua034bcdefa\ua034bcdefa\ua034bcdefg5"
                  "a\ua034bcdefa\ua034bcdefa\ua034bcdefa\ua034bcdefg6"
                  ;
    // Test must locate the last character.
    int loc = std.utf.toUTF32(text).length-1;

    assert(getCharAt(text, loc) == '6');
    assert(nthCharacter(text, loc) == '6');

    PerformanceCounter    counter = new PerformanceCounter();

    counter.start();
    volatile for(int i = 0; i < 10_000_000; ++i)
    {  getCharAt(text, loc); }
    counter.stop();

    writefln("Derek Parnell: %10d", counter.microseconds());

    counter.start();
    volatile for(int i = 0; i < 10_000_000; ++i)
    {  nthCharacter(text, loc); }
    counter.stop();

    writefln("  Daniel Keep: %10d", counter.microseconds());
}
//-----------------------------

On my machine (Intel Core 2 6600 @ 2.40GHz, 2GB RAM) I got this result ...

c:\temp>test
Derek Parnell:    7939664
  Daniel Keep:   26683373

-- 
Derek Parnell
Melbourne, Australia
"Justice for David Hicks!"
skype: derek.j.parnell


More information about the Digitalmars-d-learn mailing list