Golo, en attendant les classes
Pendant la pĂ©riode estivale, le Doc ne reste pas inactif et Golo âaugmenteâ gentiment ses capacitĂ©s, notamment avec les Collection literals et les Structures (pas encore disponibles sur le repository officiel). Ces quelques nouveautĂ©s de juillet mâont poussĂ© Ă faire un petit exercice : en attendant dâavoir des classes, quelle est la meilleure solutions pour les simuler ?
Alors, jusquâici, mon mot-clĂ© prĂ©fĂ©rĂ© dans Golo est DynamicObject
, mĂȘme si le Doc me dĂ©conseille (pour des raisons dâoptimisation) de lâutiliser, jâen use et en abuse. Je commencerait donc par lui.
Objectif
Lâobjectif premier, câest de simuler une bonne vieille classe âĂ la Javaâ comme celle ci :
public class Human {
public String firstName;
public String lastName;
public Human(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String hello() {
return "hello " + this.firstName + " " + this.lastName;
}
}
Pour cela, je vais vous proposer 3 solutions :
- avec un DynamicObject et une fonction (qui sert de constructeur)
- avec une HashMap (nous verrons ainsi la nouvelle notation des âCollection literalsâ) et une fonction
- avec une Structure et une fonction
DynamicObject par lâexemple
Le code sera celui-ci :
function DynamicHuman = |firstName, lastName| {
return DynamicObject()
:firstName(firstName)
:lastName(lastName)
:define("hello",|this|->
"hello %s %s":format(this:firstName(), this:lastName())
)
}
Nous lâutiliserons comme ceci :
let bob = DynamicHuman("Bob", "Morane")
println(bob:hello())
Pour plus dâinformations sur les DynamicObjects, câest par-ici http://golo-lang.org/documentation/next/# _dynamic_objects.
Une âpseudo-classeâ avec une HashMap
Le code sera celui-ci :
function FakeHuman = |firstName, lastName| {
let h = map[
["firstName", firstName],
["lastName", lastName]
]
h:put("hello", -> "hello %s %s":format(h:get("firstName"), h:get("lastName")))
return h
}
Remarque : vous notez quâun des Ă©lĂ©ments de la HashMap est une fonction (lambada)
Nous lâutiliserons comme ceci :
let bob = FakeHuman("Bob", "Morane")
println(bob:get("hello"):invokeWithArguments())
Remarque : la notation est moins sexy quâavec un DynamicObject, mais pourquoi pas ⊠A priori câest plus optimisĂ© quâun DynamicObject.
Struct / la nouveauté de la semaine
Lundi, apparaĂźt un thread Ă propos dâune nouvelle fonctionnalitĂ© : struct
https://sourceforge.net/p/golo-lang/discussion/users/thread/84255b46/. Et cette phrase : âIndeed, it compiles to JVM classes, and as such, they are way faster than dynamic objects.â mâinterpelle sur 2 points :
- faster than dynamic objects
- it compiles to JVM classes
Donc plus rapide, ok ça se tente. Golo compile ça en classe, ça devrait pouvoir dire que lâon peut utiliser augment
pour coller des mĂ©thodes aux structures. Jâai donc fait ceci (et ça marche) :
module bench
struct human = {firstName, lastName}
function StructHuman = |firstName, lastName| {
return human(firstName, lastName)
}
augment bench.types.human {
function hello = |this| ->
"hello %s %s":format(this:firstName(), this:lastName())
}
Et nous lâutiliserons comme ceci :
let bob = StructHuman("Bob", "Morane")
println(bob:hello())
Oui, et alors ?
Finalement que faut-il utiliser ? (rappelez-vous, je suis trĂšs fan des DynamicObjects).
Donc, nouvel exercice : Benchmark, je vais âinstancierâ et appeler la mĂ©thode hello()
100 000 fois pour chacune des solutions et calculer la durĂ©e dans chacun des cas. Jâobtiens ceci :
duration for 100000 DynamicHumans : 12206 ms
duration for 100000 FakeHumans : 867 ms
duration for 100000 StructHumans : 233 ms
⊠Yâa pas photo, struct
wins! ⊠Je vais aller casser mes codes ;)
42. ;)
Vous trouverez le code de benchmark ici : https://gist.github.com/k33g/6018173
Tweet