Make SetLength(100 Mb) instant on Windows.

Add an optional constant SysOSAllocZeroesStartingFrom that can be defined by platform’s sysheap.inc to promise that SysOSAlloc requests of at least this size come zeroed, and use this information in AllocMem to make huge SetLengths (relatively) instant. FastMM / that mORMot thing do the same. For platforms other than Windows, the constant can often be 0 (e.g. when using Unix’s mmap(MAP_ANONYMOUS)), but do it yourselves.

Try this:

{$mode objfpc} {$longstrings on} {$typedaddress on} {$coperators on} {$modeswitch anonymousfunctions}
uses
	SysUtils;

	procedure Benchmark(const name: string; proc: TProcedure);
	var
		start, time: double;
		reps, iUnit: uint32;
	begin
		reps := 0; start := Now;
		repeat
			inc(reps);
			proc;
			time := (Now - start) * SecsPerDay;
		until not (time < 0.5);
		time := time / reps;
		iUnit := 0;
		while (iUnit < 3) and (time < 0.9) do begin iUnit += 1; time *= 1e3; end;
		writeln((name + ': ').PadRight(25), time:0:ord(time < 10), ' ', 's/ms/us/ns'.Split('/')[iUnit], '/call');
	end;

begin
	Benchmark('SetLength(100 Mb)',
		procedure
		var
			a: array of byte;
		begin
			SetLength((@a)^, 100 * 1024 * 1024);
		end);
end.

My effect: 20 ms/call12 µs/call.

Merge request reports

Loading