Thread overview
pass by reference or value?
Jan 07, 2004
imr1984
Jan 07, 2004
Ilya Minkov
Jan 08, 2004
imr1984
Jan 08, 2004
imr1984
Jan 08, 2004
Andy Friesen
Jan 10, 2004
Georg Wrede
Jan 10, 2004
Ilya Minkov
Jan 10, 2004
Ilya Minkov
January 07, 2004
As structs are value types, should i always pass a struct using one of the reference qualifiers (i hope thats the right name) ? for example:

void myFunc(in MyStruct ms)
{
}

Or should i just let it pass by value?

void myFunc(MyStruct ms)
{
}

I was thinking that with the advent of the 64 bit processors which have 127 general purpose registers, it might just be faster to pass it by value, but i might be wrong. What do you think?


January 07, 2004
If you read the manual,

> void myFunc(in MyStruct ms)

is absolutely the same as

> void myFunc(MyStruct ms)

because where no qualifier is specified, in is implicit.

In only denotes semantics, but not whether the struct would be passed by value or not. Depending on the size of the struct, compiler should be able to choose automatically, whether this is by value, or by constant reference. I'm not sure whether the current one can draw any wisdom of the struct size, but it is just the beginning, right?

> I was thinking that with the advent of the 64 bit processors which have 127
> general purpose registers, it might just be faster to pass it by value, but i
> might be wrong. What do you think?

I think if you are talking of structs up to 8 bytes, it might already faster to pass them by value. With newer architectures, the margin would probably move towards larger numbers, but it is up to compiler to decide, so that code would stay portable and would not loose on performance. Same with alignment.

-eye

January 08, 2004
In article <bthren$2p6n$1@digitaldaemon.com>, Ilya Minkov says...
>
>If you read the manual,
>
>> void myFunc(in MyStruct ms)
>
>is absolutely the same as
>
>> void myFunc(MyStruct ms)
>
>because where no qualifier is specified, in is implicit.
>
>In only denotes semantics, but not whether the struct would be passed by value or not. Depending on the size of the struct, compiler should be able to choose automatically, whether this is by value, or by constant reference. I'm not sure whether the current one can draw any wisdom of the struct size, but it is just the beginning, right?
>
>> I was thinking that with the advent of the 64 bit processors which have 127 general purpose registers, it might just be faster to pass it by value, but i might be wrong. What do you think?
>
>I think if you are talking of structs up to 8 bytes, it might already faster to pass them by value. With newer architectures, the margin would probably move towards larger numbers, but it is up to compiler to decide, so that code would stay portable and would not loose on performance. Same with alignment.
>
>-eye
>

"Depending on the size of the struct, compiler should be
>able to choose automatically, whether this is by value, or by constant reference."

so where is the threshold value for this decision? Where does it say this in the spec? By constant reference, do you mean that if the struct is passed by reference then the function isnt allowed to change it?


January 08, 2004
In article <bthren$2p6n$1@digitaldaemon.com>, Ilya Minkov says...
>
>If you read the manual,
>
>> void myFunc(in MyStruct ms)
>
>is absolutely the same as
>
>> void myFunc(MyStruct ms)
>
>because where no qualifier is specified, in is implicit.
>
>In only denotes semantics, but not whether the struct would be passed by value or not. Depending on the size of the struct, compiler should be able to choose automatically, whether this is by value, or by constant reference. I'm not sure whether the current one can draw any wisdom of the struct size, but it is just the beginning, right?
>
>> I was thinking that with the advent of the 64 bit processors which have 127 general purpose registers, it might just be faster to pass it by value, but i might be wrong. What do you think?
>
>I think if you are talking of structs up to 8 bytes, it might already faster to pass them by value. With newer architectures, the margin would probably move towards larger numbers, but it is up to compiler to decide, so that code would stay portable and would not loose on performance. Same with alignment.
>
>-eye
>

"Depending on the size of the struct, compiler should be
>able to choose automatically, whether this is by value, or by constant reference."

so where is the threshold value for this decision? Where does it say this in the spec? By constant reference, do you mean that if the struct is passed by reference then the function isnt allowed to change it?


January 08, 2004
imr1984 wrote:
> "Depending on the size of the struct, compiler should be 
> 
>>able to choose automatically, whether this is by value, or by constant reference."
> 
> 
> so where is the threshold value for this decision? Where does it say this in the
> spec? By constant reference, do you mean that if the struct is passed by
> reference then the function isnt allowed to change it?

It's the other way around, actually.  The compiler would look at how you use it, and work out how to implement it appropriately.  If you pass a big struct in, and you don't alter it, then the compiler can implement it as passing by const reference.  If you alter it, then it has no choice but to pass by value.  The compiler should always be able to pass by reference if you use out or inout.

In other words, don't think about it.  The compiler knows enough to decide on its own.

 -- andy
January 10, 2004
In article <btjq3f$2nna$1@digitaldaemon.com>, Andy Friesen says...
>It's the other way around, actually.  The compiler would look at how you use it, and work out how to implement it appropriately.  If you pass a big struct in, and you don't alter it, then the compiler can implement it as passing by const reference.  If you alter it, then it has no choice but to pass by value.  The compiler should always be able to pass by reference if you use out or inout.
>
>In other words, don't think about it.  The compiler knows enough to decide on its own.

This sounds as if the out and inout were superfluous. Which, I think, just deepens the original question.


January 10, 2004
imr1984 wrote:

> so where is the threshold value for this decision? Where does it say this in the
> spec? By constant reference, do you mean that if the struct is passed by
> reference then the function isnt allowed to change it?

Threshold need not be explicit. And would definately be optimally chosen for each platform. Besides, i don't know how it is implemented now! The purpose of the current compiler is to implement the specification correctly. Being good comes next.

By constant reference, i mean that the original cannot be modified. To modify it, the compiler would need to automatically generate a local copy within the function to simulate a pass by value. This cannot affect calling convention, since it has to be completely identifiable by a prototype.

However, this only works so with value types, such as primitives and structs. Classes and array slices are different, in the sense that they always have a reference semantics - you can mutate them but you cannot reseat them.

Bottom line is: let design drive your code, and let platform-specific performance considerations to the compiler. Even if you might be unsatisfied by decisions the current one could make, soon this will pay off, with transition to better compilers and then 64-bit systems.

-eye

January 10, 2004
Georg Wrede wrote:

> This sounds as if the out and inout were superfluous.
> Which, I think, just deepens the original question.

They are not superfluous, since they change most importantly the semantics - helping to write correct and self-documenting code - and by the way also applicable optimisations.

-eye