GC question
Cym13 via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Sun Feb 5 05:08:37 PST 2017
On Sunday, 5 February 2017 at 04:22:30 UTC, rikki cattermole
wrote:
> On 05/02/2017 5:02 PM, thedeemon wrote:
>
> snip
>
>> It may look so from a distance. But in my experience it's not
>> that bad.
>> In most software I did in D it did not matter really (it's
>> either 64-bit
>> or short lived programs) and the control D gives to choose how
>> to deal
>> with everything makes it all quite manageable, I can decide
>> what to take
>> from both worlds and hence pick the best, not the worst.
>
> The best of both worlds can be done quite simply.
>
> Instead of a chain of input ranges like:
>
> int[] data = input.filter!"a != 7".map!"a * 2".array;
>
> Use:
>
> int[] data;
> data.length = input.length;
>
> size_t i;
> foreach(v; input.filter!"a != 7".map!"a * 2") {
> data[i] = v;
> i++;
> }
>
> data.length = i;
>
> Of course this is dirt simple example, but instead look at it
> for e.g. a csv parser with some complex data structure creation
> + manipulation.
>
> I have some real world code here[0] that uses it. Not only is
> there less allocations and uses the GC but also it ends up
> being significantly faster!
>
> [0]
> https://gist.github.com/rikkimax/42c3dfa6500155c5e441cbb1437142ea#file-reports-d-L124
Some data to weigh that in order to compare different memory
management strategies on that simple case:
#!/usr/bin/env rdmd
import std.conv;
import std.stdio;
import std.array;
import std.range;
import std.algorithm;
auto input = [1, 2, 7, 3, 7, 8, 8, 9, 7, 1, 0];
void naive() {
int[] data = input.filter!(a => a!= 7).map!(a => a*2).array;
assert(data == [2, 4, 6, 16, 16, 18, 2, 0], data.to!string);
}
void maxReallocs() {
int[] data;
size_t i;
foreach(v ; input.filter!(a => a!=7).map!(a => a*2)) {
data ~= v;
}
assert(data == [2, 4, 6, 16, 16, 18, 2, 0], data.to!string);
}
void betterOfTwoWorlds() {
int[] data;
data.length = input.length;
size_t i;
foreach(v ; input.filter!(a => a!=7).map!(a => a*2)) {
data[i] = v;
i++;
}
data.length = i;
assert(data == [2, 4, 6, 16, 16, 18, 2, 0], data.to!string);
}
void explicitNew() {
int[] data = new int[input.length];
scope(exit) delete data;
size_t i;
foreach(v ; input.filter!(a => a!=7).map!(a => a*2)) {
data[i] = v;
i++;
}
data.length = i;
assert(data == [2, 4, 6, 16, 16, 18, 2, 0], data.to!string);
}
void cStyle() @nogc {
import std.c.stdlib;
int* data = cast(int*)malloc(input.length * int.sizeof);
scope(exit) free(data);
size_t i;
foreach(v ; input.filter!(a => a!=7).map!(a => a*2)) {
data[i++] = v;
}
debug assert(data[0..i] == [2, 4, 6, 16, 16, 18, 2, 0],
data.to!string);
}
void onTheStack() @nogc {
int[100] data;
size_t i;
foreach(v ; input.filter!(a => a!=7).map!(a => a*2)) {
data[i++] = v;
}
debug assert(data[0..i] == [2, 4, 6, 16, 16, 18, 2, 0],
data.to!string);
}
void main(string[] args) {
import std.datetime;
benchmark!(
naive,
maxReallocs,
betterOfTwoWorlds,
explicitNew,
cStyle,
onTheStack
)(100000).each!writeln;
}
/* Results:
Compiled with dmd -profile=gc test.d
====================================
TickDuration(385731143) // naive,
TickDuration(575673615) // maxReallocs,
TickDuration(255928562) // betterOfTwoWorlds,
TickDuration(270497154) // explicitNew,
TickDuration(97596363) // cStyle,
TickDuration(96467459) // onTheStack
GC usage:
bytes allocated, allocations, type, function, file:line
17600000 100000 int[] test.explicitNew test.d:43
4400000 100000 int[] test.betterOfTwoWorlds
test.d:30
3200000 800000 int[] test.maxReallocs test.d:22
3200000 100000 int[] test.maxReallocs test.d:25
3200000 100000 int[] test.explicitNew test.d:51
3200000 100000 int[] test.explicitNew test.d:53
3200000 100000 int[] test.betterOfTwoWorlds
test.d:37
3200000 100000 int[] test.betterOfTwoWorlds
test.d:39
3200000 100000
std.array.Appender!(int[]).Appender.Data
std.array.Appender!(int[]).Appender.this
/usr/include/dlang/dmd/std/array.d:2675
3200000 100000 int[] test.naive test.d:14
Compiled with dmd -O -inline test.d
===================================
TickDuration(159383005) // naive,
TickDuration(187192137) // maxReallocs,
TickDuration(94094585) // betterOfTwoWorlds,
TickDuration(102374657) // explicitNew,
TickDuration(41801695) // cStyle,
TickDuration(45613954) // onTheStack
Compiled with dmd -O -inline -release -boundscheck=off test.d
=============================================================
TickDuration(152151439) // naive,
TickDuration(140870515) // maxReallocs,
TickDuration(46740440) // betterOfTwoWorlds,
TickDuration(59089016) // explicitNew,
TickDuration(26038060) // cStyle,
TickDuration(25984371) // onTheStack
*/
More information about the Digitalmars-d-learn
mailing list