2

MiscUtilsを使用していくつかの一般的な数学クラスを実装しようとしています。MiscUtilsを使用せず、単に型をラップするサンプルコードには、いくつかの主要なパフォーマンスの問題があります。

組み込みの値型で数学を使用すると、少なくとも15倍高速になります。構造体で値型をラップするだけでは、約2倍遅くなります。動的を使用して演算子タイプの制約をバイパスすると、約30倍遅くなります!!!!

私の目標は、次のような単純なクラスを作成することです。

class Vector<T> { ... }

また、Vectorなどを使用して、パフォーマンスに大きな影響を与えることなくTのリストを追加できます(Tはプリミティブ型になります)。

結果:

デバッグを伴うデバッグモード:

    V  = 1.0x    (Direct ValueType addition)
    WE = 6.4x    (Wrapped ValueType empty addition)
    WA = 17.9x   (Wrapped ValueType MiscUtils addition)
    D  = 17.8x   (Dynamic ValueType addition)
    DE = 37.1x   (Dynamid Wrapped Valuetype empty addition)
    DA = 37.7x   (Dynamid Wrapped Valuetype MiscUtils addition)

デバッグなしのリリースモード:

V  - 0.36s
WE - 0.27s
WA - 1.25s
D  - 1.34s
DE - 7.74s
DA - 7.22s
    V  = 1.3x
    WE = 1.0x
    WA = 4.5x
    D  = 4.9x
    DE = 28.2x
    DA = 26.3x

V  - 0.18s
WE - 0.14s
WA - 0.62s
D  - 0.66s
DE - 3.01s
DA - 3.65s
    V  = 1.3x
    WE = 1.0x
    WA = 4.5x
    D  = 4.8x
    DE = 21.9x
    DA = 26.6x

V  - 0.12s
WE - 0.09s
WA - 0.41s
D  - 0.44s
DE - 2.17s
DA - 2.42s
    V  = 1.3x
    WE = 1.0x
    WA = 4.4x
    D  = 4.8x
    DE = 23.7x
    DA = 26.5x

とにかく、ご覧のとおり、MiscUtilsは予想よりもはるかに遅く(サイトは数パーセントと言っています)、動的はひどいです。

何が起こっているのか、または結果を改善する方法について何かアイデアはありますか?

#define __MiscUtils
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
#if __MiscUtils
using MiscUtil;
#endif

namespace GenericNumerics
{

    struct num1<T> where T : struct
    {
        public readonly T a;
        public num1(T v) { a = v; }
        public static num1<T> operator +(num1<T> c1, num1<T> c2) { return new num1<T>(); }
        public static implicit operator num1<T>(T d) { return new num1<T>(); }
    }
    #if __MiscUtils
    struct num2<T> where T : struct
    {
        public readonly T a;
        public num2(T v) { a = v; }
        public static num2<T> operator +(num2<T> c1, num2<T> c2) { return Operator.Add(c1.a, c2.a); }
        public static implicit operator num2<T>(T d) { return new num2<T>(); }
    }
    #endif


    class Program
    {
        public static Stopwatch Stopwatch = new Stopwatch();



        static void Main(string[] args)
        {
            var cntV = 0L; var cntWE = 0L; var cntWA = 0L; var cntD = 0L; var cntDE = 0L; var cntDA = 0L;
            double time = 2000;         

            for (int k = 0; k < 1; k++)
            {

                {
                    Console.Write("V  - ");
                    var x = 1D; var y = 0D; var z = 0D;
                    Stopwatch.Restart();
                    while(Stopwatch.ElapsedMilliseconds < time)
                    {
                        x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; z = x + z; x = x + z; x = y + z; y = y + z; z = x + z;
                        x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; z = x + z; x = x + z; x = y + z; y = y + z; z = x + z;
                        cntV++;
                    }
                    Console.WriteLine(String.Format("{0:0.00}s", time/cntV*1000));
                }

                {
                    Console.Write("WE - ");
                    num1<double> x = 1D; num1<double> y = 0D; num1<double> z = 0D;
                    Stopwatch.Restart();                    
                    while (Stopwatch.ElapsedMilliseconds < time)
                    {
                        x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; z = x + z; x = x + z; x = y + z; y = y + z; z = x + z;
                        x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; z = x + z; x = x + z; x = y + z; y = y + z; z = x + z;
                        cntWE++;
                    }
                    Console.WriteLine(String.Format("{0:0.00}s", time / cntWE * 1000));
                }

                #if __MiscUtils
                {
                    Console.Write("WA - ");
                    num2<double> x = 1D; num2<double> y = 0D; num2<double> z = 0D;
                    Stopwatch.Restart();
                    while (Stopwatch.ElapsedMilliseconds < time)
                    {
                        x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; z = x + z; x = x + z; x = y + z; y = y + z; z = x + z;
                        x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; z = x + z; x = x + z; x = y + z; y = y + z; z = x + z;
                        cntWA++;
                    }
                    Console.WriteLine(String.Format("{0:0.00}s", time / cntWA * 1000));
                }
                #endif

                {
                    Console.Write("D  - ");
                    dynamic x = 1D; dynamic y = 0D; dynamic z = 0D;
                    Stopwatch.Restart();
                    while (Stopwatch.ElapsedMilliseconds < time)
                    {
                        x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; z = x + z; x = x + z; x = y + z; y = y + z; z = x + z;
                        x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; z = x + z; x = x + z; x = y + z; y = y + z; z = x + z;
                        cntD++;
                    }
                    Console.WriteLine(String.Format("{0:0.00}s", time / cntD * 1000));
                }

                #if __MiscUtils
                {
                    Console.Write("DE - ");
                    dynamic x = new num2<double>(0); dynamic y = new num2<double>(0); dynamic z = new num2<double>(0);
                    Stopwatch.Restart();
                    while (Stopwatch.ElapsedMilliseconds < time)
                    {
                        x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; z = x + z; x = x + z; x = y + z; y = y + z; z = x + z;
                        x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; z = x + z; x = x + z; x = y + z; y = y + z; z = x + z;
                        cntDE++;
                    }
                    Console.WriteLine(String.Format("{0:0.00}s", time / cntDE * 1000));
                }

                {
                    Console.Write("DA - ");
                    dynamic x = new num2<double>(0); dynamic y = new num2<double>(0); dynamic z = new num2<double>(0);
                    Stopwatch.Restart();
                    while (Stopwatch.ElapsedMilliseconds < time)
                    {
                        x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; z = x + z; x = x + z; x = y + z; y = y + z; z = x + z;
                        x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; y = y + z; z = x + z; x = x + z; x = y + z; z = x + z; x = x + z; x = y + z; y = y + z; z = x + z;
                        cntDA++;
                    }
                    Console.WriteLine(String.Format("{0:0.00}s", time / cntDA * 1000));
                }
                #endif

                var m = (double)Math.Max(cntV, Math.Max(cntWE, Math.Max(cntWA, Math.Max(cntD, Math.Max(cntDE, cntDA)))));
                Console.WriteLine(string.Format("\tV  = {0:0.0}x\n\tWE = {1:0.0}x\n\tWA = {2:0.0}x\n\tD  = {3:0.0}x\n\tDE = {4:0.0}x\n\tDA = {5:0.0}x\n", m / cntV, m / cntWE, m / cntWA, m / cntD, m / cntDE, m / cntDA));
            }

            Console.ReadKey();
            return;
        }
    }
}
4

0 に答える 0