Compilação longa de estúdio visual ao substituir int por duplo

86

Minha cópia do VS2013 Ultimate compila este código por mais de 60 segundos:

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;
    }
}

Mas se eu substituir doublepor int, ele compila imediatamente. Como pode ser explicado ...?

Alex Zhukovskiy
fonte
Compila imediatamente na minha máquina, para os dois tipos de dados ... Em que máquina você está compilando?
Chris Mantle
1
Raspe meu primeiro comentário; Estou vendo o mesmo comportamento. ~ 15 segundos com doublee instantâneo com int. Máquina de 3.4 GHz.
Kevin Richardson
Interessante. Verifiquei minha versão e estou executando o VS2013 Premium - pensei ter instalado o Ultimate. Talvez seja apenas a versão Ultimate com a qual isso ocorre.
Chris Mantle
1
@chris Apenas para apoiar essa hipótese, o VS Express 2013 / Windows Desktop a compila perfeitamente.
ClickRick de
5
Pelo que ouvi, "comportamento muito estranho do VS2013" dificilmente é uma raridade. :)
Lightness Races in Orbit

Respostas:

140

Eu reproduzo, 27 segundos na minha máquina. O malfeitor é MsMpEng.exe, ele queima 100% do core por tanto tempo. Fácil de ver na guia Processos do Gerenciador de Tarefas.

Este é o serviço Windows Defender, aquele que realmente executa as verificações de malware. Desativá-lo desmarcando a opção "Ativar proteção em tempo real" corrige instantaneamente o atraso. O mesmo acontece com a adição do caminho onde armazeno os projetos na caixa "Locais de arquivos excluídos", provavelmente sua abordagem preferida.

Eu odiaria ter que adivinhar o motivo subjacente, mas tenho que assumir que seu código-fonte está acionando uma regra de malware. Não é uma boa explicação, não vejo o atraso quando viso um .NET versão <4.0. Ok, eu desisto :)

Hans Passant
fonte
4
Omg, Microsoft, você está brincando comigo ... Tnx pela ajuda, é verdade MSSEe .Net 4.0+quem são os culpados
Alex Zhukovskiy
3
Boa pegada! Estou me perguntando o que exatamente causa o problema (especialmente para um programa que é tão simples e quase não contém dependências externas). Seria possível que os bytes MSIL resultantes da compilação se parecessem exatamente com um padrão de malware conhecido e, assim, o MsMpEnd fosse disparado?
tigrou
-1

Não posso dizer com autoridade porque já se passaram mais de 20 anos desde que comecei a mexer no código do assembly, mas posso facilmente acreditar nisso.

A diferença entre as operações de ponto flutuante padrão IEEE e as implementadas por um processador freqüentemente força a vinculação nas rotinas da biblioteca para fazer a tradução, enquanto a matemática inteira pode apenas usar as instruções da CPU. Na época em que o IEEE definiu o padrão, eles fizeram algumas escolhas que eram muito incomuns na implementação, e especialmente aquelas há muito mais caras para implementar em microcódigo e, claro, os sistemas de PC atuais são construídos em torno de chips descendentes de 80387 e 80486 , que são anteriores ao padrão.

Então, se eu estiver certo, o tempo maior é porque envolve a adição de um pedaço de código de biblioteca ao link, e a vinculação é uma grande parte do tempo de construção que tende a crescer multiplicativamente à medida que pedaços relocáveis ​​são adicionados.

O Clang no Linux pode ou não ter a mesma lentidão; se evitar, e estendendo minhas suposições ainda mais, isso seria um artefato da omnipresente biblioteca de memória compartilhada que você obtém e otimizações de linker em torno disso.

homem-jogador
fonte