Stopwatch.Restart() : une autre nouveauté de .NET 4.0

C’est le genre de petite fonction qui ne mange pas de pain, mais qui montre que parfois, Microsoft prend en compte les demandes des développeurs. Restart() ne fait rien qu’il était impossible de faire en .NET 2.0 : il rend simplement l’utilisation des chronomètres plus élégante.

Imaginez le code suivant :

static void Main(string[] args)
{
    Stopwatch Chrono = Stopwatch.StartNew();
    // Traitement 1
    Chrono.Stop();
    Console.WriteLine("Traitement 1 : {0}", Chrono.Elapsed);

    Chrono.Reset();
    Chrono.Start();
    // Traitement 2
    Chrono.Stop();
    Console.WriteLine("Traitement 2 : {0}", Chrono.Elapsed);
}

Comme nous devons chronométrer deux traitements, il est nécessaire de remettre à zéro le chronomètre, sinon il repartira de sa valeur affichée pour le premier traitement. Il faut donc appliquer un Reset(), puis seulement relancer le chronomètre avec Start(). Dommage de faire deux lignes de code, et on en vient vite à écrire ceci pour aller plus vite :

static void Main(string[] args)
{
    Stopwatch Chrono = Stopwatch.StartNew();
    // Traitement 1
    Chrono.Stop();
    Console.WriteLine("Traitement 1 : {0}", Chrono.Elapsed);

    Chrono = Stopwatch.StartNew();
    // Traitement 2
    Chrono.Stop();
    Console.WriteLine("Traitement 2 : {0}", Chrono.Elapsed);
}

Mais là, c’est plus un problème de gestion de ressource : pourquoi abandonner une instance de Stopwatch, et donc donner du travail au ramasse-miettes, alors qu’on pourrait continuer à l’utiliser comme montré précédemment ? C’est de la perte de ressources et tout nous pousse à éviter ceci : l’optimisation des performances des machines, le Lean, l’écologie…

La solution : Restart() qui nous permet de garder notre instance de Stopwatch, et en même temps de relancer le chronomètre en une seule instruction :

static void Main(string[] args)
{
    Stopwatch Chrono = Stopwatch.StartNew();
    // Traitement 1
    Chrono.Stop();
    Console.WriteLine("Traitement 1 : {0}", Chrono.Elapsed);

    Chrono.Restart();
    // Traitement 2
    Chrono.Stop();
    Console.WriteLine("Traitement 2 : {0}", Chrono.Elapsed);
}

Ce n’est pas grand chose, mais quand on fait des tests de performance toute la journée, ça sert…

Posted in .NET | Tagged | Leave a comment

Programmation parallèle et HyperThreading : les limites…

Je suis en train de bouquiner cette merveille de Joe Duffy :

http://www.amazon.com/Concurrent-Programming-Windows-CONCURRENT-PROGRAMMING/dp/B002HLS6QK

Concurrent Programming on Windows [CONCURRENT PROGRAMMING ON WIND]

Que ceux qui aiment en avoir pour leur argent courent l’acheter : c’est du lourd, dans tous les sens du terme… 950 pages, mais surtout une mine d’information sur ce qui se passe derrière les mécanismes de threading : comment Windows gère, découpe, affecte les tranches et les priorités, quels sont les mécanismes de verrou et comment ils fonctionnent, comment ils peuvent être mis en oeuvre au niveau du hardware, etc. Génial…

La raison pour laquelle je parle de ce livre est qu’il m’a permis de comprendre en détail ce qui se passait sur la parallélisation de calculs intensifs avec l’HyperThreading.

Pour situer le contexte : lors de mes premiers tests sur la parallélisation, j’ai souhaité voir la performance des BlockingCollection et j’ai réalisé le petit programme ci-dessous :

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Collections.Concurrent;

