Virtual value types during compile-time for static type safety, static optimizations and function overloading.

Baz via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Jul 17 17:07:54 PDT 2015


On Friday, 17 July 2015 at 21:20:41 UTC, Tamas wrote:
> Although this code is fully operational, presents nice api and 
> compile-time optimizations, the extra Struct wrapper is not 
> without runtime penalty.
>
> Is there a solution that results the same static optimizations, 
> but has no runtime penalty, i.e. the functions just operates 
> with ints? (At least when compiled)
>
> Thanks, Tamas

Hi, I don't see the runtime penalities you talk about.

I've defined these alias:

---
alias abs1 = abs!int;
alias abs2 = abs!Positive;
alias isqrt1 = isqrt!int;
alias isqrt2 = isqrt!Positive;
---

and the asm produced for the `Positive` type is clearly faster:

;------- abs1 -------
00402074h  enter 000Ch, 00h
00402078h  test eax, eax
0040207Ah  js 00402081h
0040207Ch  mov dword ptr [ebp-0Ch], eax
0040207Fh  leave
00402080h  ret
00402081h  neg eax
00402083h  mov dword ptr [ebp-08h], eax
00402086h  leave
00402087h  ret
;----------------------------

;------- abs2 (Positive)-------
00402088h  enter 0004h, 00h
0040208Ch  leave
0040208Dh  ret
;----------------------------

;------- isqrt1 -------
00402090h  enter 0008h, 00h
00402094h  test eax, eax
00402096h  jns 004020CFh
00402098h  mov ecx, 00454D60h
0040209Dh  push ecx
0040209Eh  call 00403410h
004020A3h  add esp, 04h
004020A6h  push dword ptr [004540A4h]
004020ACh  push dword ptr [004540A0h]
004020B2h  push dword ptr [004540E4h]
004020B8h  push dword ptr [004540E0h]
004020BEh  push 0000001Bh
004020C0h  push 00000000h
004020C2h  call 004035C0h
004020C7h  push eax
004020C8h  call 00403400h
004020CDh  jmp 004020E6h
004020CFh  call 0040247Ch
004020D4h  fsqrt
004020D6h  sub esp, 04h
004020D9h  fstp dword ptr [esp]
004020DCh  call 00402494h
004020E1h  mov dword ptr [ebp-08h], eax
004020E4h  leave
004020E5h  ret
004020E6h  leave
004020E7h  ret
;----------------------------

;------- isqrt2 (Positive)-------
004020E8h  enter 0008h, 00h
004020ECh  call 00402560h
004020F1h  fsqrt
004020F3h  sub esp, 04h
004020F6h  fstp dword ptr [esp]
004020F9h  call 00402494h
004020FEh  mov dword ptr [ebp-08h], eax
00402101h  leave
00402102h  ret
;----------------------------

(dmd win32 bit, -w -wi).

Also note that i've tweaked the code to get rid of a few warnings:
---
Positive abs(T)(T n) {
     static if (is(T == Positive)) {
         return n;
     }
     else
     {
         if (n >= 0) return Positive(n);
         else return Positive(-n);
     }
}

Positive isqrt(T)(T x) {
     static if (is(T == Positive)) {
         return Positive(sqrt(x.to!float).to!int);
     }
     else
     {
         if (x<0)
             throw new Exception("no root for negative numbers");
         else return Positive(sqrt(x.to!float).to!int);
     }

}
---


More information about the Digitalmars-d-learn mailing list