Compilazione lunga di Visual Studio quando si sostituisce int con double


86

La mia copia di VS2013 Ultimate compila questo codice per oltre 60 secondi:

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

Ma se sostituisco doublecon int, viene compilato immediatamente. Come si spiega ...?


Compila immediatamente sulla mia macchina, per entrambi i tipi di dati ... Su quale macchina lo stai compilando?
Chris Mantle

1
Gratta il mio primo commento; Sto vedendo lo stesso comportamento. ~ 15 secondi con doublee istantaneo con int. Macchina da 3,4 Ghz.
Kevin Richardson

Interessante. Ho controllato la mia versione e in realtà sto eseguendo VS2013 Premium, pensavo di aver installato Ultimate. Forse è solo la versione Ultimate con cui ciò si verifica.
Chris Mantle

1
@chris Giusto per supportare questa ipotesi, VS Express 2013 / Windows Desktop lo compila perfettamente.
ClickRick

5
Da quello che ho sentito, "VS2013 comportamento molto strano" non è certo una stranezza. :)
Gare di leggerezza in orbita l'

Risposte:


140

Riprovo, 27 secondi sulla mia macchina. Il malfattore è MsMpEng.exe, brucia il core al 100% per così tanto tempo. Facile da vedere nella scheda Processi di Task Manager.

Questo è il servizio Windows Defender, quello che esegue effettivamente le scansioni malware. Disattivarlo deselezionando l'opzione "Attiva protezione in tempo reale" risolve immediatamente il ritardo. Lo stesso vale per l'aggiunta del percorso in cui memorizzo i progetti nella casella "Percorsi dei file esclusi", probabilmente il tuo approccio preferito.

Non vorrei dover indovinare il motivo sottostante, ma devo presumere che il tuo codice sorgente stia attivando una regola del malware. Non è un'ottima spiegazione, non vedo il ritardo quando scelgo come destinazione una versione .NET <4.0. Va bene, mi arrendo :)


4
Omg, Microsoft, mi prendi in giro ... Tnx per chiedere aiuto, è veramente MSSEe .Net 4.0+chi sono i colpevoli
Alex Zhukovskiy

3
Buona pesca! Mi chiedo quale sia esattamente la causa del problema (specialmente per un programma che è così semplice e non contiene quasi dipendenze esterne). Sarebbe possibile che i byte MSIL risultanti dalla compilazione assomiglino esattamente a un pattern di un malware noto e quindi MsMpEnd si attiverebbe?
tigrou

-1

Non posso dirlo in modo autorevole perché sono passati più di 20 anni da quando ho giocherellato a livello di codice assembly, ma posso crederci facilmente.

La differenza tra le operazioni in virgola mobile standard IEEE e quelle implementate da un processore spesso forza il collegamento nelle routine della libreria per eseguire la traduzione, mentre la matematica intera può semplicemente usare le istruzioni della CPU. Nel momento in cui l'IEEE ha definito lo standard, ha fatto alcune scelte che erano molto rare nell'implementazione, e soprattutto che molto tempo fa molto più costose da implementare in microcodice, e ovviamente gli attuali sistemi PC sono costruiti attorno a chip discendenti dagli 80387 e 80486 , che sono antecedenti allo standard.

Quindi, se ho ragione, il tempo aumentato è perché implica l'aggiunta di una parte del codice della libreria al collegamento e il collegamento è una parte importante del tempo di compilazione che tende a crescere in modo moltiplicativo man mano che vengono aggiunti blocchi rilocabili.

Clang su Linux potrebbe o non potrebbe avere lo stesso rallentamento; se lo evita, ed estendendo ulteriormente le mie supposizioni, sarebbe un artefatto dell'onnipresente libc a memoria condivisa che ci si arriva e le ottimizzazioni del linker attorno a questo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.