dimanche 22 février 2009

Hashtable, Dictionary<TKey, TValue> etc.

Rentrons directement dans le vif du sujet : Je ne vous présente plus la classe Hashtable, ni la classe Dictionary<TKey, TValue>. Et bien j'ai fait une petite constatation et je voulais vous en faire part ô chers lecteurs. Supposons qu'à partir de 2 collections diverses, nous souhaitions en peupler une troisième :

// Notre 1ère collection :
// On crée 3 personnes et on les ajoute à notre 1ère collection
Personne jaco = new Personne("Pastorius", "John Francis Anthony", new DateTime(1951, 12, 1));
Personne marcus = new Personne("Miller", "Marcus", new DateTime(1959, 6, 14));
Personne victor = new Personne("Wooten", "Victor Lemonte", new DateTime(1964, 11, 8));

List<Personne> topBassists = new List<Personne>();
topBassists.Add(jaco);
topBassists.Add(marcus);
topBassists.Add(victor);

// Notre 2è collection
// On récupère à partir d'une source tierce, 3 autres personnes.
Personne s = new Personne("Clarck", "Stanley", new DateTime(1948, 10, 17));
Personne m = new Personne("Miller", "Marcus", new DateTime(1959, 6, 14));
Personne v = new Personne("Wooten", "Victor Lemonte", new DateTime(1964, 11, 8));

List<Personne> smvBassists = new List<Personne>();
smvBassists.Add(s);
smvBassists.Add(m);
smvBassists.Add(v);

//..
// Enfin on souhaite récupérer une liste de personnes avec comme source les 2 listes précédentes.
List<Personne> jazzFestival = new List<Personne>();
jazzFestival.AddRange(topBassists);
jazzFestival.AddRange(smvBassists);

Vous l'avez deviné on va se retrouver avec des doublons dans notre liste.


C'est là qu'intervient la classe hashtable ou Dictionary<TKey, TValue>. Elle va nous permettre de gérer les doublons :

Dictionary<string, Personne> jazzFestivalTriee = new Dictionary<string, Personne>();

foreach (Personne p in jazzFestival)
{
if (!jazzFestivalTriee.ContainsKey(p.Nom))
jazzFestivalTriee.Add(p.Nom, p);
}

Et là, on se retrouve avec une collection d'éléments uniques. Top non ? Bon ok, il n'y a pas de quoi s'énerver :) Bon alors le petit truc que j'ai trouvé c'est qu'on peut se passer de la condition if (!jazzFestivalTriee.ContainsKey(p.Nom)) , sans pour autant se faire jeter une exception à la figure. En fait il faut simplement passer par l'indexeur du hashtable / Dictionary<TKey, TValue> :

foreach (Personne p in jazzFestival)
{
jazzFestivalTriee[p.Nom] = p;
}

Et le résultat est identique.



Chouette non ? Et en plus on y gagne en perf (enfin on est dans l'ordre du chouïa :) Voici ce petit tableau récapitulatif :



































Dictionary<Tkey, Tvalue>



Hashtable


Avec condition if

1426



2522


Sans condition if

1262



2217


Gain observé (en %)

12,99524564



13,75732972


Quelques remarques : tout d'abord, sur quel code ont été faites les mesures :
List<Personne> listeAtrier = new List<Personne>();

for (int i = 0; i < 5300000; i++) // 5,3 millions
listeAtrier.Add(new Personne(i.ToString(), (i * 2).ToString(), new DateTime(1981, 11, 23)));

for (int i = 0; i < 1500000; i++) // 1,5 millions
listeAtrier.Add(new Personne(i.ToString(), (i * 2).ToString(), new DateTime(1981, 11, 23)));


Donc j'ai crée une liste de 'personne' 5,3 millions d'items et puis j'en ai ajouté encore 1,5 millions qui sont identiques à ce de la première (pour qu'il y est des doublons dans la liste). La suite du code n'a rien de surprenant :

Hashtable listeTriee = new Hashtable();
//Dictionary<string, Personne> listeTriee = new Dictionary<string, Personne>();

