> Запускать в Release-режиме без подключенного отладчика! Результаты от C++(нативной реализации) практически не отличаются.
Первоначально я вытащил Windows-версию, а потом самостоятельно переписал в кроссплатформенную версию, чтобы код можно было запускать в комплиляторе на mac os. Переписать пришлось потому что в windows-версии есть зависимости, которые несовместимы с другими ОС. И теперь кроссплатформенный код можно запускать на любом ОС, где поддерживается .Net
### Кроссплатформенная версия
```csharp
using System.Diagnostics;
class Program
{
static void Main(string[] args)
{
long start, end;
long milliseconds = 6000; // по умолчанию тест запускается на 6 секунд
int randomBufferSize = 20000;
// наполняем буфер 32-битных чисел с плавающей запятой(float) для участия в тесте
List<float> mem1 = new List<float>();
Random rnd1 = new Random(777);
for (int n = 0; n < randomBufferSize; n++)
{
float a = rnd1.Next(int.MaxValue) * 1000.0f;
float b = rnd1.Next(int.MaxValue) + a;
float c = rnd1.Next(int.MaxValue) / 10000.0f + b;
mem1.Add(c == 0.0f ? 1.0f : c);
}
// наполняем буфер 64-битных чисел с плавающей запятой(double) для участия в тесте
List<double> mem2 = new List<double>();
Random rnd2 = new Random(777);
for (int n = 0; n < randomBufferSize; n++)
{
double a = rnd2.Next(int.MaxValue) * 1000.0d;
double b = rnd2.Next(int.MaxValue) + a;
double c = rnd2.Next(int.MaxValue) / 10000.0d + b;
mem2.Add(c == 0.0f ? 1.0f : c);
}
long v4 = 0;
float v11, r1 = 0;
double v10, r2 = 0;
int v5 = 300;
int v6 = 0;
int v7, v8, v9;
// Запускаем таймер для подсчета числа тиков
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
while (true)
{
v7 = v6;
v8 = v6 + 1;
v9 = v8;
v6 = v8 + 1;
if (v6 >= 20000)
{
v6 = 0;
}
v10 = mem2[v9];
v11 = mem1[v9];
// 20 операций float
r1 = (((((((((((((((((((v11 + mem1[v7]) - v11) * v11) + v11) - v11) * v11) + v11) - v11) * v11) / v11) + v11) - v11) * v11) + v11) - v11) * v11) + v11) - v11) * v11) / v11;
// 20 операций double
r2 = ((((((v10 + mem2[v7] - v10) * v10 + v10 - v10) * v10 + v10 - v10) * v10 / v10 + v10 - v10) * v10 + v10 - v10) * v10 + v10 - v10) * v10 / v10;
if (--v5 == 0)
{
// если указанное в параметре число тиков исчерпано
if (stopwatch.ElapsedMilliseconds >= milliseconds)
{
break;
}
v5 = 300;
}
// число операций (по 20 на каждый тип)
v4 += 40;
}
stopwatch.Stop();
double result = (v4 / stopwatch.ElapsedMilliseconds) / 1000.0;
// выводим числа r1 и r2 чтобы компилятор не срезал полезные вычисления в ходе оптимизации
Console.WriteLine("Result/ops: " + result + " / " + v4 + ", " + r1 + ", " + r2);
Console.ReadKey();
}
}
```