www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - memoize & __traits(compiles...)

reply John Chapman <johnch_atms hotmail.com> writes:
I'm doing a fair amount of repeatedly checking if a function 
compiles with __traits(compiles...), executing the function if 
so, erroring out if not, like this:

   static if (__traits(compiles, generateFunc1())) {
     return generateFunc1();
   } static if (__traits(compiles, generateFunc2())) {
     return generateFunc2();
   } else static assert(false);

But it seems inefficient to have to evaluate those functions 
twice, so I'd like to optimise this so if __traits(compiles...) 
succeeds, the result is cached and then used when the function is 
actually called. I wondered if using std.functional.memoize would 
help?
Nov 23 2018
next sibling parent reply Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Friday, 23 November 2018 at 10:34:11 UTC, John Chapman wrote:
 I'm doing a fair amount of repeatedly checking if a function 
 compiles with __traits(compiles...), executing the function if 
 so, erroring out if not, like this:

   static if (__traits(compiles, generateFunc1())) {
     return generateFunc1();
   } static if (__traits(compiles, generateFunc2())) {
     return generateFunc2();
   } else static assert(false);

 But it seems inefficient to have to evaluate those functions 
 twice, so I'd like to optimise this so if __traits(compiles...) 
 succeeds, the result is cached and then used when the function 
 is actually called. I wondered if using std.functional.memoize 
 would help?
No, std.functional.memoize uses a hashtable to cache the runtime results of calls to expensive functions. assuming that the example is not oversimplified and generateFunc1 and generateFunc2 are functions, the compiler doesn't do extra semantic analysis so the validity of the functions is effectively cached. If they are templates (with parameters) then the compiler will automatically memoize them (it too keeps a hashtable of template instances). When in doubt, profile! https://blog.thecybershadow.net/2018/02/07/dmdprof/
Nov 23 2018
parent John Chapman <johnch_atms hotmail.com> writes:
On Friday, 23 November 2018 at 11:29:24 UTC, Nicholas Wilson 
wrote:
 No, std.functional.memoize uses a hashtable to cache the 
 runtime results of calls to expensive functions.

 assuming that the example is not oversimplified and 
 generateFunc1 and generateFunc2 are functions, the compiler 
 doesn't do extra semantic analysis so the validity of the 
 functions is effectively cached.

 If they are templates (with parameters) then the compiler will 
 automatically memoize them (it too keeps a hashtable of 
 template instances).
Ah, that's good to know.
Nov 23 2018
prev sibling parent Daniel Kozak <kozzi11 gmail.com> writes:
__traits(compiles...) does not call your function so it is not evaluate
twice only once, so there is no need to use memoize

On Fri, Nov 23, 2018 at 11:35 AM John Chapman via Digitalmars-d-learn <
digitalmars-d-learn puremagic.com> wrote:

 I'm doing a fair amount of repeatedly checking if a function
 compiles with __traits(compiles...), executing the function if
 so, erroring out if not, like this:

    static if (__traits(compiles, generateFunc1())) {
      return generateFunc1();
    } static if (__traits(compiles, generateFunc2())) {
      return generateFunc2();
    } else static assert(false);

 But it seems inefficient to have to evaluate those functions
 twice, so I'd like to optimise this so if __traits(compiles...)
 succeeds, the result is cached and then used when the function is
 actually called. I wondered if using std.functional.memoize would
 help?
Nov 23 2018