dmd/druntime/benchmark/gcbench/conmsg.d
2022-07-09 18:53:15 +02:00

95 lines
2 KiB
D

/**
* This benchmarks GC in a producer-consumer program.
*
* Copyright: Copyright Martin Nowak 2014 -.
* License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
* Authors: Martin Nowak
*/
import std.algorithm, std.concurrency, std.conv, std.file, std.json, std.range;
JSONValue buildVal(in dchar[] word) pure
{
JSONValue[string] res;
res["word"] = word.to!string;
res["length"] = word.length;
auto pos = new size_t[word.length];
foreach (i; 0 .. pos.length)
pos[i] = i;
res["array"] = pos;
return JSONValue(res);
}
void producer(Tid consumer)
{
auto text = cast(string)read("extra-files/dante.txt");
foreach (word; text.splitter.map!(to!(dchar[])))
{
foreach (_; 0 .. 7)
{
immutable val = buildVal(word);
consumer.send(val);
if (!nextPermutation(word)) break;
}
}
}
void serialize(in JSONValue val, ref ubyte[] buf)
{
with (JSONType) switch (val.type)
{
case object:
foreach (k, v; val.object)
{
buf ~= cast(ubyte[])k;
serialize(v, buf);
}
break;
case array:
foreach (v; val.array)
serialize(v, buf);
break;
case uinteger:
ulong v = val.uinteger;
buf ~= (cast(ubyte*)&v)[0 .. v.sizeof];
break;
case string:
buf ~= cast(ubyte[])val.str;
break;
default:
assert(0);
}
}
struct Socket
{
static void send(ubyte[] buf) { _buf = buf; }
static ubyte[] _buf; // keep a reference
}
void log(string s)
{
__gshared size_t dummy;
dummy = s.length;
}
void consumer()
{
scope (failure) assert(0);
while (true)
{
auto msg = receiveOnly!(Variant);
if (msg.peek!OwnerTerminated) return;
auto val = msg.get!(immutable JSONValue);
ubyte[] buf; serialize(val, buf);
Socket.send(buf);
}
}
void main(string[] args)
{
producer(spawn(&consumer));
}