以前曾经讨论过使用typedef来完成强类型的数值计算,最终遇到的问题是D里面没办法定义进行全局运算符重载。
最近在struct上找到点灵感,把基本类型用struct包装后使用,就可以重载运算符了,当然效率也是有保证的,D前几个版本已经完成了NRVO,struct也可以在栈上分配,所以不用担心性能,不过编译时注意打开-O选项。
简单测试了一下,性能与基本类型基本上没有差别:
最近在struct上找到点灵感,把基本类型用struct包装后使用,就可以重载运算符了,当然效率也是有保证的,D前几个版本已经完成了NRVO,struct也可以在栈上分配,所以不用担心性能,不过编译时注意打开-O选项。
简单测试了一下,性能与基本类型基本上没有差别:
template WrapStruct(T)
{
T value;
T opCast()
{
return value;
}
typeof(*this) opAssign(T)(T v)
{
value = v;
return *this;
}
static typeof(*this) opCall(T)(T v)
{
typeof(*this) result;
result.value = v;
return result;
}
}
struct Length
{
mixin WrapStruct!(float);
Time opDiv(Speed speed)
{
return Time(value / speed.value);
}
Speed opDiv(Time time)
{
return Speed(value / time.value);
}
char[] toString()
{
return std.string.format("%f m", value);
}
}
struct Speed
{
mixin WrapStruct!(float);
Length opMul(Time time)
{
return Length(value * time.value);
}
char[] toString()
{
return std.string.format("%f m/s", value);
}
}
struct Time
{
mixin WrapStruct!(float);
Length opMul(Speed speed)
{
return Length(value * speed.value);
}
char[] toString()
{
return std.string.format("%f s", value);
}
}
import std.stdio;
import std.date;
void main()
{
{
Length length = 30;
Speed speed = 3;
Time time = length / speed;
assert(cast(float)time == 10);
time = 5;
speed = length / time;
assert(cast(float)speed == 6);
}
{
long start = getUTCtime();
float length = 3;
float speed = 1.5;
float time;
for (int i=0; i<100000000; ++i)
{
time = length / speed;
}
writefln(getUTCtime() - start);
}
{
long start = getUTCtime();
Length length = 3;
Speed speed = 1.5;
Time time;
for (int i=0; i<100000000; ++i)
{
time = length / speed;
}
writefln(getUTCtime() - start);
}
}