How about a Hash template?

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Fri Apr 29 12:58:03 PDT 2011


On 4/29/11 2:44 PM, KennyTM~ wrote:
[snip]

You need to replace the assert and compile with -O -release -inline. My 
results:

find in array: 163
compile-time 1: 10
either: 17
straight comparison: 8
compile-time 2: 11

Code:

import std.datetime, std.algorithm, std.typecons, std.stdio;

auto either(Keys...)(Keys keys)
{
     static struct Result
     {
         bool opIn_r(Key)(Key key)
         {
             foreach (k; keys) {
                 if (k == key) {
                     return true;
                 }
             }
             return false;
         }
         private Keys keys;
     }
     return Result(keys);
}

struct ctEither(keys...) {
     @safe bool opBinaryRight(string op:"in", T)(in T x) const pure 
nothrow {
         foreach (k; keys)
             if (x == k)
                 return true;
         return false;
     }
}

struct ctEither2(keys...) {
     @safe bool opBinaryRight(string op:"in", T)(in T x) const pure 
nothrow {
         switch (x) {
             default:
                 return false;
             foreach (k; keys) {
                 case k:
                     return true;
             }
         }
         return false;
     }
}

int p = 1234567890;

void a() {
     p !in ctEither!(1, 12, 123, 1234, 12345, 123456, 1234567, 12345678, 
123456789)() || assert(0);
}
void b() {
     p !in either(1, 12, 123, 1234, 12345, 123456, 1234567, 12345678, 
123456789) || assert(0);
}
void c() {
     ![1, 12, 123, 1234, 12345, 123456, 1234567, 12345678, 
123456789].canFind(p)  || assert(0);
}
void d() {
     !(p == 1 || p == 12 || p == 123 || p == 1234 || p == 12345 || p == 
123456 || p == 1234567 || p == 12345678 || p == 123456789)  || assert(0);
}
void e() {
     p !in ctEither2!(1, 12, 123, 1234, 12345, 123456, 1234567, 
12345678, 123456789)() || assert(0);
}

void main() {
     writeln("find in array: ", benchmark!c(1_000_000)[0].to!("msecs", 
int) );

     writeln("compile-time 1: ", benchmark!a(1_000_000)[0].to!("msecs", 
int) );
     writeln("either: ", benchmark!b(1_000_000)[0].to!("msecs", int) );
     writeln("straight comparison: ", 
benchmark!d(1_000_000)[0].to!("msecs", int) );
     writeln("compile-time 2: ", benchmark!e(1_000_000)[0].to!("msecs", 
int) );
}


More information about the Digitalmars-d mailing list