Fastest Way to Append Multiple Elements to an Array

Tobias Pankrath via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Wed Dec 17 04:30:36 PST 2014


On Wednesday, 17 December 2014 at 11:15:30 UTC, zeljkog wrote:
> On 15.12.14 01:00, "Nordlöw" wrote:
>> Isn't this algorithm already encoded somewhere in Phobos?
>
> void append(T, Args...)(ref T[] arr, auto ref Args args){
> {
>    static if (args.length == 1)
>       arr ~= args[0];     // inlined
>    else{
>       arr.length += args.length;
>       foreach(i, e; args)
>          arr[$ - args.length + i] = e;
>    }
> }
>
> I've just tested, this looks usable.
> Equal for 1 item, considerably (~40%) faster for 2, and much 
> (100+%) faster for more.
> Also more convenient.
>
> Maybe samthing like that should go to Fobos.

I don't think you can beat appender. And your function does not 
accept ranges, only elements. I would write it like this:

---
void append(T, Args...)(ref T[] data, Args args)
{
	static size_t estimateLength(Args args)
	{
		size_t result;
		foreach(e; args)
			static if(hasLength!(typeof(e)))
				result += e.length;
			else
				result += 1;

		return result;
	}

	auto app = appender!(T[])(data);
	app.reserve(data.length + estimateLength(args));

	foreach(e; args)
		app.put(e);
	data = app.data;
}

void main()
{
	import std.stdio;
	int[] data;
	append(data, 1, 2, only(1, 2, 3), iota(4, 9));
	writeln(data);
}

---

Maybe appender.put should get an overload that does the same, 
though I didn't had the need for it yet.


More information about the Digitalmars-d-learn mailing list