目标是实现与此 C++ 示例相同的效果:避免创建临时对象。我尝试将 C++ 示例翻译成 D,但没有成功。我也尝试过不同的方法。
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.");
}
表达式模板版本比非表达式模板版本慢。我期待表达式模板版本更快并接近预期。那么我的表达式模板有什么问题?在D中做表达式模板的正确方法是什么?