namespace TestParallelisme
{
    class Program
    {
        static void Main(string[] args)
        {
            List<int> Entiers = new List<int>();
            for (int i = 1000000; i < 1200000; i++)
                Entiers.Add(i);

            List<int> PremiersStandard = new List<int>();
            Stopwatch Chrono = Stopwatch.StartNew();
            foreach (int Entier in Entiers)
                if (EstPremier(Entier))
                    PremiersStandard.Add(Entier);
            Console.WriteLine("{0} premiers trouvés en {1}", PremiersStandard.Count, Chrono.Elapsed);

            BlockingCollection<int> PremiersParallel = new BlockingCollection<int>();
            Chrono = Stopwatch.StartNew();
            Parallel.ForEach(Entiers, i => { if (EstPremier(i)) PremiersParallel.Add(i); });
            Console.WriteLine("{0} premiers trouvés en {1}", PremiersParallel.Count, Chrono.Elapsed);

        }

        private static bool EstPremier(int Entier)
        {
            for (int i = 2; i < Entier - 1; i++)
                if (Entier % i == 0)
                    return false;
            return true;
        }
    }
}

Vu que la machine de test est un bi-processeur Quad-Core avec l’HyperThreading activé, je disposais de 16 voies, et le calcul parallélise évidemment très bien :

image

Mais en termes de performance, on n’est pas sur un rapport de 16, mais très proche de 8 :

image

Ceci m’a vite fait penser que l’HyperThreading n’était pas fait pour exécuter en parallèle du code intensif, mais bien pour accélérer le traitement en gardant des contextes d’exécution dédoublés, tout en partageant l’unité de calcul.

Si on désactive l’HT dans le BIOS, on voit qu’on ne dispose plus que de 8 voies :

image

Mais les performances n’ont quasiment pas bougé :

image

Voila qui confirmait que l’HyperThreading n’accélérait les traitements que lorsqu’ils ne sont pas intensifs du point de vue du CPU. J’avais enfin la justification mesurable des articles sur les blogs Maya qui expliquait qu’il valait mieux désactiver l’HT. Effectivement, pour des opérations de rendu 3D très gourmandes en CPU, l’HT n’apporte rien. Il peut effectivement permettre d’exécuter en parallèle des threads avec peu de calcul, mais de toute façon, le gain ne sera que parce qu’il n’y a pas de perte de temps pour le rechargement du contexte.

Avoir une justification quantifiée est sympa, mais le mieux est encore d’avoir l’explication précise de pourquoi ça fonctionne comme ça… mais ça, c’est le bouquin de Joe Duffy qui vous le dira !

Oui, je sais, vous aimeriez bien avoir la réponse, mais ce bouquin est tellement bien fait que je ne me permettrai pas d’expliquer avec mes mots à moi, qui reflèteraient le fait que je ne suis pas encore 100% à l’aise avec ces concepts, ce qui est très bien amené dans le livre. A vos libraires, donc…

Et en cadeau-bonus : un chapitre gratuit !

Posted in Parallélisation | 2 Comments

TryParse pour Enum : ça existe, mais en .NET 4.0

La plupart d’entre vous savez que gérer une exception est quelque chose de très lent, et qui peut amener à des potentiels problèmes de performance. Prenons un bloc de code comme ceci :

decimal Resultat = 0;

Stopwatch Chrono = Stopwatch.StartNew();
try { Resultat = decimal.Parse("coucou"); }
catch { Resultat = -1; }
Chrono.Stop();
Console.WriteLine("Dans un try...catch : {0} ticks", Chrono.ElapsedTicks);

Chrono.Restart();
if (!decimal.TryParse("coucou", out Resultat))
    Resultat = -1;
Chrono.Stop();
Console.WriteLine("Avec un TryParse : {0} ticks", Chrono.ElapsedTicks);

Notez au passage qu’il faut bien affecter la valeur –1 en cas d’échec : comme la variable est précédée d’un mot-clé out dans la signature, cela signifie que c’est la fonction qui l’initialise, et elle le fait sur la valeur par défaut du type. Toute affectation préalable sera écrasée.

L’exécution ramènera quelque chose comme :

image

Il y a bien sûr un peu de variance en fonction de la machine, l’ordre dans lequel on exécute les deux tests, peut-être des effets de cache, etc. Mais en gros, le fait de traiter une exception pose un gros problème de temps, et c’est la raison pour laquelle la fonction TryParse existe : aller vite pour traiter, tout en ouvrant la porte à une possibilité relativement fréquente de chaîne non transformable dans le type qu’on cherche à attendre.

