On Friday, 21 January 2022 at 21:56:33 UTC, H. S. Teoh wrote:

What's the point of calling .dup here? The only reference to records is going out of scope, so why can't you just return it? The .dup is just creating extra work for nothing.


T

good pickup. thanks ;-)

// ----

module test;
@safe:

import std.stdio : write, writef, writeln, writefln;
import std.range : iota, enumerate;
import std.array : array, byPair, Appender, appender;
import std.random : Random, unpredictableSeed, dice, randomCover;
import std.algorithm : map;
import std.conv : to;
import std.format;
import std.stdio : File;
import std.file : exists;
import std.exception : enforce;

debug { import std; }

Random rnd;
static this() {  rnd = Random(unpredictableSeed); }

void main(string[] args)
{
    int recordsNeeded, valuesPerRecord;
    string fname;

    if(args.length < 4)
    {
        recordsNeeded = 10; // default
        valuesPerRecord= 8; // default

        fname = "D:/rnd_records.txt"; // default
        //fname = "./rnd_records.txt"; // default
    }
    else
    {
        // assumes valid values being passed in ;-)
        recordsNeeded = to!int(args[1]);
        valuesPerRecord = to!int(args[2]);
        fname = args[3];
    }

    debug
{ writefln("%s records, %s values for record, will be written to file: %s", recordsNeeded, valuesPerRecord, fname); }
    else
        {
enforce(!exists(fname), "Oop! That file already exists!"); enforce(recordsNeeded <= 1_000_000_000, "C'mon! That's too many records!");
        }

int[][int][] records = CreateDataSet(recordsNeeded, valuesPerRecord);

    ProcessDataSet(records, fname);

    writefln("All done. Check if records written to %s", fname);
}

int[][int][] CreateDataSet
(const(int) recordsNeeded, const(int) valuesPerRecord)
{
    const int iotaStartNum = 100_000_001;

    int[][int][] records;
    records.reserve(recordsNeeded);
debug { writefln("records.capacity is %s", records.capacity); }

foreach(i, id; iota(iotaStartNum, iotaStartNum + recordsNeeded).enumerate)
    {
        // NOTE: below does register with -profile=gc
records ~= [ id: iota(valuesPerRecord).map!(valuesPerRecord => cast(int)rnd.dice(0.6, 1.4)).array ];
    }

    debug { writefln("records.length = %s", records.length); }
    return records;
}

// this creates a big string of 'formatted' records, and outputs that string to a file.
void ProcessDataSet
(in int[][int][] records, const(string) fname)
{
    auto file = File(fname, "w");
    scope(exit) file.close;

    Appender!string bigString = appender!string;
    bigString.reserve(records.length);
debug { writefln("bigString.capacity is %s", bigString.capacity); }

    // NOTE: forward declaration required for this nested function
    void processRecord(const(int) id, const(int)[] values)
    {
bigString ~= id.to!string ~ "," ~ values.format!"%(%s,%)" ~ "\n";
    }

    foreach(ref const record; records)
    {
        foreach (ref rp; record.byPair)
        {
            processRecord(rp.expand);
        }
    }

debug { writeln; writeln(bigString[].until("\n")); writeln; } // display just one record

    file.write(bigString[]);
}
// ----


Reply via email to