Stopwatch timer = new Stopwatch();
timer.Start();
foreach (Personne p in listeAtrier)
{
//if (!listeTriee.ContainsKey(p.Nom))
//listeTriee.Add(p);
listeTriee[p.Nom] = p;
}
timer.Stop();
Console.WriteLine(listeAtrier.Count);
Console.WriteLine(listeTriee.Count);
Console.WriteLine(timer.ElapsedMilliseconds);

Voilà, pour d'autres optimisations, vous pouvez aller ici.

lundi 16 février 2009

Snippets Visual Studio 2008

Ca fait un petit moment que je voulais le faire et c'est l'arrivée de C# 3 et des automatic properties qui m'y ont poussé. Les snippets. En effet, j'utilise pas mal les snippets (merci Ge-Off ;-)) et depuis c# 3 quand on fait un prop ou un propg on obtient ça :

public int MyProperty { get; set; }
Or ce n'est pas toujours ce qu'on veut. Ce qu'on veut c'est redéfinir le getter ou le setter donc ce qu'on veut c'est ça :

private int myVar;

public int MyProperty
{
get { return myVar; }
set { myVar = value; }
}
rien de bien sorcier mais à force... donc si comme moi, ces raccourcis vous manquent, rejoignez mon groupe Facebook téléchargez donc ces quelques petits fichiers xml qui vous rendront la vie meilleure :)

Installez-les dans le répertoire des snippets (par exemple : C:\Program Files\Microsoft Visual Studio 9.0\VC#\Snippets\1033\Visual C# pour VS 2008)


Et puis quelques uns que j'utilise assez souvent :

  • cr.snippet : Console.Read();
  • cwr.snippet : Console.WriteLine(); Console.Read();

samedi 14 février 2009

Retour des Techdays 2009 (1er jour)

L'ambiance y est toujours aussi bonne, la plénière toujours excellente. L'organisation était meilleure que l'année dernière (et j'étais sans doute moi-même mieux organisé que l'année dernière). Serait-ce dû à Microsoft Solver Foundation ? A priori je dirai que oui, j'y reviendrai.

Arrivée vers 8h15, je prends mon badge illico et patiente jusqu'à 9h pour entrer dans l'auditorium principal du Palais des Congrès. Ambiance bon enfant pour faire patienter, les speakers dessinent des ronds sur Paint 1.0 tournant sur Windows 3.0 pendant qu'un dessinateur dessine des croquis sur Surface. 20 ans de technologies se côtoient sur le podium parsemé de robots. Bref, un condensé de
Hi-Tech !

9h30 - début de la plénière Développeur

La plénière présente succinctement les sessions (destinées aux développeurs) qui se dérouleront tout au long des 3 jours. Au programme et dans le désordre :

  • Visual Studio 2010
  • Windows Azure
  • Microsoft Solver Foundation
  • Microsoft Surface
  • Windows 7

Visual Studio 2010 a été présenté comme le point de synchronisation chez Microsoft. Comme ils en ont prit l'habitude, il sortira conjointement avec le .NET Framework 4 ainsi que MS SQL Server (qui a des cycles de développement de plus en plus court !). Visual Studio 2010 (dixit Microsoft) c'est encore plus de productivité, une meilleure intégration des frameworks existants (WPF, Silverlight notamment), et enfin une gestion des tests facilitée : Plus de tests, toujours plus de tests ! (Il y a même un logiciel destiné aux tests fonctionnels qui interagit avec Team System).

Windows Azure. C'est la nouvelle "vision" de Microsoft. Pour résumer, ça va permettre aux développeurs de choisir quand faire du "software" et quand faire du "services" ; la fameuse vision "Software + Services" de Microsoft : Telle brique de l'application sera au sein de mon logiciel, telle autre sera consommé en tant que service etc.

L'exemple choisi était une galerie de photo exposée sur le web. 2 parties distinctes ; le client qui upload les photos sur un serveur web (Web Role Instance), qui les restitue. Une fonctionnalité de l'application consistait à générer des miniatures de ces photos haute-résolution. Mais où et comment sera gérée cette fonctionnalité ? Côté client ? Côté serveur ? Sur un serveur tiers ?

C'est exactement ce à quoi répond Azure (entre autre). En fonction des contraintes de l'application, de la disponibilité et de la charge du serveur, du nombre d'utilisateurs, on choisira "simplement " le meilleur compromis. Concrètement pour le développeur, Visual Studio sera interfacé avec Azure et on créera les types de projets qu'on souhaite et comment/où ils seront déployés. Dans l'exemple, en l'occurence la solution choisit était de développer un projet de type "service windows" (Worker Instance) hébergé sur un serveur tiers (pour ne pas grever les performances du serveur web), en créant un type particulier de projet Azure dans Visual Studio. Azure c'est le développement "In the Cloud".

Sinon Azure c’est également toute une plateforme applicative auxquels s’articulent des Services. Sql Data services, .NET Services, Live Services. Mais n’ayant assisté à d’autres sessions Azure, je ne pourrais en dire plus, mais c'est clairement l'avenir du développement chez Microsoft.

Microsoft Solver Foundation, MSF de son p'tit nom permet de résoudre un problème en tenant compte de plus ou moins nombreuses contraintes, En l'occurrence faire rentrer sur 3j plus de 300 sessions en fonction de la disponibilité des speakers, de la taille des salles, du nombre de préinscrits pour telle et telle session, de la chronologie (sessions d'introduction d'abord, puis session avancées ensuite) et j'en passe... La démo est bluffante puisqu'en 40 secondes à peine l'agenda était sorti. Concrètement ça c'est traduit par le fait que cette année, j'ai pu aller à toutes les sessions auxquelles j'avais prévu d'aller (contrairement à l'année dernière). Plus de renseignements ici et .

