Lo + Leído
Eventos destacados
Artículos para tus primeros pasos
Si estás empezando a introducirte en el mundo de Groovy y Grails, no te pierdas nuestros artículos básicos:
- Introducción a Groovy, parte 1 (Andrés Almiray)
- Introducción a Groovy, parte 2 (Andrés Almiray)
- Introducción a Groovy, parte 3 (Andrés Almiray)
- Introducción a Grails (Material Seminario ImaginaWorks)
Los protagonistas te cuentan de qué van los proyectos más importantes del mundo Groovy:
Groovy: primeros pasos
Benchmark de Groovy, Java, C++, etc.
idecasso - viernes 05/12/2008http://blog.dhananjaynene.com/2008/07/performance-comparison-c-java-python-ruby-jython-jruby-groovy/
En los resultados, aparece Groovy como el lenguaje mas lento, pero como siempre, baje el código y me di cuenta habian omitido todos los tipos de datos.
Por lo cual procedi a cambiar todos los def por el tipo de dato correspondiente y especificando que los enteros son int (0i, 5i,7i) y long donde tocaba, disminuyendo considerablemente el tiempo de ejecución.
En mi humilde Pentium 4 a 2.4 Ghz(no es dual Core), con 1.5 Gb de ram y Xubuntu 8.04, con sun jdk 1.6_07 y Groovy 1.5.6, para mas informacion es una Dell Optiplex GX260, en ella me dio los siguientes resultados:
Original 2178.45578797 microseconds (Interpretado)
Original 2130.03473054 microseconds (Compilado)
Corregido: 193.14217284 microseconds(Interpretedo)
Corregido: 191.73054723 microseconds(Compilado)
Pero luego pense en probar dejando los def y unicamente corrigiendo los enteros(int y long en la variable y 7i,5i,10i,7l) y los resultados fueron los siguientes:
Corregido int: 193.1019066 microseconds(Interpretedo)
Corregido int: 196.70635049 microseconds(Compilado)
El chiste del benchmark es que implementan el mismo algoritmo en diferentes lenguajes, siendo el resultado de Java "Puro":
Java: 2809 nanoseconds.
Lo que noto es que es un algoritmo que hace varios operaciones que no se implementarian directamente en Groovy, pero podemos observar que se corrijio bastante el desempeño cuando se dejo de usar def para los numeros enteros, tal vez este es el mayor cuello de botella de Groovy.
Y de hecho me parece que se acerca muchisimo a los demás lenguajes que siguen a C++ y Java, comparando los resultados del blogger contra los de mi máquina, tal vez en la suya Groovy quedaria en tercer lugar. Y yo no use Groovy 1.6, que si lo usaron en el benchmark.
Lo que aprendi es que hay que tener cuidado al usar def, evitar sobre todo al trabajar con numeros.
Este el código original:
class Chain
{
def size
def first
def init(siz)
{
def last
size = siz
for(def i = 0 ; i < siz ; i++)
{
def current = new Person()
current.count = i
if (i == 0) first = current
if (last != null)
{
last.next = current
}
current.prev = last
last = current
}
first.prev = last
last.next = first
}
def kill(nth)
{
def current = first
def shout = 1
while(current.next != current)
{
shout = current.shout(shout,nth)
current = current.next
}
first = current
}
}
class Person
{
def count
def prev
def next
def shout(shout,deadif)
{
if (shout < deadif)
{
return (shout + 1)
}
prev.next = next
next.prev = prev
return 1
}
}
def main(args)
{
println "Starting"
def ITER = 100000
def start = System.nanoTime()
for(def i = 0 ; i < ITER ; i++)
{
def chain = new Chain()
chain.init(40)
chain.kill(3)
}
def end = System.nanoTime()
println "Total time = " + ((end - start)/(ITER * 1000)) + " microseconds"
}
def ITER = 100000
def start = System.nanoTime()
for(def i = 0 ; i < ITER ; i++)
{
def chain = new Chain()
chain.init(40)
chain.kill(3)
}
def end = System.nanoTime()
println "Time per iteration = " + ((end - start)/(ITER * 1000)) + " microseconds"
Código sin def:
class Chain
{
int size
Person first
Person init(int siz)
{
Person last
size = siz
for(int i = 0i ; i < siz ; i++)
{
Person current = new Person()
current.count = i
if (i == 0i) first = current
if (last != null)
{
last.next = current
}
current.prev = last
last = current
}
first.prev = last
last.next = first
}
Person kill(int nth)
{
Person current = first
int shout = 1i
while(current.next != current)
{
shout = current.shout(shout,nth)
current = current.next
}
first = current
}
}
class Person
{
def count
Person prev
Person next
def shout(shout,deadif)
{
if (shout < deadif)
{
return (shout + 1i)
}
prev.next = next
next.prev = prev
return 1i
}
}
def main(args)
{
println "Starting"
long ITER = 100000l
long start = System.nanoTime()
for(int i = 0i ; i < ITER ; i++)
{
def chain = new Chain()
chain.init(40i)
chain.kill(3i)
}
long end = System.nanoTime()
println "Total time = " + ((end - start)/(ITER * 1000i)) + " microseconds"
}
int ITER = 100000l
long start = System.nanoTime()
for(int i = 0i; i < ITER ; i++)
{
Chain chain = new Chain()
chain.init(4i)
chain.kill(3i)
}
long end = System.nanoTime()
println "Time per iteration = " + ((end - start)/(ITER * 1000i)) + " microseconds"
Código con int y long corregidos únicamente, lo demás usa def:
class Chain
{
int size
def first
def init(int siz)
{
def last
size = siz
for(int i = 0i ; i < siz ; i++)
{
def current = new Person()
current.count = i
if (i == 0i) first = current
if (last != null)
{
last.next = current
}
current.prev = last
last = current
}
first.prev = last
last.next = first
}
def kill(int nth)
{
def current = first
int shout = 1i
while(current.next != current)
{
shout = current.shout(shout,nth)
current = current.next
}
first = current
}
}
class Person
{
int count
def prev
def next
int shout(shout,deadif)
{
if (shout < deadif)
{
return (shout + 1i)
}
prev.next = next
next.prev = prev
return 1i
}
}
def main(args)
{
println "Starting"
long ITER = 100000l
long start = System.nanoTime()
for(int i = 0i ; i < ITER ; i++)
{
def chain = new Chain()
chain.init(40i)
chain.kill(3i)
}
long end = System.nanoTime()
println "Total time = " + ((end - start)/(ITER * 1000i)) + " microseconds"
}
int ITER = 100000l
long start = System.nanoTime()
for(int i = 0i; i < ITER ; i++)
{
def chain = new Chain()
chain.init(4i)
chain.kill(3i)
}
long end = System.nanoTime()
println "Time per iteration = " + ((end - start)/(ITER * 1000i)) + " microseconds"
Re: Benchmark de Groovy, Java, C++, etc.
idecasso - viernes 05/12/2008Revisando otra vez el benchmark, me parecio que si verificaba con el profiler de Netbeans podria identificar los cuellos de botella, de hecho encontre que el 40% del tiempo de ejecución se iba en llamados a get y set, cosa que me parecio extraña por que no deberian tardar tanto, pero en fin, es un punto a tener en cuenta.
Probe poniendo como public todas los atributos de person y las llamadas a get y set bajaron a 36%, pero seria cosa de checar en donde mas habria que mover para obtener mejores tiempos.
Más que nada este asunto me interesa para poder saber como obtener mejor rendimiento en Groovy, que evitar o usar poco, y si mi aplicacion corre lenta por que es eso.
Aunque como dije antes, este es un algoritmo que se implementaria en Java y no en Groovy, por que el conjunto de datos es muy grande.
Un momento...
Re: Benchmark de Groovy, Java, C++, etc.
idecasso - viernes 05/12/2008Revisando otra vez el benchmark, me parecio que si verificaba con el profiler de Netbeans podria identificar los cuellos de botella, de hecho encontre que el 40% del tiempo de ejecución se iba en llamados a get y set, cosa que me parecio extraña por que no deberian tardar tanto, pero en fin, es un punto a tener en cuenta.
Probe poniendo como public todas los atributos de person y las llamadas a get y set bajaron a 36%, pero seria cosa de checar en donde mas habria que mover para obtener mejores tiempos.
Más que nada este asunto me interesa para poder saber como obtener mejor rendimiento en Groovy, que evitar o usar poco, y si mi aplicacion corre lenta por que es eso.
Aunque como dije antes, este es un algoritmo que se implementaria en Java y no en Groovy, por que el conjunto de datos es muy grande.