Я запустил приведенный ниже код, чтобы проверить скорость некоторых распространенных применений в моей программе для единиц измерения, и был очень удивлен. С результатами: Все тесты были запущены 1 миллион раз в режиме отладки (режим запуска дал аналогичные различия). Кажется, что нет никакого реального преимущества в использовании структур для единиц измерения скорости с точки зрения скорости, поэтому может ли кто-нибудь сказать, какие преимущества могут быть? (У меня есть программа для обработки больших чисел, и это представляет для меня огромный интерес). Если приведенный ниже пример кода неверен, сообщите мне об этом. Что мне действительно нужно, так это наиболее удобный способ обработки единиц измерения, не делая код подробным (лучше всего было бы использовать UOM * UOM, а не UOM.Value * UOM.Value, но, по-видимому, это не самая эффективная скорость). Все время в мс.
Умножить на 7
Умножить поля структуры 8
Умножить свойство структуры 232
Умножение структуры температуры с использованием перегруженного оператора * 141
Умножение полей класса 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());
}
}