About structs and performant handling
Namespace
rswhite4 at googlemail.com
Sat Mar 9 12:19:09 PST 2013
I would first like to apologize my bad English.
I like to suggest a possible solution for the current rvalue ref
problem (especially for structs).
My suggestion is based on the idea of 'auto ref' and the proposal
of deadalnix which was discussed here:
http://forum.dlang.org/thread/funxviipfkdftmdfyrfk@forum.dlang.org?page=1
Smaller structs are very performant if you move or copy them.
This is more performant as to create them only to pass them by
ref.
But structs with a bigger size aren't that performant if you pass
them as copy or move them (See also my small benchmark:
http://dpaste.1azy.net/edit/b9624e01).
So I like to suggest a new syntax for this behaviour.
If you want that your function/method/whatever takes a struct as
well as rvalue and lvalue, you declare this parameter with a '&'
(Or whatever, the syntax doesn't matter at all. I like the '&'
because I know it from C++ and many (C++) Newcomer will know what
it means. Furthermore '&' is a lot shorter than eg. 'auto ref').
For example:
[code]
struct A { }
void foo(A& a) { }
[/code]
The compiler will check by these kind of parameters if they are
structs and if the size is proven greater as N (maybe 16 - 24)
bit. If not, the '&' will be ignored. The function take in this
cases normally lvalues as copy and moves rvalues.
But if the struct size is greater than N the compiler changes the
storage class of this parameter to ref.
Example:
If you have another struct B with the following structure
(instead of the lightweight struct A):
[code]
struct B {
public:
int[100] ids;
}
[/code]
the method 'foo' will be changed to:
[code]
void foo(ref B b) { }
[/code]
In this case lvalues are taken by ref and in case that a rvalue
is used, a temporary variable is created and passed to the
function (like C++ does). Or if you don't like temporary
variables you could also use a wrapper, something like:
[code]
@property
ref T make(T, Args...)(Args args) {
static if (args.length != 0) {
static T result = void;
T _temp = T(args);
memcpy(&result, &_temp, T.sizeof);
} else {
static T result;
}
return result;
}
[/code]
So the two possible kind of calls to foo would be:
[code]
B b;
foo(b);
[/code]
and
[code]foo(B());[/code]
which is converted to:
[code]foo(make!B);[/code]
I see a lot of potential in this solution, because the compiler
is taking care about gaining the most powerfull/performant code,
it's simple (and simple is always good) AND it could solve the
rvalue ref problem.
And now you can behead me.
More information about the Digitalmars-d
mailing list