В чем преимущество использования структур для UOM, таких как температура? - PullRequest
0 голосов
/ 29 февраля 2020

Я запустил код ниже, чтобы проверить скорость некоторых распространенных применений в моей программе для UOM, и был весьма удивлен. С результатами: Все тесты были выполнены 1 миллион раз в режиме отладки (режим выполнения дал аналогичные различия). Кажется, что нет реального преимущества в использовании структур для UOM с точки зрения скорости, поэтому кто-нибудь может сказать, какие будут преимущества? (У меня есть программа хруста большого числа, и это представляет для меня огромный интерес). Если приведенный ниже пример кода неверен, пожалуйста, дайте мне знать. Что мне действительно нужно, так это самый удобный способ обработки UOM без создания подробного кода (UOM * UOM, а не UOM.Value * UOM.Value будет лучшим, но, очевидно, не самым эффективным с точки зрения скорости). Время в мс.

Multply удваивается 7

Multply struct fields 8

Multply struct свойство 232

Multply температурная структура с использованием перегруженного оператора * 141

Multply поля класса 7

Умножение и загрузка удваивается в массив объектов 692

Умножение полей структуры и загрузка в массив объектов 719

Умножение полей структуры и загрузка новой структуры в массив объектов 926

Умножение структур с перегруженным оператором загрузки структуры в массив объектов 906

Умножение полей классов и загрузка в массив объектов 697

Умножение полей классов и загрузка нового класса в массив объектов 964

Умножить класс, используя перегруженный оператор * и загрузить класс в массив объектов 948

public class TestSpeed
{
    public class TempClass
    {
        public double value=100;
        private double v;

        public TempClass(double v)
        {
            this.v = v;
        }

        public static TempClass operator *(TempClass t1, TempClass t2)
        {
            return new TempClass(t1.value * t2.value);
        }
    }

    public struct TempStruct
    {
        public double value;

        public TempStruct(double v)
        {
            value = v;
        }

        public double GetTemp
        {
            get { return value; }
            set { this.value = value; }
        }

        public static TempStruct operator *(TempStruct t1, TempStruct t2)
        {
            return new TempStruct(t1.value * t2.value);
        }
    }


    [TestMethod]
    public void TestDouble()
    {
        double doubleValue = 100;
        TempStruct t = new TempStruct();
        TempStruct Tres= new TempStruct(100);
        TempClass tclass = new TempClass(100);
        double res;

        var watch = Stopwatch.StartNew();

        for (int i = 0; i < 10000000; i++)
        {
            res = doubleValue*doubleValue;
        }

        watch.Stop();

        var elapsedMs = watch.ElapsedMilliseconds;
        Debug.WriteLine("Multply doubles "+ elapsedMs.ToString());

        watch = Stopwatch.StartNew();

        for (int i = 0; i < 10000000; i++)
        {
            Tres.value = t.value * t.value;
        }

        watch.Stop();


        elapsedMs = watch.ElapsedMilliseconds;
        Debug.WriteLine("Multply struct fields " + elapsedMs.ToString());

        watch = Stopwatch.StartNew();

        for (int i = 0; i < 10000000; i++)
        {
            Tres.GetTemp = t.GetTemp * t.GetTemp;
        }

        watch.Stop();


        elapsedMs = watch.ElapsedMilliseconds;
        Debug.WriteLine("Multply struct property " + elapsedMs.ToString());


        watch = Stopwatch.StartNew();

        for (int i = 0; i < 10000000; i++)
        {
            Tres = t * t;
        }

        watch.Stop();

        elapsedMs = watch.ElapsedMilliseconds;
        Debug.WriteLine("Multply temperature struct using overloaded * operator " + elapsedMs.ToString());

        watch = Stopwatch.StartNew();

        for (int i = 0; i < 10000000; i++)
        {
            res = tclass.value * tclass.value;
        }

        watch.Stop();
        elapsedMs = watch.ElapsedMilliseconds;
        Debug.WriteLine("Multply class fields " + elapsedMs.ToString());
    }


    [TestMethod]
    public void TestDoubleArray()
    {
        double doublevalue = 100;
        TempStruct t = new TempStruct();
        TempStruct Tres = new TempStruct(100);
        TempClass tclass = new TempClass(100);
        object[] res = new object[10000000];

        var watch = Stopwatch.StartNew();

        for (int i = 0; i < 10000000; i++)
        {
            res[i] = doublevalue * doublevalue;
        }

        watch.Stop();

        var elapsedMs = watch.ElapsedMilliseconds;
        Debug.WriteLine("Multiply & Load doubles into object array " + elapsedMs.ToString());

        watch = Stopwatch.StartNew();

        for (int i = 0; i < 10000000; i++)
        {
            res[i] = t.value * t.value;
        }

        watch.Stop();


        elapsedMs = watch.ElapsedMilliseconds;
        Debug.WriteLine("Multiply struct fields & Load into object array " + elapsedMs.ToString());


        watch = Stopwatch.StartNew();

        for (int i = 0; i < 10000000; i++)
        {
            res[i] = new TempStruct(t.value * t.value);
        }

        watch.Stop();


        elapsedMs = watch.ElapsedMilliseconds;
        Debug.WriteLine("Multiply struct fields & Load new struct into object array " + elapsedMs.ToString());



        watch = Stopwatch.StartNew();

        for (int i = 0; i < 10000000; i++)
        {
            res[i] = t * t;
        }

        watch.Stop();

        elapsedMs = watch.ElapsedMilliseconds;
        Debug.WriteLine("Multiply structs with overloaded operator a load struct into object array " + elapsedMs.ToString());

        watch = Stopwatch.StartNew();

        for (int i = 0; i < 10000000; i++)
        {
            res[i] = tclass.value * tclass.value;
        }

        watch.Stop();
        elapsedMs = watch.ElapsedMilliseconds;
        Debug.WriteLine("Multiply class fields & load into object array " + elapsedMs.ToString());

        watch = Stopwatch.StartNew();

        for (int i = 0; i < 10000000; i++)
        {
            res[i] = new TempClass(tclass.value * tclass.value);
        }

        watch.Stop();
        elapsedMs = watch.ElapsedMilliseconds;
        Debug.WriteLine("Multiply class fields & load new class into object array " + elapsedMs.ToString());

        watch = Stopwatch.StartNew();

        for (int i = 0; i < 10000000; i++)
        {
            res[i] = tclass * tclass;
        }

        watch.Stop();
        elapsedMs = watch.ElapsedMilliseconds;
        Debug.WriteLine("Multiply class using overloaded * operator & load class into object array " + elapsedMs.ToString());
    }
}    

1 Ответ

0 голосов
/ 29 февраля 2020

Разница между структурой и классом заключается в распределении памяти. Используя класс, у вас очень маленькие накладные расходы. Таким образом, вы не сможете заметить снижение производительности.

Тогда смысл использования struct не в использовании ссылки. Следовательно, вам не нужно беспокоиться о том, что значение, измененное в 1 методе, может повлиять на другой метод.

...