Bien sûr, si vous avez une certaine garantie que la chaîne est censée ne jamais être autre chose qu’un numérique, vous pouvez tout à fait utiliser Parse, et laisser les cas exceptionnels (c’est d’ailleurs bien pourquoi on appelle ceci des exceptions) être traités par le catch.

Au passage, même si on remplace la chaîne coucou pour une chaîne comme 12 qui ne provoque pas d’exception, on reste dans des rapports non négligeables :

image

La fonction TryParse existe aussi pour les entiers, les dates, etc. Mais curieusement, jusqu’à .NET 4.0, elle n’existait pas pour les énumérations. Du coup, on était obligé de réaliser ce genre de code, qui est bien sûr plus rapide que de traiter l’exception, mais qui n’est pas très élégant :

enum Mode { NORMAL = 0, RAPIDE = 1 };

static void Main(string[] args)
{
    Mode Resultat = 0;

    Stopwatch Chrono = Stopwatch.StartNew();
    try { Resultat = (Mode)Enum.Parse(typeof(Mode), "COUCOU"); }
    catch { Resultat = Mode.NORMAL ; }
    Chrono.Stop();
    Console.WriteLine("Dans un try...catch : {0} ticks", Chrono.ElapsedTicks);

    Chrono.Restart();
    Resultat = Mode.NORMAL;
    if (Enum.IsDefined(typeof(Mode), "COUCOU"))
        Resultat = (Mode)Enum.Parse(typeof(Mode), "COUCOU");
    Chrono.Stop();
    Console.WriteLine("Avec un TryParse : {0} ticks", Chrono.ElapsedTicks);
}

J’ai fait exprès ici de répéter la valeur COUCOU en dur, qui viendrait normalement d’une variable, pour faire apparaître le manque d’élégance de ce code : d’une certaine manière, on force .NET à travailler deux fois. Il doit d’abord vérifier que l’entrée existe dans l’énumération, puis si c’est le cas, refaire à peu près le même travail pour trouver cette valeur.

C’est un peu la même chose que l’utilisation d’un as au lieu d’un is :

// Code peu performant, car la conversion est réalisée potentiellement deux fois
if (Instance is Personne)
    ((Personne)Instance).Reveiller();

// Code plus élégant et performant
Personne p = Instance as Personne;
if (p != null)
    p.Reveiller();

Encore une petite note pour préciser qu’en plus, le second code est mieux résistant au cas où l’instance est nulle.

Heureusement, .NET 4.0 a corrigé ceci, avec un TryParse dans la classe Enum, et générique de surcroît, ce qui va nous éviter ces horreurs de cast…

Le bon code est donc celui-ci :

Mode Resultat = 0;

Stopwatch Chrono = Stopwatch.StartNew();
try { Resultat = (Mode)Enum.Parse(typeof(Mode), "COUCOU"); }
catch { Resultat = Mode.NORMAL ; }
Chrono.Stop();
Console.WriteLine("Dans un try...catch : {0} ticks", Chrono.ElapsedTicks);

Chrono.Restart();
if (!Enum.TryParse<Mode>("COUCOU", out Resultat))
    Resultat = Mode.NORMAL;
Chrono.Stop();
Console.WriteLine("Avec un TryParse : {0} ticks", Chrono.ElapsedTicks);

 

Il est à la fois élégant, et surtout très performant dans le cas où les chaînes sont invalides plus souvent que de manière absolument exceptionnelle :

image

Merci à Johan de m’avoir fait remarqué ceci.

Posted in .NET, C# | 2 Comments

Centre de solutions .NET Framework

Je suis content de vous annoncer que ce blog est désormais référencé dans le Centre de solutions .NET du support Microsoft (catégorie Communautés). Je ne peux que vous recommander d’aller faire un tour sur http://support.microsoft.com/ph/548/fr, c’est plein de ressources intéressantes. J’ai du coup découvert de nouveaux blogs de collègues (ou devrais-je dire “coreligionnaires”) MVP.

image

Posted in .NET | Leave a comment

Méthodes agiles : aux racines du pragmatisme

