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[]);
}
// ----