DIP 1019--Named Arguments Lite--Community Review Round 1

Rubn where at is.this
Mon Feb 18 13:18:15 UTC 2019


On Monday, 18 February 2019 at 10:17:32 UTC, Atila Neves wrote:
> On Friday, 15 February 2019 at 17:43:52 UTC, 12345swordy wrote:
>> On Friday, 15 February 2019 at 17:38:23 UTC, Francesco Mecca 
>> wrote:
>>> On Friday, 15 February 2019 at 13:49:04 UTC, Atila Neves 
>>> wrote:
>>>> [...]
>>>
>>> I think that the solution proposed by Atila is better for the 
>>> following reasons:
>>> 1. it is a library solution
>>> 2. allows both the user and the author of a library to 
>>> specify functions with named parameters
>>> 3. it is very lightweight
>>>
>>> [...]
>>
>> You miss the other reason on why it is not enough: Compile 
>> time and run-time performance penalty.
>> -Alex
>
> Run-time? I'd expect the call to inlined. It'll definitely take 
> longer to compile though, but I'm at a loss why named 
> parameters in the compiler are expected to be free.

The compiler isn't some magic device, your implementation is not 
easily optimized out to have no runtime cost. Even LDC has 
trouble optimizing it, and forget about DMD.

struct Foo {
     int[1024] value;
}

void foo(ref Foo faa ) {
     import core.stdc.stdio : printf;
     foreach(int i, ref v; faa.value) {
         printf("%d", v);
     }
  }

alias slowFoo = kwargify!foo;

void func() {
     import std.stdio;
     Foo f;

     foreach(int i, ref v; f.value) {
         writeln("%d", v);
     }

     slowFoo( f );

     foreach(int i, ref v; f.value) {
         writeln("%d", v);
     }

}

void example.func():
         push    rbp
         push    r15
         push    r14
         push    rbx
         sub     rsp, 8200
         lea     rdi, [rsp + 4104]
         xor     ebx, ebx
         xor     esi, esi
         mov     edx, 4096
         call    memset at PLT
         lea     r15, [rsp + 8]
         lea     r14, [rip + .L.str.1]
.LBB1_1:
         mov     ebp, dword ptr [rsp + 4*rbx + 4104]
         mov     rdi, r15
         call    @property @trusted std.stdio.File 
std.stdio.trustedStdout()@PLT
         mov     esi, 10
         mov     ecx, 2
         mov     rdi, r15
         mov     edx, ebp
         mov     r8, r14
         call    @safe void 
std.stdio.File.write!(immutable(char)[], int, 
char).write(immutable(char)[], int, char)@PLT
         mov     rdi, r15
         call    @safe void std.stdio.File.__dtor()@PLT
         add     rbx, 1
         cmp     rbx, 1024
         jb      .LBB1_1
         lea     rdi, [rsp + 8]
         lea     rsi, [rsp + 4104]
         mov     edx, 4096
         call    memcpy at PLT          <--------------------
         lea     rbx, [rip + .L.str.1]
         xor     ebp, ebp
.LBB1_4:
         mov     esi, dword ptr [rsp + 4*rbp + 8]
         xor     eax, eax
         mov     rdi, rbx
         call    printf at PLT           <-------------------
         add     rbp, 1
         cmp     rbp, 1024
         jne     .LBB1_4
         xor     ebx, ebx
         lea     r15, [rsp + 8]
         lea     r14, [rip + .L.str.1]

https://godbolt.org/z/6Tu8V7

As you can it is unable to optimize the extra copy that your 
implementation does by having to build a tuple before passing it 
to the function.

No one is arguing that named parameters that are built in will be 
free. But it will be way faster as the compiler knows exactly 
what you are doing, not the hacky workaround you have that is 
severally limited (no templates, distinguished by types not 
"names" only allows you to reorder parameters all but useless for 
default types like int/float). Your implementation is extremely 
slow, both increasing compile times and decreasing runtime 
performance. All for the purpose of simply making code more 
readable. That's not a worthwhile trade off for the performance 
hit in both aspects.





More information about the Digitalmars-d mailing list