Expression Patterns in D

The goal is to achieve the same effect as in this C ++ example : avoid creating time series. I tried translating the C ++ example to D without success. I also tried different approaches.

import std.datetime : benchmark;
import std.stdio    : writefln, writeln;

void bench(alias fun, string time = "msecs")(string msg, uint n = 1_000_000) {
  auto b = benchmark!fun(n);
  writefln(" %s: %s ms", msg, b[0].to!(time, int));
}

alias double Real;

struct Expression(string op, E1, E2) {
  E1 _v1;
  E2 _v2;
  alias _v1 v1;
  alias _v2 v2;

  auto opIndex(size_t i) {
    return mixin("v1[i]" ~ op ~ "v2[i]");
  }

  auto opBinary(string op, E)(auto ref E e) {
    return Expression!(op, typeof(this), E)(this, e);
  }
}

struct ExpVector {

  Real[40] _data = void;
  alias _data this;

  this(Real datum) pure nothrow { _data = datum; }

  auto opBinary(string op, T)(auto ref T other) {
    return Expression!(op, typeof(this), T)(this, other);
  }

  void opAssign(E)(auto ref E exp) {
    foreach(i, ref datum; _data)
      datum = exp[i];
  }
}

struct Vector {

  Real[40] _data = void;
  alias _data this;

  this(Real datum) pure nothrow { _data = datum; }

  auto opBinary(string op)(auto ref Vector other) {
    Vector ret;
    foreach(i, datum; _data)
      ret[i] = mixin("datum" ~ op ~ "other[i]");
    return ret;
  }
}

void main() {

  ExpVector e1 = ExpVector(1.5);
  ExpVector e2 = ExpVector(7.3);
  ExpVector ef;
  void T1() {
    ef = (e1 + e2) * (e1 + e2);
  }
  bench!T1(" vector operations using template expression");

  Vector v1 = Vector(1.5);
  Vector v2 = Vector(7.3);
  Vector vf;
  void T2() {
    vf = (v1 + v2) * (v1 + v2);
  }
  bench!T2(" regular vector operations");

  void T3() {
    for(int i = 0; i < vf.length; ++i)
      vf[i] = (v1[i] + v2[i]) * (v1[i] + v2[i]);
  }
  bench!T3(" what is expected if template expressions worked and temporaries were not created.");
}

The version of the expression template is slower than the version of the expressionless template. I expected that the version of the expression template would be much faster and close to the expected one. So what is wrong with my expression patterns? What is the correct way to create an expression template in D?

+5
source share
1 answer

In wikipedia C ++, examples of expression classes contain references to temporary, and in the case of an expression ...


Vec a, b;
double c;
Vec result = ( a - b ) * c
... right before the assignment to the result vector, we have some kind of tree in memory:
a           b
 \        /
  \      /
   \    /
 VecDifference
      \
       \
        \
       VecScaled( has copy of 'c' embedded directly in object )
VecDifference a b, VecScaled VecDifference (, ++, ). ( , , Vec)
Expression ( op, E1, E2) ,

Expression!( "*", Expression!( "-", Vec, Vec ), double )
( "-", Vec, Vec), a b. , Vec, 4 a b ( ). , , D. , ?
(BTW, ++ 11 , : http://lanzkron.wordpress.com/2011/02/21/inferring-too-much/)
+2

All Articles