1

コードフラグメントの比較A:

struct Vector2(T) {
    // ...

    auto opCast(U)() {
        return U(x, y);
    }

    void opOpAssign(string op)(Vector2 vector) {
        mixin ("x" ~ op ~ "= vector.x;");
        mixin ("y" ~ op ~ "= vector.y;");
    }
}

void main() {
    auto fVec = Vector2!float(1.5, 1.5);
    auto dVec = Vector2!double(1.5, 1.5);

    // Benchmark: Loop following 10 million times.
    fVec += cast(Vector2!float)  dVec;
    dVec -= cast(Vector2!double) fVec;
}

Bと:

struct Vector2(T) {
    // ...

    void opOpAssign(string op, U)(Vector2!U vector) {
        mixin ("x" ~ op ~ "= vector.x;");
        mixin ("y" ~ op ~ "= vector.y;");
    }
}

void main() {
    auto fVec = Vector2!float(1.5, 1.5);
    auto dVec = Vector2!double(1.5, 1.5);

    // Benchmark: Same as A.
    fVec += dVec;
    dVec -= fVec;
}

私のベンチマーク(DMD、Win7)では、AはBよりも約50ms高速です。これが理由は何ですか?Aの方が速い場合はそれを使用したいのですが、何を試しても、Vector2!doubleを暗黙的にVector2!floatにキャストすることはできません。これらのタイプを暗黙的にキャストする方法について何かアイデアはありますか?それとも、暗黙のうちにキャストしてはいけない理由についての議論はありますか?

これらのコンパイラでこのベンチマークを実行するようにGDCとLDCを設定していますが、これがDMDのみの最適化の問題であるかどうかを誰かが知っていますか?

4

2 に答える 2

3

コンパイラに関する限り、同じテンプレートの 2 つの異なるインスタンス化には、2 つの完全に別個の型以外の共通点はありません。あなたは宣言することができます

struct VectorFloat
{
    ...
}

struct VectorDouble
{
    ...
}

をテンプレートVector2化する代わりに、違いはありません。Vector2!floatVector!double全く違うタイプです。そして、あなたが宣言するどんなタイプでも、それらの間で変換する方法が欲しいなら、あなたはそれらを宣言しなければならないでしょう - それらopCastは 、alias this、コンストラクター、または何でも。暗黙的な変換を機能させる唯一の方法は を使用することだと思いますがalias thisラチェット フリークが指摘するように、float と double の間の暗黙的な変換はD の通常の動作ではなく、間違いなく悪い考えです。

A が B より速い理由はわかりません。私は実際にはそれが逆であることを期待していたでしょう。ただし、コンパイラが正確に何をしているかによっては、後で変更される可能性があり、コンパイラごとに簡単に異なる可能性があります。そして、 1,000 万回の反復で 50ミリ秒の違いしか見られないので、API の観点からより理にかなっているバージョンを使用します (どちらであると考えても)。ただし、float と double の間で暗黙的に変換するのは良い考えだとは思わないという理由だけで、最初のものを使用することを主張しますが、それはあなたのコードであるため、それはあなた次第です。

ちなみに、必要に応じて、opCast直接呼び出す代わりに std.conv.to を使用できます。opCastキャストは非常に鈍い手段であるため、コンパイラーはとにかくそれを行う可能性が高いのに対し、 の定義を台無しにすると大声で叫ぶので、そのようにするとエラーが発生しにくくなります。

于 2012-01-10T00:00:24.780 に答える
1

精度が失われるためからに暗黙的に変換できないのと同じように、単精度 ing ポイントに暗黙的にキャストdoubleしないでください。floatlongint

ほとんどの言語では、変換時に精度を失いたい場合は明確にする必要があります。独自の規則を強制するのではなく、言語の既存の規則に従うのが最善です。

于 2012-01-09T22:59:35.297 に答える