Patterns to avoid GC with capturing closures?
vit
vit at vit.vit
Sun Aug 26 06:08:39 UTC 2018
On Friday, 24 August 2018 at 15:18:13 UTC, Peter Alexander wrote:
> Consider this code, which is used as an example only:
>
> auto scaleAll(int[] xs, int m) {
> return xs.map!(x => m * x);
> }
>
> As m is captured, the delegate for map will rightly allocate
> the closure in the GC heap.
>
> In C++, you would write the lambda to capture m by value, but
> this is not a facility in D.
>
> I can write scaleAll like this:
>
> auto scaleAll(int[] xs, int m) @nogc {
> return repeat(m).zip(xs).map!(mx => mx[0] * mx[1]);
> }
>
> So that repeat(m) stores m, but it is quite hacky to work like
> this.
>
> I could write my own range that does this, but this is also not
> desirable.
>
> Are there any established patterns, libraries, or language
> features that can help avoid the GC allocation in a principled
> way here?
I try pack/unpack solution, but it looks horrible.
Problem is when every part of chain (filter, map, ...) need
capture different variables.
I implement modified version of algorithm (filter, map, until,
tee): https://dpaste.dzfl.pl/929a7af4e87f
You don't need reimplement all of std.algorithm, only parts which
can be in the middle of chain, things like any, all, each, count
can be ignored.
example:
void main()@nogc{
import std.algorithm : any;
import std.range : iota;
import util.algorithm : map, filter;
const int
a = 1,
b = 2,
c = 3;
const x = iota(0, 10)
.map!((x, i) => x*i)(a) ///map!((x) => x*a)
.map!((x, i) => x*i)(b) ///map!((x) => x*b)
.filter!((x, i) => x%i)(c)///filter!((x) => x%c)
.any!(x => x % c);
assert(x == true);
}
More information about the Digitalmars-d-learn
mailing list