GPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge
Upcoming SlideShare
Loading in...5
×
 

GPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge

on

  • 2,034 views

 

Statistics

Views

Total Views
2,034
Views on SlideShare
1,784
Embed Views
250

Actions

Likes
1
Downloads
16
Comments
0

2 Embeds 250

http://glaforge.appspot.com 248
http://a0.twimg.com 2

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    GPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge GPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge Presentation Transcript

    • PrettyTime et GParsGuillaume LaforgeGroovy Project ManagerSpringSource, a division of VMwareTwitter: @glaforgeBlog: http://glaforge.appspot.comGoogle+: http://gplus.to/glaforge
    • Guillaume Laforge• Groovy Project Manager chez VMware • Initiateur du framework Grails • Créateur du toolkit Gaelyk pour App Engine• Co-auteur de Groovy in Action• Membre des CastCodeurs• Suivez-moi... ou pas :-) • Blog: http://glaforge.appspot.com • Twitter: @glaforge • Google+: http://gplus.to/glaforge @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 2
    • Nananère !
    • PrettyTimeOu comment écrire des dates relatives lisibles
    • http://ocpsoft.com/prettytime/
    • http://ocpsoft.com/prettytime/ 2 days ago right now 3 months from now in 3 minutes
    • PrettyTime• Représenter des dates «relatives» – par rapport à «maintenant»• On souhaite savoir... – il y a combien de temps que... – dans combien de temps...• Plutôt que de connaître la date absolue et précise – du coup, meilleure notion de la fraîcheur dʼune information – surtout valable pour des laps de temps courts @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 10
    • PrettyTime• Librairie Open Source : LGPL v3• Version 1.0.7, disponible dans Maven Central• Léger : 58 ko• Développé par Lincoln III Baxter / OCPSoft – Senior Software Engineer chez JBoss / RedHat• Customisable – y-compris les langues supportées : • français, anglais, espagnol, allemand, italien, hollandais, portugais, bulgare, chinois, croate, estonien, hongrois, norvégien, polonais, roumain, slovénien, turque, vietnamien @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 11
    • Dépendance• Si vous nʼavez pas de chance... <dependency> <groupId>com.ocpsoft</groupId> <artifactId>ocpsoft-pretty-time</artifactId> <version>1.0.7</version> </dependency>• Si vous avez de la chance... – dans un script Groovy @Grab(com.ocpsoft:ocpsoft-pretty-time:1.0.7) import com.ocpsoft.pretty.time.PrettyTime – ou avec Gradle dependencies { compile com.ocpsoft:ocpsoft-pretty-time:1.0.7 } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 12
    • Vie de cochon... cʼest bien ma veine... C’est bien mais ch’préfère utiliser @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 13
    • Allez, des morceaux de code ! @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 14
    • Comment lʼutiliser ?@Grab("com.ocpsoft:ocpsoft‐pretty‐time:1.0.7")import com.ocpsoft.pretty.time.PrettyTime  def p = new PrettyTime()println p.format(new Date()) // à linstant @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 15
    • Comment lʼutiliser ? @Grab("com.ocpsoft:ocpsoft‐pretty‐time:1.0.7") import com.ocpsoft.pretty.time.PrettyTime   long seconds = 1000 long minutes =   60 * seconds long hours   =   60 * minutes long days    =   24 * hours long weeks   =    7 * days long months  =   31 * days long years   =  365 * days  long now = new Date().time def p = new PrettyTime() [     [  0,              "à linstant"       ],     [ 10 * minutes,    "dans 10 minutes"   ],     [ ‐3 * hours,      "il y a 3 heures"   ],     [  9 * days,       "dans 1 semaine"    ],     [ ‐2 * weeks,      "il y a 2 semaines" ],     [  3 * months,     "dans 3 mois"       ],     [‐15 * years,      "il y a 1 décénie"  ],     [111 * years,      "dans 1 siècle"     ] ].each { diff, text ‐>     assert p.format(new Date(now + diff)) == text } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
    • Comment lʼutiliser ? @Grab("com.ocpsoft:ocpsoft‐pretty‐time:1.0.7") import com.ocpsoft.pretty.time.PrettyTime   long seconds = 1000 long minutes =   60 * seconds long hours   =   60 * minutes long days    =   24 * hours long weeks   =    7 * days long months  =   31 * days long years   =  365 * days  long now = new Date().time def p = new PrettyTime() [     [  0,              "à linstant"       ],     [ 10 * minutes,    "dans 10 minutes"   ],     [ ‐3 * hours,      "il y a 3 heures"   ],     [  9 * days,       "dans 1 semaine"    ],     [ ‐2 * weeks,      "il y a 2 semaines" ],     [  3 * months,     "dans 3 mois"       ],     [‐15 * years,      "il y a 1 décénie"  ],     [111 * years,      "dans 1 siècle"     ] ].each { diff, text ‐>     assert p.format(new Date(now + diff)) == text } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
    • Intégration• PrettyTime sʼutilise facilement nʼimporte où... – utilisez simplement lʼAPI directement• Mais PrettyTime propose une intégration JSF <h:outputText value="#{exampleBean.futureDate}"> <f:converter converterId="com.ocpsoft.PrettyTimeConverter"/> </h:outputText>• Il existe également un plugin Grails <prettytime:display date="${someDate}" /> @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 17
    • GParsOu comment tirer partide vos multiples processeurs multicores
    • Loi de Moore @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 21
    • Le constat...• Les architectures de nos ordinateurs évoluent – simple vers multi-processeurs (cʼest pas nouveau) – simple vers multi-coeurs• On atteints les limites de la loi de Moore• Nos applications devront évoluer pour sʼadapter – pour tirer parti des multiples coeurs et processeurs• Groovy se devait de proposer des solutions pour la programmation concurrente et parallèle @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 22
    • Lʼâge de pierre• Il est difficile de bien utiliser – les threads – synchronize – wait / notify / notifyAll• On obtient rapidement – des dead-locks et live-locks – des race conditions – des starvation• Problème de gestion dʼaccès à de la mémoire partagée @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 23
    • Les programmes multithreadésd’aujourd’hui avec threads et locksmarchent par accident :-)
    • passage deimmuabilité messages
    • http://gpars.codehaus.org
    • GPars• GPars est Open Source : Apache Software Licence 2• Version actuelle : 0.12• Dépendances – jsr166y et extra166y (1.7.0) – groovy, si vous lʼutilisez• GPars est bundlé avec la distribution de Groovy – mais peut-être téléchargé individuellement• Et surtout, GPars a une API Java ! – pas seulement pour Groovy @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 27
    • Un large panel de solutions• actors• fork / join• map / filter / reduce avec parallel arrays• executors (java.util.concurrent)• dataflow (operators et streams)• agents• STM (Software Transactional Memory)• CSP (Communicating Sequential Processes) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 28
    • Fonctions parallèles pour les collections @Grab(org.codehaus.gpars:gpars:0.12) import static groovyx.gpars.GParsPool.withPool def nums = 1..100000 withPool(5) { def squares = nums. collectParallel { it ** 2 }. grepParallel { it % 7 == it % 5 }. grepParallel { it % 3 == 0 } println squares[0..3] + "..." + squares[-3..-1] assert squares[0..3] == [36, 144, 1089, 1296] } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 29
    • Fonctions parallèles pour les collections @Grab(org.codehaus.gpars:gpars:0.12) import static groovyx.gpars.GParsPool.withPool def nums = 1..100000 withPool(5) { def squares = nums.makeTransparent(). collect { it ** 2 }. grep { it % 7 == it % 5 }. grep { it % 3 == 0 } println squares[0..3] + "..." + squares[-3..-1] assert squares[0..3] == [36, 144, 1089, 1296] } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 30
    • Fonctions parallèles pour les collections @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 31
    • Map / filter / reduce• Concept popularisé par le papier de Google – approche utilisée initialement pour la création de lʼindex du moteur de recherche import static groovyx.gpars.GParsPool.withPool withPool(5) { def nums = 1..100000 println nums.parallel. map { it ** 2 }. filter { it % 7 == it % 5 }. filter { it % 3 == 0 }. reduce { a, b -> a + b } // sum() } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 32
    • Map / filter / reduce• Opérations sur les «parallel arrays» (JSR-266) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 33
    • Fork / join• Principe du « diviser pour mieux régner » – découper un problème en plus petits morceaux• Problématiques récursives – merge sort, quick sort – traverse de graphe – recherche sur un système de fichiers @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 34
    • Fork / join import static groovyx.gpars.GParsPool.runForkJoin import static groovyx.gpars.GParsPool.withPool withPool { runForkJoin(new File("./src")) { currentDir -> long count = 0 currentDir.eachFile { if (it.isDirectory()) { println "Forking a thread for $it" forkOffChild it } else { count++ } } return count + childrenResults.sum(0) } } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 35
    • Fork / join vs map / filter / reduce ? @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 36
    • Actors• Concept popularisé par Erlang – repris aussi par Scala• Echange asynchrone de messages – au travers dʼune boîte aux lettres – coordination explicite• Pas dʼétat partagé @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 37
    • Actors import static groovyx.gpars.actor.Actors.actor def decryptor = actor { loop { react { message -> if (message instanceof String) reply message.reverse() else stop() } } } def console = actor { decryptor.send lellarap si yvoorG react { println Decrypted message: + it decryptor.send false } } [decryptor, console]*.join() @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 38
    • Actors import static groovyx.gpars.actor.Actors.actor def decryptor = actor { loop { react { message -> Verbes : if (message instanceof String) start() reply message.reverse() stop() else stop() act() } send(msg) } sendAndWait(msg) } actor << msg loop { } def console = actor { react { msg -> } decryptor.send lellarap si yvoorG react(timeout) { msg -> } react { msg.reply(msg2) println Decrypted message: + it receive() decryptor.send false join() } } [decryptor, console]*.join() @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 38
    • Dataflow• Approche moins connue mais avec nombreux avantages – pas de « race conditions » – pas de « live locks » – des « deadlocks » déterministes• Tâches, utilisant des variables assignables une seule fois – possibilité dʼutiliser des «flux» pour des données en continu• Le dataflow gère le graphe des tâches à résoudre @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 39
    • Dataflowimport groovyx.gpars.dataflow.DataFlowsimport static groovyx.gpars.dataflow.DataFlow.tasknew DataFlows().with { task { a = 10 } task { b = 5 } task { x = a - b } task { y = a + b } task { result = x * y } assert 50 == result} @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 40
    • Agents• En anglais dans le texte (documentation de GPars) – a thread-safe non-blocking shared mutable state wrappers – thread-safe : utilisable par des threads concurrents – non-blocking : pas de «synchronized» et dʼattente pour accéder à la resource – shared mutable state : donnée partagée qui peut changer de valeur (non immuable) – wrapper : lʼagent est un wrapper autour de la donnée à manipuler• Concept inspiré par les « agents » de Clojure @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 41
    • Agents import groovyx.gpars.agent.Agent def jugMembers = new Agent<List<String>>([Me]) jugMembers.send { it << James} def t1 = Thread.start { jugMembers.send { it << Joe } } def t2 = Thread.start { jugMembers << { it << Dave } jugMembers { it << Alice } } [t1, t2]*.join() println jugMembers.val jugMembers.valAsync { println "Current members: $it" } jugMembers.await() @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 42
    • Agents import groovyx.gpars.agent.Agent def jugMembers = new Agent<List<String>>([Me]) jugMembers.send { it << James} def t1 = Thread.start { jugMembers.send { it << Joe } } def t2 = Thread.start { jugMembers << { it << Dave } jugMembers { it << Alice } } [t1, t2]*.join() println jugMembers.val jugMembers.valAsync { println "Current members: $it" } jugMembers.await() @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 42
    • Agents import groovyx.gpars.agent.Agent def jugMembers = new Agent<List<String>>([Me]) jugMembers.send { it << James} def t1 = Thread.start { jugMembers.send { it << Joe } } def t2 = Thread.start { jugMembers << { it << Dave } jugMembers { it << Alice } } [t1, t2]*.join() println jugMembers.val jugMembers.valAsync { println "Current members: $it" } jugMembers.await() @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 42
    • Oui mais en Java alors ? @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 43
    • Comment choisir ?• Données – linéaires : collections parallèles – récursives : fork / join• Tâches – linéaires : fonctions asynchrones, CSP, dataflow, actors – recursives : fork / join – sur les mêmes données : agents, STM• Flux de données – régulier (même structure, même origine) : opérateurs dataflow – irrégulier (structures / origines différentes) : actors @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 44
    • Comment choisir ? mon problème données tâches flux mêmes linéaires récursives linéaires récursives régulier irrégulier donnéescollections agents fonctions async dataflowparallèles fork / join fork / join actors STM CSP stream fork / join dataflow @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 45
    • Thank you! e L aforg pment aume vy Develo Guill Groo m Hea d of g mail.co aforge@ mail: gl glaforge e E @ o /glaforg T witter : http://gplus.t Go ogle+: @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 46
    • Q&A — Got questions, Really?
    • Image credits• Ecureuil: http://cheznectarine.c.h.pic.centerblog.net/a314fd6e.jpg• Didier: http://gallery.paperjam.lu/d/1316-2/IMG_3030.jpg• Cochon: http://chezginette.net.over-blog.net/pages/Connaitre_les_morceaux_de_viande-3441365.html• Petit cochon: http://www.renders-graphiques.fr/image/upload/normal/7471_render_cochon.png• Dépendance: http://www.komrod.com/wp-content/uploads/2011/02/internet-addiction-jeu-video-dependance1.jpg• Hexadecimal time: http://en.wikipedia.org/wiki/Hexadecimal_time• CPU: http://img.alibaba.com/wsphoto/v0/335090360/intel-xeon-3040-CPU-for-server.jpg• CPUs: http://blog.ldlc.com/wp-content/uploads/2010/02/comparatif-cpu.jpg• Loi de Moore: http://fr.wikipedia.org/wiki/Fichier:Loi_de_Moore.png• Biface: http://upload.wikimedia.org/wikipedia/commons/7/75/Biface.jpg• Car crash: http://www.twikeodream.com/images/2063798sub2.jpg• Mail box: http://images.neutralexistence.com/junkmail.jpg• Statue: http://www.linternaute.com/savoir/magazine/photo/tresors-de-kaboul/image/statue-228201.jpg• Diviser pour mieux régner: http://29.media.tumblr.com/tumblr_lppxk3FPiM1r0hgevo1_500.png• Grumpy 2: http://grumpy.division-par-zero.fr/wp-content/images/grumpy.jpg• @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 48