On 2012-12-27 13:52, bearophile wrote:
There is also assumeSafeAppend, for your experiments :-)

This is it! Makes appends in-place. The following code uses only 40 MB of RAM (or 75 MB without prior call to reserve):

    import std.stdio;
    class C { string x; }
    void main(string[] args) {
        char[] s;
        s.reserve(40_000_000);
        for (int i=0, j=0; i < 500_000_000; i++) {
            if (i % 10_000_000 == 0) {
                writeln("loop ", ++j); stdout.flush();
                s.length = 0;
                s.assumeSafeAppend();
            }
            s ~= "....";
        }
    }

But I also had to write s.length = 0 instead of either s = [] or s = "".dup.
I wonder why GC didn't reclaim the regions previously used by the array before it an empty one was assigned to s. GC has started freeing those regions only after the 21'st loop when used up RAM has gone up to 780 MB. I have 8 GB of RAM, 4 GB free but I doubt 780 MB is the right moment to start clearing space. :)

Oddly enough I can keep it at 40 MB (or 75 MB when not reserving space) without assumeSafeAppend(), when using manual delete:

    import std.stdio;
    class C { string x; }
    void main(string[] args) {
        char[] s;
        s.reserve(40_000_000);
        for (int i=0, j=0; i < 500_000_000; i++) {
            if (i % 10_000_000 == 0) {
                writeln("loop ", ++j); stdout.flush();
                delete s;
                s = [];
                s.reserve(40_000_000);
            }
            s ~= "....";
        }
    }

Now, this delete looks like Python's kind of GC cheating. :)
Personally, I don't have anything against it, but is it a valid practice?


Reply via email to