Microsoft Surface, la célèbre table était elle aussi de la partie durant la plénière. La démo présentée était en fait l'utilisation du SDK de Surface avec Visual Studio. C'est assez impressionnant. En quelques lignes de codes, (les même qu'avec une application WPF classique) on arrive à obtenir un résultat assez sympathique (support du Multitouch, zoom, manipulation des items...)

Enfin une évocation rapide du successeur de  Windows Vista, Windows 007. Là encore quelques features plutôt sympa était présentées, on l'a vu tourner sur un eeePC mais n'ayant assisté à aucune session sur Windows 7, je ne pourrai en dire plus. Une chose à retenir toutefois, c'est l'intérêt que montrent les utilisateurs pour ce nouvel OS, puisque la session sera reconduite également mercredi et jeudi.

11h Le nouveau CLR 4.0

C'est sur cette session que c'est finalement porté mon choix. Avec regret, presque. Il n'y a vraiment pas de quoi s'énerver avec cette nouvelle version du CLR. En effet, on notera la cohabitation entre la CLR 2 et la CLR 4 pour des raisons de rétro compatibilité.

13h Programmation dynamique

Je suis allé à cette session plus par curiosité qu'autre chose et à dire vrai, je n'ai vraiment pas été déçu. Je me doutais qu'il y serait question de la DLR (Dynamic Language Runtime) qui apparaîtra avec le Framework 4 mais finalement on ne l'a évoqué qu'à la fin.

La session montrait en fait que C#, depuis sa première version pouvait également générer du code dynamiquement en générant de l'IL grâce à l'api Emit (dans Reflection). Le problème qui résidait alors dans ces scénarios dynamiques était alors le nombre de ligne de codes qu'il fallait écrire et surtout qu'il fallait écrire l'IL. C'est là qu'intervient C# 4. Il simplifiera toute cette "plomberie" en quelques lignes de codes (mais j'y reviendrai plus tard).

De même grâce à un outil dont j'ignorais l'existence mais qui a l'air d'être une vraie mine d'informations et qui s'appelle SOS, on a pu inspecter ce que générait le compilateur lorsqu'on utilisait des types génériques. On a pu constater qu'en fait, le type n'était pas résolu à la compilation et donc qu'on avait à faire alors à du code dynamique (le raccourci est un peu rapide mais en gros c'est ça)

Les Expressions lambdas, introduit avec C#3 et Linq permettent également de jouer quelques scénarios dynamiques en récupérant un résultat en tant qu'expression, puis en compilant cette expression plus tard :

Expression<Func<double, double, double>> exp = (op1, op2) => op1 * op2;
Console.WriteLine(exp);    // Affiche (op1, op2) => op1 * op2;
var f = exp.Compile();     // L'expression n'est compilé qu'à ce
                           // moment là
double result = f(24, 9);  // Exécution du code compilé
Console.WriteLine(result); // Affiche 216;

Je tiens à signaler que cette session était vraiment d'une grande qualité tant par son contenu que par ses speakers !

14h30 Présentation de C# 4

Auditorium plein à craquer ou presque, c'était une session très attendue par les développeurs. Quid de cette nouvelle version. Et bien au menu des "grosses" nouveautés il y a :

  • 2 types ajoutés à la BCL (Base Class Library) : Tuple et BigInteger.
  • le mot clé dynamic.
  • les paramètres nommés et optionnels en C#

BigInteger : est un entier dont la précision n’est pas limitée. Ce type était implémenté dans certaines betas du .NET Framework 3.5 mais pour des raisons de performances, il a finalement été retiré.

Tuple : Ce type a été ajouté pour harmoniser et faciliter l’interopérabilité des langages du Framework. Le tuple est une structure générique de données qui peut contenir un ensemble de types différents : Tuple<T1, T2, T3, T4, T5, T6, T7, T8>

Evolutions des besoins, adaptation des langages

Ce n'est pas ce que j'ai retenu de la session. En effet, ce qui est apparu, c'est la direction dans laquelle vont les langages de développement Microsoft, y compris C#. Trois axes prédominent aujourd'hui les besoins des applications :

  • Applications concurrentielles (Multiplication des coeurs)
  • Langage déclaratif (On déclare ce qu'on veut obtenir) : F#
  • Dynamicité

Concurrence : Aujourd'hui le constat c'est qu'aujourd'hui tout est réalisable. Cependant, on dépense énormément de temps à créer/gérer le multithreading par exemple. Microsoft répond par un framework : ParallelFx. La gestion des threads est déléguée au Framework. Voici un exemple, avec PLinq (version "parallélisée" de Linq) qui illustre bien la simplicité de créer des threads :

var q_CustomersParis = from customers.AsParallel()
                      
where customers.City == "Paris"
                      
order by customers.Name
                      
select new {Name, FirstName};

A savoir, le nombre de threads, la priorité des threads est géré automatiquement par ParallelFx, prenant en compte les threads qu'on gère nous même.

Déclaratif : Pour le côté déclaratif, Microsoft a intégré F# parmis les langages "officiels" .NET. Je ne connais pas F# mais l'idée d'un langage déclaratif comme F# ou Lisp (dont les créateurs de F# se sont largement inspirés pour la syntaxe) s'illustre très bien dans Linq (une fois encore) Si on prend une requête, elle est très facile à lire : "A partir de la source customers où customer dont la propriété city est égal à Paris , ordonnéé par la propriété nom, tu les sélectionnes". Beaucoup plus facile que des boucles foreach imbriquées en C# classique (et encore, ici l'exemple est simpliste).

Dynamicité : En revanche, en ce qui concerne la dynamicité, .NET n'avait jusqu'ici pas ou peu de réponses. Par code dynamique il faut entendre "Code qui sera exécuté mais qui n'a pas été compilé". C'est chose faite avec la DLR ou Dynamic Language Runtime. Elle se situe au dessus de la CLR. J'imagine que c'est ce sur quoi les langages s'appuient mais en revanche le speaker n'en a pas dit plus. Ecrire du code dynamique en C# devient donc plus aisé.

Petite mise au point : C# restera un langage impératif (c'est à dire ni dynamique, ni fonctionnel) mais apporte ces facilités pour répondre à des besoins ponctuelles dans une application. C# ne deviendra pas un langage fonctionnel (puisqu'il y a déjà F#) ni un langage dynamique (il y a Iron Python et Iron Ruby). En revanche, comme avec VB.NET dont le "rapprochement" avec C# a été officialisé récemment, il y a fort à parier que lesgages s'inspireront les uns les autres.

Le futur de C# et de .NET

C# 4 et le .NET Framework 4 a presque été présenté comme une transition avec le C# 5 et le .NET Framework 5. Il n'y a donc pas d'évolutions majeures a priori et on pourra exploiter ces évolutions pleinement dans la version future de la plateforme.

16h MEF, Unity, IoC

Voici une très très belle session qui parle un petit peu d'architecture et particulièrement d'IoC (pour Inversion Of Control). Je ne connaissais que de nom ce principe d'architecture et ça m'a permit d'en découvrir l'intérêt. Relativement facile à mettre en place (en tout cas c'était vendu comme tel) quelques frameworks ont été cités (Spring.Net...) et c'est Unity qui a été présenté, Techdays oblige. C'est à tester absolument et c'est ici ! Comme le disais le speaker, facile à mettre en place... une fois qu'on a décortiqué le projet et identifier les dépendances existantes pour supprimer les dépendances superflues. MEF (Managed Extensibility Framework) est un framework déjà utilisé par Microsoft pour Visual Studio et Office et a pour objectif d'unifier la manière dont est appréhendée l'extensibilité d'applications (add-ins, plug-ins...). Il nous a été présenté également comme un Framework IoC mais orienté "externe" c'est à dire, tournée vers l'extensibilité contrairement à Unity qui est orienté "interne". Bref j'ai été enthousiasmé par cette session et je vais regarder ça d'un peu plus près.

17h30 Silverlight avancé

Autant le dire, j'ai été déçu par cette session... peut-être parce que j'en attendais beaucoup. Sujets trop disparates, trop de speakers (4)... bref je suis un peu resté sur ma fin. L'idée de cette session était de montrer comment ont été résolus des problèmes rencontrés avec  Silverlight.  Soit :

  • Quid du Deeplinking avec Silverlight ?
  • Le binding avec Silverlight
  • Le pattern utilisé avec Silverlight : MV + YS (Model View + Your Stuff)
  • Manipulation de bitmap avec Silverlight (présentation de QuakeLight)

Le deeplinking, c'est permettre à l'internaute d'utiliser les boutons "back et "forward" du navigateur. C'est également prendre en compte les robots des  moteurs de recherches. L'idée ici était d'utiliser ASP.NET MVC pour les moteurs de recherche et DataServices (anciennement Astoria) pour Silverlight. Si le navigateur supportait le javascript (donc si le navigateur n'est pas un moteur de recherche) Silverlight était chargé, sinon ce sont les "vues" asp.net qui sont affichées (pour que les robots puissent naviguer dedans).

Concernant le binding avec Silverlight, a été présenté rapidement le projet Silverlight Extensions qui permet de combler quelques manques (template selector entre autre). Une chose qui m'a surprise, c'est que dans la présentation, on a introduit du fonctionnel dans les converters alors que c'est déconseillé, dumoins en WPF.  Pas grand chose à dire sur cette partie.

Concernant le 3è thème abordé, le sujet était très intéressant mais malheureusement il n'y avait pas assez de temps pour le présenter. Sur la base des patterns existants MVC (Model View Controller) et MV-VM  (Model View ViewModel) plus spécifique à WPF, le but était de montrer comment s'organiser sur des gros projets Silverlight). On y a également retrouvé Unity.

Enfin Quakelight est une version de Quake portée sur Silverlight inspiré de la version portée sur Flash. La présentation fut extrêmement rapide et portait sur la manipulation bas niveau de bitmap.

Conclusion

Voilà ce que j'ai retenu des Techdays cette année. Petite précision : j'ai écrit ce post "à chaud" en sortant des techdays ou presque.  Il y a donc quelques manques (je ne parle pas des code contracts, ni de l'ouverture du compilateur C# pour les futures versions de c#  par exemple...) et sans doute quelques mauvaises interprétations de ma part.  Quoiqu'il en soit je ferai les updates qui vont bien.

dimanche 8 février 2009

Techdays 2009

Bon, je ne vais pas épiloguer sur les Techdays aller faire un petit tour sur le site officiel ou sur le blog  où est présenté largement l'événement. Je ne devais pas en être et bonne surprise, finalement j'ai pu me dégager une journée pour y participer ! Alors comme d'habitude, (enfin l'année dernière) voici mon agenda cette année :

Mardi 10 février :

  • Plénière développeur
  • Le nouveau CLR 4.0
  • Programmation dynamique
  • Présentation de C#4
  • MEF, Unity, IoC
  • Le développement avancé en Silverlight 2