[Issue 22155] New: practical range usage often causes unnecessary closure allocations.

d-bugmail at puremagic.com d-bugmail at puremagic.com
Wed Jul 28 16:06:01 UTC 2021


https://issues.dlang.org/show_bug.cgi?id=22155

          Issue ID: 22155
           Summary: practical range usage often causes unnecessary closure
                    allocations.
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: normal
          Priority: P1
         Component: phobos
          Assignee: nobody at puremagic.com
          Reporter: john.loughran.colvin at gmail.com

void foo(int[] a, int b) @nogc {
        import std.algorithm.iteration : map;
        size_t i = 0;
        foreach (el; a.map!(x => x + b))
            a[i++] = el;
    }

onlineapp.d(1): Error: function `onlineapp.foo` is `@nogc` yet allocates
closures with the GC
onlineapp.d(4):        onlineapp.foo.__lambda4 closes over variable b at
onlineapp.d(1)

or the more common case for us:

    a.map!(x => a + b).array;

which ends up allocating an unnecessary extra closure, even if `a.length` is 0.


It is not clear to me exactly how this could be fixed even conceptually, but it
is worth documenting as a real problem.

I want to use the GC freely, but I also want to be in control. Random closures
that you can't spot easily cause a lot of problems. Using `@nogc` is way too
restrictive for these use cases, e.g. you might be totally fine with GC
allocation *inside* the lambda, you just don't want to do another one to
capture. Every allocation is individually expensive, often dwarfing the rest of
the code in the function.

--


More information about the Digitalmars-d-bugs mailing list