Thread overview | ||||||
---|---|---|---|---|---|---|
|
October 23, 2012 Structs, Speed and refs. | ||||
---|---|---|---|---|
| ||||
Hey everybody! A bit of background; I'm porting some code over from D1 to D2 and I ran into a bit of a problem. I have a bunch of code that looks something like this: class Bar : Other { override void func(ref LargeStruct st) {} } Bar bar; LargeStruct foo, too; bar.func(foo - too); This compiles just fine in D1 but no longer in D2. Because the temp created by "foo - too" is not a lvalue apparently. I don't want to remove the "ref" storage type because i still want it to be fast. And I rather have neater looking code vs: LargeStruct foo, too, temp; temp = foo - too; bar.func(temp); One solution is to turn "in" structs into pass by reference, eg const ref, but not require lvalue semantics at the call site? Cheers, Jakob. |
October 23, 2012 Re: Structs, Speed and refs. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jakob Bornecrantz | Hi,
First of all, I think there is no difference in speed between
LargeStruct foo, too, temp;
temp = foo - too;
bar.func(temp);
and with func without ref.
How looks your opBinary(Right) method?
For eg. this works for me:
struct LargeStruct {
int x;
auto ref opBinary(string op)(LargeStruct rhs) if (op == "-") {
this.x = this.x - rhs.x;
return this;
}
}
class Bar {
void func(ref LargeStruct st) {}
}
void main(string[] args)
{
Bar bar = new Bar();
LargeStruct foo, too;
bar.func(foo - too);
}
However this will modify foo struct.
On Tuesday, 23 October 2012 at 09:44:06 UTC, Jakob Bornecrantz wrote:
> Hey everybody!
>
> A bit of background; I'm porting some code over from D1 to D2 and I ran into a bit of a problem. I have a bunch of code that looks something like this:
>
> class Bar : Other {
> override void func(ref LargeStruct st) {}
> }
>
> Bar bar;
> LargeStruct foo, too;
> bar.func(foo - too);
>
> This compiles just fine in D1 but no longer in D2. Because the temp created by "foo - too" is not a lvalue apparently. I don't want to remove the "ref" storage type because i still want it to be fast. And I rather have neater looking code vs:
>
> LargeStruct foo, too, temp;
> temp = foo - too;
> bar.func(temp);
>
> One solution is to turn "in" structs into pass by reference, eg const ref, but not require lvalue semantics at the call site?
>
> Cheers, Jakob.
|
October 23, 2012 Re: Structs, Speed and refs. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Kozák | On Tuesday, 23 October 2012 at 10:36:11 UTC, Daniel Kozák wrote: > Hi, > > First of all, I think there is no difference in speed between > > LargeStruct foo, too, temp; > temp = foo - too; > bar.func(temp); > > and with func without ref. That doesn't seem to be the case, as at least DMD always copies to the stack. Even if I change the function to have the struct as a unused local variable it still copies. void example(LargeStruct t, Bar bar) { bar.func(t); } with ref: Dump of assembler code for function _D7example4testFS7example11LargeStructC7example3BarZv: 0x0000000000425ee0 <+0>: push %rbp 0x0000000000425ee1 <+1>: mov %rsp,%rbp 0x0000000000425ee4 <+4>: sub $0x10,%rsp 0x0000000000425ee8 <+8>: lea 0x10(%rbp),%rsi 0x0000000000425eec <+12>: mov (%rdi),%rax 0x0000000000425eef <+15>: rex.W callq *0x30(%rax) 0x0000000000425ef3 <+19>: mov %rbp,%rsp 0x0000000000425ef6 <+22>: pop %rbp 0x0000000000425ef7 <+23>: retq without ref: Dump of assembler code for function _D7example4testFS7example11LargeStructC7example3BarZv: 0x0000000000425ee0 <+0>: push %rbp 0x0000000000425ee1 <+1>: mov %rsp,%rbp 0x0000000000425ee4 <+4>: sub $0x10,%rsp 0x0000000000425ee8 <+8>: lea 0x208(%rbp),%rsi 0x0000000000425eef <+15>: mov $0x40,%ecx 0x0000000000425ef4 <+20>: pushq (%rsi) 0x0000000000425ef6 <+22>: sub $0x8,%rsi 0x0000000000425efa <+26>: loop 0x425ef4 <_D7example4testFS7example11LargeStructC7example3BarZv+20> 0x0000000000425efc <+28>: mov (%rdi),%rax 0x0000000000425eff <+31>: rex.W callq *0x30(%rax) 0x0000000000425f03 <+35>: add $0x200,%rsp 0x0000000000425f0a <+42>: mov %rbp,%rsp 0x0000000000425f0d <+45>: pop %rbp 0x0000000000425f0e <+46>: retq > > How looks your opBinary(Right) method? > > For eg. this works for me: > > struct LargeStruct { > int x; > > auto ref opBinary(string op)(LargeStruct rhs) if (op == "-") { > this.x = this.x - rhs.x; > return this; > } > } > > class Bar { > void func(ref LargeStruct st) {} > } > > > void main(string[] args) > { > Bar bar = new Bar(); > LargeStruct foo, too; > bar.func(foo - too); > } > > However this will modify foo struct. Since this is D1 code being ported I'm currently using opSub. I tried changing your code to opSub and I got the same error as with mine. Your example should probably be an error. I'm not saying I was right in doing what I did. The point of the post was to improve D. Cheers, Jakob. |
October 23, 2012 Re: Structs, Speed and refs. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jakob Bornecrantz | On Tuesday, 23 October 2012 at 09:44:06 UTC, Jakob Bornecrantz wrote: > One solution is to turn "in" structs into pass by reference, eg const ref, but not require lvalue semantics at the call site? And here we go again - missing rvalue-to-const-ref propagation. Check out http://forum.dlang.org/thread/yhnbcocwxnbutylfeoxi@forum.dlang.org |
Copyright © 1999-2021 by the D Language Foundation