Изменить : Я решил свою проблему. Причиной была ошибка в процедуре тестирования, и она будет подробно описана, когда мне будет позволено ответить на мой собственный вопрос.
Я знаю, что таких вопросов обычно следует избегать, но я столкнулся с очень странной ситуацией, в которой не могу разобраться. Я пытался реализовать PRNG и тестировал его производительность в сравнении с System.Random. Я обнаружил, что мой код был примерно в 50 раз медленнее, но проблема была не в алгоритме, а просто в вызове метода. Даже если бы я просто вернул константу, это все равно было бы во много раз медленнее.
Итак, я пишу простую тестовую программу, которая сравнивает вызов метода, обертывающего random.NextDouble(), метод, возвращающий -1, и прямой вызов random.NextDouble(). Я провел тест в Идеоне, и он дал ожидаемые результаты; все времена были похожи, и возвращение константы было самым быстрым.Все время было около 0,1 секунды.
Однако тот же код, скомпилированный в Visual Studio 2011 Beta или 2010 C# Express, даст 4 секунды, 4 секунды и 0,1 секунды для каждого случая соответственно. Я определенно работаю в режиме выпуска, флажок оптимизации кода установлен, и запуск из-за пределов Visual Studio дает те же результаты. Так почему же вызовы таких простых методов в Visual Studio намного медленнее, чем в Ideone? Вот код, который я использовал для сравнения:
using System;
using System.Diagnostics;
public class Test{
static Random random = new Random();
public static Double Random() {
return random.NextDouble();
}
public static Double Random2() {
return -1;
}
public static void Main() {
{
Stopwatch s = new Stopwatch();
Double a = 0;
s.Start();
for (Int32 i = 0; i < 5000000; i++)
a += Random();
s.Stop();
Console.WriteLine(s.ElapsedMilliseconds);
}
{
Stopwatch s = new Stopwatch();
Double a = 0;
s.Start();
for (Int32 i = 0; i < 5000000; i++)
a += Random2();
s.Stop();
Console.WriteLine(s.ElapsedMilliseconds);
}
{
Stopwatch s = new Stopwatch();
Double a = 0;
s.Start();
for (Int32 i = 0; i < 5000000; i++)
a += random.NextDouble();
s.Stop();
Console.WriteLine(s.ElapsedMilliseconds);
}
}
}