Your SlideShare is downloading. ×
  • Like
GPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Now you can save presentations on your phone or tablet

Available for both IPhone and Android

Text the download link to your phone

Standard text messaging rates apply

GPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge

  • 1,768 views
Published

 

Published in Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
1,768
On SlideShare
0
From Embeds
0
Number of Embeds
2

Actions

Shares
Downloads
16
Comments
0
Likes
1

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. PrettyTime et GParsGuillaume LaforgeGroovy Project ManagerSpringSource, a division of VMwareTwitter: @glaforgeBlog: http://glaforge.appspot.comGoogle+: http://gplus.to/glaforge
  • 2. 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
  • 3. Nananère !
  • 4. PrettyTimeOu comment écrire des dates relatives lisibles
  • 5. http://ocpsoft.com/prettytime/
  • 6. http://ocpsoft.com/prettytime/ 2 days ago right now 3 months from now in 3 minutes
  • 7. 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
  • 8. 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
  • 9. 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
  • 10. 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
  • 11. Allez, des morceaux de code ! @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 14
  • 12. 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
  • 13. 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
  • 14. 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
  • 15. 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
  • 16. GParsOu comment tirer partide vos multiples processeurs multicores
  • 17. Loi de Moore @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 21
  • 18. 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
  • 19. 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
  • 20. Les programmes multithreadésd’aujourd’hui avec threads et locksmarchent par accident :-)
  • 21. passage deimmuabilité messages
  • 22. http://gpars.codehaus.org
  • 23. 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
  • 24. 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
  • 25. 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
  • 26. 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
  • 27. Fonctions parallèles pour les collections @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 31
  • 28. 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
  • 29. Map / filter / reduce• Opérations sur les «parallel arrays» (JSR-266) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 33
  • 30. 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
  • 31. 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
  • 32. Fork / join vs map / filter / reduce ? @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 36
  • 33. 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
  • 34. 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
  • 35. 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
  • 36. 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
  • 37. 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
  • 38. 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
  • 39. 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
  • 40. 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
  • 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
  • 42. Oui mais en Java alors ? @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 43
  • 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
  • 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
  • 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
  • 46. Q&A — Got questions, Really?
  • 47. 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