Je souhaite préciser tout d’abord que ce n’est pas dans mes habitudes de démonter un article. J’ai une approche toute scientifique de la vérité, qui n’est faite que de doute et de remises en question. Vous pouvez éplucher ce blog, et je suis à peu près sûr que vous n’y trouverez pas une critique sans que je propose une alternative.

Mais là, ça dépasse les bornes. On est habitués, sur internet, à des articles pas très bien informés, ou à des posts reprenant simplement les communiqués de presse de tel ou tel éditeur. Mais ce que j’ai lu hier sur les méthodes agiles dans cet article se doit d’être classé dans le domaine de l’ignorance quasi-totale, voire de la médisance…

There is nothing more dangerous than a little knowledge

J’aime bien ce proverbe anglais, et je trouve qu’il est très vrai : acquérir un peu de connaissance sur quelque chose qui était auparavant complètement inconnu peut donner la fausse impression d’avoir tout compris au problème. Je pense que c’est ce qui a touché l’auteur de cet article…

Entendons-nous bien : je ne prétends pas être un expert des méthodes agiles. J’ai participé en tant qu’orateur à quelques étapes de l’Agile Tour, mais mes conférences sont surtout des retours d’expérience, et je ne connais pas assez la théorie pour discuter de l’agilité de manière définitive. A l’occasion de l’Agile Tour Vannes, j’ai d’ailleurs préféré refuser l’honneur que m’avait fait l’équipe organisatrice de me proposer de participer à la table ronde du midi aux côtés de Régis Médina, Laurent Morisseau, Patrice Petit et Alexandre Boutin : je suis un vermisseau à côté de ces personnages de l’agilité.

Eux sont de vrais experts… mais ça serait limite injurieux (et une perte de temps intellectuel précieux) de convoquer de telles pointures pour expliquer tout ce qui ne va pas dans cet article.

Commençons par le titre

“Méthodes agiles : du dogme au pragmatisme” : l’avantage dans ce genre de titre est qu’on est tout de suite au courant du niveau de l’article. Visiblement, l’auteur de cet article n’est pas au courant que le pragmatisme est justement une des valeurs fondamentales de l’agilité. Aller écrire que l’agilité vient au pragmatisme… il faut que je cherche mes mots et ma comparaison pour bien faire comprendre l’absurdité d’une telle phrase. Voyons voir :

Picasso devrait faire preuve d’abstraction

ou bien peut-être :

Microsoft : un avenir dans l’édition logicielle ?

Il faut bien comprendre que l’agilité est justement l’inverse du dogmatisme. Ce ne sont pas des théories logicielles qui ont présidé à l’établissement du manifeste agile, mais la longue expérience d’une quinzaine de professionnels distillée dans des principes qui ont été démontrés comme facteurs essentiels de réussite des projets informatiques.

Comme une majorité de personnes qu’on rencontre sur l’Agile Tour, je suis personnellement venu à l’agilité par le chemin du pragmatisme. En fait, j’ai même commencé à appliquer des principes agiles avant de prendre connaissance de ce mouvement dans son ensemble, et nous sommes très nombreux à nous être reconnus dans les méthodes agiles après les avoir appliquées sans le savoir. Tous les principes du manifeste agile sont applicables sans aucun lien à une théorie quelconque.

Donc, ne serait-ce que sous-entendre que l’agilité a pu passer par une étape de dogmatisme montre une ignorance quasi-complète du domaine…

Trois lignes plus bas

Juste après le titre, on nous apprend que “les méthodes agiles ont souvent été mises en œuvre de manière dogmatique”. Affirmation gratuite et sans aucune référence, mais peut-être est-ce qu’inconsciemment, l’auteur a souhaité donné une piste pour corriger l’énormité du titre. Effectivement, le dogmatisme peut être dans l’application d’une méthode, mais certainement pas dans la méthode elle-même.

L’auteur continue en nous expliquant doctement que la réussite des projets agiles passe par le respect de certaines “précautions et compromis”. Passons sur le fait que toute personne un tant soit peu au courant des retours d’expérience sur l’agilité sait que la plupart des “compromis” sur les principes sont justement des causes d’échec des projets soit-disant menés en mode agile. C’est d’ailleurs un des principaux arguments des personnes qui rejettent l’approche agile : ériger en preuve de l’échec de la méthode des projets qui ont été menés en saupoudrant des notions d’agilité, sans comprendre le besoin d’adoption globale de la méthode.

