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