Длинная компиляция Visual Studio при замене int на double

86

Моя копия VS2013 Ultimate компилирует этот код за 60+ секунд:

class Program
{
    static void Main(string[] args)
    {
        double dichotomy = Dichotomy(
            d =>
            {
                try
                {
                    int size = (int) d;
                    byte[] b = new byte[size];
                    return -b.Length;
                }
                catch (Exception)
                {
                    return 0;
                }
            },
            0,
            int.MaxValue,
            1);

        Console.WriteLine(dichotomy);
        Console.ReadKey();
    }

    private static double Dichotomy(
        Func<double, double> func,
        double a,
        double b,
        double epsilon)
    {
        double delta = epsilon / 10;
        while (b - a >= epsilon)
        {
            double middle = (a + b) / 2;
            double lambda = middle - delta, mu = middle + delta;
            if (func(lambda) < func(mu))
                b = mu;
            else
                a = lambda;
        }
        return (a + b) / 2;
    }
}

Но если я заменю doubleна int, он немедленно компилируется. Как это объяснить ...?

Алексей Жуковский
источник
Компилируется немедленно на моей машине для обоих типов данных ... На какой машине вы его компилируете?
Крис Мантл
1
Поцарапайте мой первый комментарий; Я наблюдаю такое же поведение. ~ 15 секунд с doubleи мгновенный с int. Машина 3,4 ГГц.
Кевин Ричардсон
Интересно. Я проверил свою версию и на самом деле использую VS2013 Premium - думал, что у меня установлен Ultimate. Возможно, это происходит только с Ultimate-версией.
Крис Мантл
1
@chris Чтобы поддержать эту гипотезу, VS Express 2013 / Windows Desktop отлично ее компилирует.
ClickRick 07
5
Из того, что я слышал, «очень странное поведение VS2013» не является чем-то необычным. :)
Lightness Races на орбите

Ответы:

140

Репро, 27 секунд на моей машине. Злоумышленник - MsMpEng.exe, столько времени сжигает 100% ядро. Легко увидеть на вкладке «Процессы» диспетчера задач.

Это служба Защитника Windows, которая фактически выполняет сканирование на наличие вредоносных программ. Отключение, сняв отметку с опции «Включить постоянную защиту», мгновенно исправляет задержку. То же самое и добавление пути, по которому я храню проекты, в поле «Исключенные местоположения файлов», вероятно, ваш предпочтительный подход.

Я бы не хотел угадывать основную причину, но должен предполагать, что ваш исходный код запускает правило вредоносного ПО. Не очень хорошее объяснение, я не вижу задержки, когда нацеливаюсь на версию .NET <4.0. Ладно, сдаюсь :)

Ганс Пассан
источник
4
Омг, Microsoft, ты издеваешься надо мной ... Tnx за помощь, это правда, MSSEи .Net 4.0+кто виноваты
Алекс Жуковский
3
Хороший улов! Мне интересно, в чем именно заключается проблема (особенно для программы, которая настолько проста и почти не содержит внешних зависимостей). Возможно ли, что результат компиляции байтов MSIL будет выглядеть точно так же, как образец известной вредоносной программы, и, таким образом, запустится MsMpEnd?
tigrou 07
-1

Я не могу сказать авторитетно, потому что прошло более 20 лет с тех пор, как я возился на уровне кода сборки, но я легко могу в это поверить.

Разница между стандартными операциями с плавающей запятой IEEE и операциями, реализуемыми процессором, часто вынуждает компоновку библиотечных подпрограмм для выполнения перевода, в то время как целочисленная математика может просто использовать инструкции процессора. В то время, когда IEEE определил стандарт, они сделали некоторые варианты, которые были очень необычными в реализации, и особенно то, что когда-то было намного дороже реализовать в микрокоде, и, конечно, современные системы ПК построены на чипах, происходящих от 80387 и 80486. , которые предшествуют стандарту.

Так что, если я прав, увеличенное время связано с добавлением фрагмента библиотечного кода к ссылке, а компоновка - это большая часть времени сборки, которая имеет тенденцию увеличиваться мультипликативно по мере добавления перемещаемых фрагментов.

Clang в Linux может иметь такое же замедление, а может и нет; если он этого избегает и расширяет мои предположения еще дальше, это будет артефакт вездесущей библиотеки libc с общей памятью, которую вы получите, и оптимизаций компоновщика вокруг этого.

оборотень
источник