Encore une fois, il faut trouver une comparaison pour bien faire comprendre la limite de ce genre d’approche. Imaginez par exemple qu’un tailleur se contente de découper les morceaux d’un costume et vous les livre tels quels. Appliquer certaines notions de SCRUM sans adopter la démarche dans sa totalité reviendrait au même : ça n’aurait tout simplement pas de sens. Ce qui n’empêche pas la souplesse, et les équipes ayant adopté l’agilité se sont souvent créées leur méthode propre. Mais cela passe par l’adaptation, et non l’écrémage.

Pour en revenir aux “compromis” proposés par l’auteur, prenons juste le premier, à savoir “répondre aux attentes des métiers en parlant leur langage”. Et l’auteur d’expliquer le principe des itérations courtes et son avantage. En quoi est-ce une “précaution” à prendre par rapport aux méthodes agiles ? C’est la base de SCRUM !

Et puis si, finalement : on va en traiter une autre, parce que la troisième vaut également son pesant de cacahuètes. “Adapter la méthode aux contraintes des métiers” explique que “le métier n’est pas forcément en mesure de déléguer en permanence une personne”. Encore une fois, ceci peut expliquer justement la mauvaise vision que les auteurs et témoins ont visiblement des méthodes agiles : s’ils ont participé à un projet SCRUM où le Product Owner n’était pas présent la majorité du temps, il n’est pas étonnant que le projet se soit mal passé : c’est une des principales causes d’échec de projets.

Allez, une dernière perle pour la route : “L’équipe projet doit faire preuve de souplesse dans la mise en œuvre des méthodes agiles, en s’adaptant en temps réel aux contraintes des métiers”. Tout l’inverse de l’idée de fixer la backlog de sprint… L’idée même que l’agilité pourrait porter de la rigidité sur l’adaptation aux besoins clients est absurde : les méthodes agiles sont justement nés de la constatation de l’effet tunnel induit par les méthodes traditionnelles. La réaction de mon ancien chef en lisant ceci : “Ce genre d’article est dangereux. En gros, ils prennent ce qui fait vendre (ce que le client veut) et pas ce qui pourrait faire mieux fonctionner le projet…” (note : ce commentaire éclairé vient d’un Certified Scrum Master).

Petit retour sur le dogmatisme

Nous parlions un peu plus haut des échecs de SCRUM (oui, le monde agile reconnait que ses méthodes ne sont pas parfaites – encore une preuve de non-dogmatisme, s’il fallait qu’on en rajoute) : Alexandre Boutin a une excellente présentation sur ce point, que je vous invite à voir si vous le pouvez. Suite à des retours concrets depuis plus de dix ans, Alexandre nous présente les causes d’échec les plus habituels de projets agiles. Une des principales est justement le manque de temps accordé au Product Owner. Une autre est l’application incomplète des principes agiles.

Ceci me fait revenir sur l’opposition entre le dogmatisme et le pragmatisme. D’un côté, je vois un retour informé et extrêmement fourni d’un professionnel de SCRUM. Pas de théorie dans cette présentation : juste des retours d’expérience suffisamment nombreux pour qu’on puisse en tirer des conclusions applicables. Pour moi, on est clairement dans le pragmatisme.

De l’autre côté, un article qui a la prétention d’apporter des “précautions et des compromis” à l’application d’une méthode qui s’impose de plus en plus comme un moyen de réussir les projets informatiques, et ce sans se préoccuper que ces conseils puissent être l’exact inverse de ce que propose la méthode.

Doutez, doutez, doutez…

Il est assez désolant que ce genre d’article puisse être publié sur un portail d’information à destination des professionnels de l’informatique, en particulier sans permettre de déposer des commentaires. L’auteur explique que les mots clés de l’agilité peuvent faire peur aux développeurs et aux utilisateurs : c’est sûr que si des personnes non informées passent leur temps à expliquer les limites d’une méthode qu’ils ne connaissent pas, on continuera à ramer pour en faire comprendre les apports.

