Top 5
Sergey Gromov
snake.scaly at gmail.com
Sat Oct 11 12:30:06 PDT 2008
Sat, 11 Oct 2008 15:00:20 -0400,
Benji Smith wrote:
> Sergey Gromov wrote:
> > I took the trouble to port your Appender to DMD 1.033 and fixed Benji's
> > benchmark to use it. Here's my timings, best of 5 runs each:
>
> Hey, would you mind sending me a copy of that Appender? I was about to
> start backporting it myself, but then I figured it'd be a better
> apples-to-apples comparison if I use the version you've already written.
Here's everything. Sorry for a long post! :D
module d1;
template Const(T) {
version (D_Version2)
mixin("alias const(T) Const;");
else
alias T Const;
}
template Invariant(T) {
version (D_Version2)
mixin("alias invariant(T) Invariant;");
else
alias T Invariant;
}
module appender;
import std.gc: capacity;
import d1;
struct Appender(A : T[], T)
{
private T[] * pArray;
private size_t _capacity;
version (D_Version2)
{
this(T[] * p)
{
pArray = p;
if (!pArray) pArray = (new typeof(*pArray)[1]).ptr;
_capacity = .capacity(pArray.ptr) / T.sizeof;
}
}
else
{
static Appender opCall(T[] * p)
{
Appender r;
r.pArray = p;
if (!r.pArray) r.pArray = (new typeof(*r.pArray)[1]).ptr;
r._capacity = .capacity(r.pArray.ptr) / T.sizeof;
return r;
}
}
T[] data()
{
return pArray ? *pArray : null;
}
size_t capacity() /+ const +/ { return _capacity; }
void write(T item)
{
if (!pArray) pArray = (new typeof(*pArray)[1]).ptr;
if (pArray.length < _capacity)
{
// Should do in-place construction here
pArray.ptr[pArray.length] = item;
*pArray = pArray.ptr[0 .. pArray.length + 1];
}
else
{
// Time to reallocate, do it and cache capacity
*pArray ~= item;
_capacity = .capacity(pArray.ptr) / T.sizeof;
}
}
static if (is(Const!(T) : T))
{
alias Const!(T) AcceptedElementType;
}
else
{
alias T AcceptedElementType;
}
void write(AcceptedElementType[] items)
{
while (items.length)
{
write(items[0]);
items = items[1..$];
}
}
void clear()
{
if (!pArray) return;
pArray.length = 0;
_capacity = .capacity(pArray.ptr) / T.sizeof;
}
}
module StringTest2;
import tango.io.FileConduit;
import tango.io.Stdout;
import tango.time.StopWatch;
import Util = tango.text.Util;
import appender;
void main() {
StopWatch overallWatch;
overallWatch.start();
StopWatch loadWatch;
loadWatch.start();
auto file = new FileConduit("shakespeare.txt");
char[] text = new char[cast(size_t)file.length];
file.input.read(text);
Stdout.formatln("time to load file: {0:f6} seconds", loadWatch.stop());
runCharIterateTest(text);
runWordFindTest(text);
runWordReplaceTest(text);
char[][] splitWords = runWordSplitTest(text);
runConcatenateTest(splitWords);
Stdout.formatln("overall test duration: {0:f6} seconds", overallWatch.stop());
}
private static void runCharIterateTest(char[] text) {
StopWatch watch;
watch.start();
int spaceCount = 0;
foreach (dchar c; text) {
if (c == ' ') spaceCount++;
}
Stdout.formatln("iterated through {0} characters, and found {1} spaces in {2:f6} seconds", text.length, spaceCount, watch.stop());
}
private static void runWordFindTest(char[] text) {
StopWatch watch;
watch.start();
int wordInstanceCount = -1;
int position = 0;
do {
wordInstanceCount++;
position = Util.locatePattern(text, "the", position + 1);
} while (position < text.length);
Stdout.formatln("String.indexOf(): found {0} instances of 'the' in {1:f6} seconds", wordInstanceCount, watch.stop());
}
private static void runWordReplaceTest(char[] text) {
int oldLength = text.length;
StopWatch watch;
watch.start();
char[] replaced = Util.substitute(text, "the", "XXXX");
int newLength = replaced.length;
int replacementCount = newLength - oldLength;
Stdout.formatln("replaced {0} instances of 'the' with 'XXXX' in {1:f6} seconds", replacementCount, watch.stop());
}
private static char[][] runWordSplitTest(char[] text) {
StopWatch watch;
watch.start();
Appender!(char[][]) splitWords;
foreach (segment; Util.patterns (text, " "))
splitWords.write(segment);
Stdout.formatln("split text into {0} words in {1:f6} seconds", splitWords.data.length, watch.stop());
return splitWords.data;
}
private static void runConcatenateTest(char[][] splitWords) {
StopWatch watch;
watch.start();
Appender!(char[]) buffer;
foreach (char[] word; splitWords) {
buffer.write(word);
buffer.write(" ");
}
Stdout.formatln("concatenated {0} words (with {1} chars) in {2:f6} seconds", splitWords.length, buffer.data.length, watch.stop());
}
More information about the Digitalmars-d
mailing list