Efficiently passing structs

rsw0x via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon May 4 21:20:15 PDT 2015


On Tuesday, 5 May 2015 at 02:47:03 UTC, bitwise wrote:
> On Mon, 04 May 2015 00:16:03 -0400, Jonathan M Davis via 
> Digitalmars-d-learn <digitalmars-d-learn at puremagic.com> wrote:
>> D will move the argument if it can rather than copying it 
>> (e.g. if a
>> temporary is being passed in), which reduces the need for 
>> worrying about
>> copying like you tend to have to do in C++98, and I think that 
>> a lot of D
>> code just doesn't worry about the cost of copying structs.
>
> How exactly would you move a struct? Just a memcpy without the 
> postblit?
>
>> However, if you have a large object that you know is going to 
>> be
>> expensive to copy, you're either going to have to use const ref
>> (and thus probably duplicate the function to allow rvalues), or
>> you're going to need to make it a reference type rather than
>> having all of its data live on the stack (either by making
>> it so that the struct contains a pointer to its data or by 
>> making it a
>> class).
>> In general, if you're dealing with a type that is going to be
>> expensive to copy, I'd advise making it a reference type over 
>> relying on
>> const ref simply because it's less error-prone that way. It's 
>> trivial to
>> forget to use ref on a parameter, and generic code won't use 
>> it, so it'll
>> generally work better to just make it a reference type.
>>
>> - Jonathan M Davis
>
> Something like a Matrix4x4 lives in an awkward place between a 
> class and a struct. Because of the fact that a graphics engine 
> may have to deal with thousands of them per frame, both copying 
> them at function calls, and allocating/collecting thousands of 
> them per frame, are both unacceptable.
>
> I was reading up(DIP36, pull requests, forum) and it seems like 
> auto ref was supposed to do something like this. Is there a 
> reason you didn't mention it?

it does, auto ref can bind to both lvalues and rvalues. Create 
the function with an empty template like so,

import std.stdio;

struct S{
}

void Foo()(auto ref S s){
}

void main(){
	S s;
	Foo(s);
	Foo(S());
}

There might be other ways that I'm unaware of.

>
> Why not just add "rvref" to D?

D is already bloated.


More information about the Digitalmars-d-learn mailing list