Si je peux me permettre un conseil : doutez… C’est l’approche scientifique dans toute sa grandeur que de douter de tout. L’agilité m’a beaucoup apporté, mais je n’ai pas de problème à en remettre en cause certains points. De la même manière, je vous encourage à douter de mon propre point de vue exposé dans ce blog : renseignez-vous par d’autres sources, allez voir le site Agile Tour, lisez des blogs de vrais spécialistes du sujet…

Mais par pitié, si vous êtes tombés dessus, oubliez cet article “Méthodes agiles : du dogme au pragmatisme” !

Posted in Agile, Retours | Tagged | Leave a comment

Webcasts Visual Studio

Un petit billet rapide juste pour donner l’adresse des webcasts sur Visual Studio : beaucoup de sujets sur l’ALM, le développement et les tests :

http://www.microsoft.com/france/visual-studio/evenements/

Juste un petit regret sur la qualité de la vidéo : on a vu mieux, et c’est important quand on fait voir du code.

Je profite également de ce billet pour souligner que Microsoft s’investit de plus en plus dans le mouvement Agile. L’Agile Tour Paris 2011 sera d’ailleurs dans leurs locaux.

Posted in ALM, Tests | Tagged | Leave a comment

Profilage de performance sur tests dans Visual Studio 2010

Pour commencer, un petit caveat : vous ne pourrez reproduire ce qui suit que sur une version Premium ou Ultimate de Visual Studio 2010.

Je souhaitais rediger ce petit post pour éviter si possible à certains de mes lecteurs de galérer comme un imbécile à chercher une solution compliquée pour faire quelque chose de simple. Supposons que vous souhaitiez lancer une analyse de performance par le profileur embarqué dans Visual Studio 2010, et ce en vous basant sur des tests (pour ceux qui ne connaissent pas le profilage, je me permets de vous renvoyer à mon bouquin sur le sujet) :

image

Pour cela, on pourrait s’imaginer qu’on va instrumenter la ClassLibrary :

image

Et derrière, on se branche sur MSTest.exe pour exécuter le code de test :

image

Quand on lance, on voit le message d’erreur suivant :

image

Que je recopie ici, juste pour aider à l’indexation :

MSTest.exe est signé et son instrumentation rendra sa signature non valide. Si vous poursuivez sans événement de post-instrumentation pour signer à nouveau le binaire, il risque de ne pas être chargé correctement. Voulez-vous continuer sans le resigner ?

Que se passe-t-il ? Simplement que, comme on est en mode instrumentation, Visual Studio a besoin de modifier les assemblages pour pouvoir profiler dessus. Or, nous n’avons pas indiqué que l’exécutable, en l’occurrence le lanceur de tests de Visual Studio, ne devait pas être lui-même instrumenté. Qu’à cela ne tienne, on va simplement décocher ceci dans l’Explorateur de performances :

image

Tout a l’air de bien se passer. On voit le test se lancer :

image

Le rapport est bien créé, également.

Mais cela ne fonctionne toujours pas, dans le sens où le rapport de performance est vide, et même refuse de s’ouvrir. On voit bien Visual Studio tenter de l’ouvrir, mais il se referme immédiatement et automatiquement, sans message d’erreur.

Arrivés à ce point, vous vous dites qu’il faut peut-être pointer de manière plus explicite sur les librairies instrumentées, en les plaçant dans un répertoire à part, vu qu’une option sur les propriétés de Performance vous permet de le faire :

image

Mais non, rien n’y fait… Bref, après une demie-heure à essayer de faire le malin, il faut bien se rendre à l’évidence : il va falloir lire la doc Sourire

Et évidemment, il y a un moyen d’une simplicité phénoménale d’arriver au bon résultat, à savoir simplement générer une session de profilage depuis la fenêtre Affichage des tests. Vous pouvez activer celle-ci depuis le menu Test, comme ceci :

image

Dans la fenêtre qui apparait, il ne reste plus qu’à lancer une session de performance sur le test unitaire…

image

Vous pouvez alors simplement choisir la méthode de profilage (la première page de l’assistant ne contient qu’une information) :

image

Et lancer simplement l’analyse :

image

Au final, vous obtenez les résultats tant attendus :

image

