Compilation longue de Visual Studio lors du remplacement de int par double

86

Ma copie de VS2013 Ultimate compile ce code pendant plus de 60 secondes:

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

Mais si je remplace doublepar int, il se compile immédiatement. Comment s'explique-t-il ...?

Alex Zhukovskiy
la source
Compile immédiatement sur ma machine, pour les deux types de données ... Sur quelle machine le compilez-vous?
Chris Mantle
1
Grattez mon premier commentaire; Je vois le même comportement. ~ 15 secondes avec doubleet instantané avec int. Machine 3.4Ghz.
Kevin Richardson
Intéressant. J'ai vérifié ma version et j'utilise actuellement VS2013 Premium - je pensais avoir installé Ultimate. C'est peut-être juste la version Ultimate avec laquelle cela se produit.
Chris Mantle
1
@chris Juste pour soutenir cette hypothèse, VS Express 2013 / Windows Desktop le compile très bien.
ClickRick
5
D'après ce que j'ai entendu, "VS2013 comportement très étrange" n'est guère une bizarrerie. :)
Courses de légèreté en orbite le

Réponses:

140

Je repro, 27 secondes sur ma machine. Le malfaiteur est MsMpEng.exe, il brûle 100% du noyau pendant ce temps. Facile à voir dans l'onglet Processus du gestionnaire de tâches.

Il s'agit du service Windows Defender, celui qui effectue réellement les analyses de logiciels malveillants. Le désactiver en décochant l'option "Activer la protection en temps réel" corrige instantanément le retard. Il en va de même pour l'ajout du chemin où je stocke les projets dans la case "Emplacements des fichiers exclus", probablement votre approche préférée.

Je détesterais devoir deviner la raison sous-jacente, mais je dois supposer que votre code source déclenche une règle de malware. Pas une bonne explication, je ne vois pas le délai lorsque je cible une version .NET <4.0. D'accord, j'abandonne :)

Hans Passant
la source
4
Omg, Microsoft, vous vous moquez de moi ... Tnx pour l'aide, c'est vraiment MSSEet .Net 4.0+qui sont les coupables
Alex Zhukovskiy
3
Bonne prise! Je me demande ce qui cause exactement le problème (en particulier pour un programme qui est si simple et ne contient presque pas de dépendances externes). Serait-il possible que les octets MSIL résultants de la compilation ressemblent exactement à un modèle de malware connu et que MsMpEnd se déclenche donc?
tigrou
-1

Je ne peux pas le dire avec autorité, car cela fait plus de 20 ans que je n'ai pas joué au niveau du code d'assemblage, mais je peux facilement le croire.

La différence entre les opérations à virgule flottante standard IEEE et celles implémentées par un processeur oblige souvent la liaison dans les routines de bibliothèque à effectuer la traduction, tandis que les mathématiques entières peuvent simplement utiliser les instructions du processeur. Au moment où l'IEEE a défini la norme, ils ont fait des choix qui étaient très rares dans la mise en œuvre, et surtout qu'il y a longtemps beaucoup plus coûteux à implémenter en microcode, et bien sûr les systèmes PC actuels sont construits autour de puces descendantes des 80387 et 80486. , qui sont antérieures à la norme.

Donc, si j'ai raison, l'augmentation du temps est due au fait qu'elle implique l'ajout d'un morceau de code de bibliothèque au lien, et la liaison est une grande partie du temps de construction qui a tendance à augmenter de manière multiplicative à mesure que des morceaux déplaçables sont ajoutés.

Clang sur Linux peut avoir ou non le même ralentissement; s'il l'évite, et étend mes hypothèses encore plus loin, ce serait un artefact de la libc omniprésente à mémoire partagée que vous y arrivez et des optimisations de l'éditeur de liens autour de cela.

wasgamer
la source