Dans notre cas, il s’agissait simplement de démontrer la supériorité en termes de performance d’un AddRange sur un Add en boucle sur une liste générique (sur 1000 appels d’une liste de 100 chaînes, on passe de 30,80 ms à seulement 0,87 ms).

J’en profite d’ailleurs pour rajouter une remarque rapide sur un problème tout bête : lorsqu’on profile sur des cas de benchmarks, et non pas sur des situations plus réalistes, il arrive qu’on ne voit pas les entrées dans le rapport de profilage pour certaines des fonctions qui sont appelées.

Le réflexe est d’aller voir si on a bien désactivé le filtre de suppression des fonctions les plus courtes (en termes de temps) :

image

Mais même en supprimant ceci, il arrive qu’on ne voit pas les fonctions recherchées car elles sont trop courtes en termes de taille. En effet, dans les propriétés de l’analyse de performance, une option Exclure les petites fonctions de l’instrumentation est par défaut activée :

image

Attention, lorsque vous aurez désactivé cette option, il faut bien penser à relancer l’analyse : nous ne sommes pas sur un filtre du rapport après coup, mais bien une option de l’enregistrement…

Posted in .NET, Tests | Tagged | 1 Comment

Concours avec un Windows Phone et une Kinect à gagner

Microsoft organise un concours “J’en ai rien à déployer”, dans le droit fil des “J’en ai rien à coder”. Une Kinect pour faire quelques tests du SDK me tente bien, moi Sourire J’aimerais bien voir si on peut affecter des gestes de la main à des déplacements de fenêtre…

homepage_slideJARAD

Posted in .NET | Tagged | Leave a comment

Provider ADO.NET pour Bamboo

Il y a longtemps que je n’ai pas abordé le sujet de la prévalence objet sur ce blog. Le sujet est toutefois loin d’être abandonné. Je travaille en ce moment à un provider ADO.NET pour Bamboo. J’ai usé un premier stagiaire l’an passé qui a posé les fondements du fournisseur, et je vais normalement en avoir un second cette année pour finir les tests et l’implémentation, en particulier le branchement sur un mécanisme d’analyse de la grammaire SQL.

Pour l’instant, l’analyse complète du SQL a été laissée de côté. On implémente de manière très progressive, en mode “développement émergeant piloté par les tests”, ce qui me permet de laisser plus de liberté aux stagiaires une fois que les tests unitaires sont bien posés. A ce jour, il y a donc toute l’architecture (en utilisant l’injection pour l’analyseur, factice pour l’instant, ainsi que pour le coordinateur et le mécanisme de correspondance des champs avec les propriétés dans les listes prévalentes).

Ce qu’il manque est la prise en compte des grammaires SQL complètes. Je vais donc lancer mon stagiaire futur sur les traditionnels Lex / Yac en version .NET, mais aussi lui demander de voir s’il n’existe pas une grammaire SQL pour le langage M. Ca serait l’idéal.

Comme cela avait été reconnu dans un des premiers posts sur la prévalence objets, la grande limitation de l’approche en milieu industriel est la difficulté de migrer des applications avec un gros existant en termes de SQL. J’espère qu’avec un fournisseur ADO.NET, ce point sera levé, et permettra à plus de gens d’envisager une migration.

Posted in .NET, Prevalence | Tagged | Leave a comment

Merci, Windows Live Writer !

Suite à des problèmes sur l’ancienne plateforme de blog, j’ai réalisé un transfert des anciens posts sur ce blog, et ai été confronté à la perte des quatre derniers billets. Heureusement, Live Writer m’a permis de retrouver ces fichiers.

La manipulation est simple : cliquez la commande “Ouvrir le billet récent” (quand vous passez dessus, le menu sur la droite apparait, mais vous pouvez tout de même cliquer sur la commande elle-même).

image

Dans la fenêtre qui s’affiche, entrez un mot clé du post que vous avez perdu sur le serveur :

image

Sélectionnez celui qui vous intéresse et cliquez sur OK. Vous obtiendrez alors un dialogue vous signalant que le post ne peut pas être récupéré du serveur, mais vous proposant gentiment de repartir de la version qui avait automatiquement sauvegardée en local Sourire.

Posted in Uncategorized | Leave a comment