Comparativa entre Julia, Python y R

La discusión sobre que lenguaje es el mejor para analizar datos puede llevarnos a conversaciones mas apasionadas que por temas como religión o política. Pero como Data-Scientist debemos enfocarnos en la evidencia empírica, las dimensiones con las que se podrían comparar son muchas: Comunidad, Performance, Editores, Gestor de Paquetes, Encapsulación de Código, etc… He evaluado varias de esas dimensiones y me cuesta decir cual es el mejor, algunos ganan en una otros en otra.

De todas las dimensiones, creo que hay 3 que hacen que un lenguaje de Análisis de Datos sea efectivo y el resto vendrán gracias a sus comunidades:
1) Existencia de una consola REPL, para así poder hacer pruebas.
2) Performance, por que si es lento, no podremos ejecutar nada.
3) Numero de Lineas para ejecutar, debido a que la prueba y error son los padres de la ciencia y cada experimento no puede tomar mucho tiempo.

Hay mas de tres lenguaje que cumple estas condiciones, como por ejemplo Ruby o Kotlin, pero nos enfocaremos en Python, R y Julia.

Python es un lenguaje multi-proposito orientado a objetos sobre el cual se han desarrollado paquetes para analizar datos como: pandas para tablas, scikit para Machine Learning y Numpy para matrices entre otros. su principal fortaleza es que como cualquier desarrollo se puede realizar en Python, facilita mucho integrar modelos en aplicaciones productivas.
R es un lenguaje funcional inventado para analizar datos, su principal estructura de datos son los DataFrames (tablas en memoria) y todo el lenguaje gira en torno a estas, a pesar de que R está enfocado a manipular tablas, gracias a su tremenda comunidad hoy en día se pueden hacer cosas completamente distintas e inesperadas de este como paginas web (en shiny) o APIs REST (plumber).
Julia por ultimo es otro lenguaje funcional muy nuevo, similar a R pero que no gira tan en torno a los DataFrames, su foco es ser rápido y distribuido, logrando un performance cercano al de C++, lo interesante es que mientras que las librerías eficientes de R y Python están programadas en otro lenguaje, Julia está principalmente escrito en Julia.

Los tres lenguajes anteriores son de alto nivel y tienen una consola REPL, por lo que a travez de 4 experimentos nos enfocaremos en las dimensiones 2) Performance y 3) Numero de lineas, por otro lado, dado que Julia es muy nuevo, tendremos los resultados de Julia actual y los de 6 meses atrás.

Experimento 1

Agregación sobre un DataFrame de 10 millones de registro, algunos lenguajes tienen mas de una librería para realizar esto, por lo que habrá mas de un resultado para cada uno.
En el siguiente gráfico vemos los tiempos para distintas librerías para ejecutar la misma agregación, donde:
data.table Es una librería para manipular tablas programada en C y enfocada principalmente en se rápida.
data.table + setkey los data.tables permiten crear indices, en este caso se creo un indice sobre la columna que se agregó.
DataFrames Es una de las librerías para manipular tablas en Julia.
JuliaDB Es una de las librerías para manipular tablas en Julia.
pandas Es la libreria para manipular tablas en Python, está basada en Numpy.
Queryverse Es una de las librerías para manipular tablas en Julia y tiene como objetivo imitar a tidyverse
tidyverse en verdad dplyr, el cual debido a su fácil notación, es la librería más popular para manipular tablas en R.

BarPlot de Tiempos en ejecutar

Claramente Julia no es el mas rápido, lo fue python que en el ultimo tiempo ha optimizado mucho pandas, pero si se puede destacar que en los últimos 6 meses ha mejorado mucho, alcanzando a los data.tables (data.tables + setkey considera solo el tiempo de agregación, no de crear el indice,por eso no puede considerarse ganador), cabe destacar que como Julia esta escrito en Julia, estas agregaciones se pueden programaren en un loop sin perder velocidad, a continuación en la sección de los códigos mostrare al final un ejemplo.

Los códigos para realizar cada uno de estas agregaciones es el siguiente:

data.table
dt[,list(valor = mean(valor)),by='categoria']
data.table + setkey
setkey(dt,categoria)
dt[,list(valor = mean(valor)),by='categoria']

DataFrames
aggregate(datos,:categoria,[mean])
ó by(datos,:categoria,x->(promedio = mean(x.valor)))
JuliaDB
JuliaDB.groupby(mean, indexed, :categoria, select =:valor)
pandas
datos.groupby(['categoria']).aggregate(np.mean)
Queryverse
datos |> @groupby(_.categoria) |> @map({categoria = key(_),promedio = mean(_.valor)}) |> DataFrame
tidyverse
datos %>% group_by(categoria) %>% summarise(valor = mean(valor))
Julia usando un Loop
results = []
for slice in groupby(datos,:categoria)
push!(results,(promedio = slice.categoria[1], valor = mean(slice.valor)))
end
DataFrame(results)

Todos son similar en largo, pero la escritura de Queryverse y tidyverse son los mas claros y flexibles, por otro el último ejemplo conjulia, tiene el performance de DataFrames, pero con la máxima flexibilidad, no así en eficiencia en el numero de lineas.

Experimento 2

Recursividad ,en particular series de fibonacci programadas en una función recursiva. una función recursiva es aquella que se llama a si misma varias veces para obtener un resultado, por lo que este exterimento medirá la eficiencia en código explicito, sin librerías.

En particular calcularemos Fibonacci(100), lo que nos obliga a llamar a la funcion 100 veces.

Todos los codigos son muy similares, por lo que solo pondré el codigo en python:
def fico(n,contador = 2, ant = 1, antant = 0):
if(n <= 1): return n if(n == contador): return ant + antant else: return fico(n,contador+1,ant + antant,ant)

Donde no son tan similares es el tiempo deje ejecución, a continuación los tiempo ej ejecutar la función para cada lenguaje en 2 fechasdistintas. Donde el claro perdedor es python del 2020/08/01 que correspondía a python 3.7

Ahora si vemos los resultados en escala logaritmica (log10), vemos que los 3 lenguajes han mejorado en los ultimos 6 meses y Julia es el claro ganador por mas de 2
ordenes de magnitud, por otro lado python 3.8 mejoró mucho con respecto a la versión anterior, logrando quedar a la par con R.

Francamente los tiempos para cada lenguaje fueron chicos, por lo que solo recomendaría Julia si en tu modelo hay que llamar mucho a alguna función hecha por ti, por ejemplo en Optimización utilizando el método del gradiente.

Experimento 3

Performance sobre Matrices

Los tres lenguajes son muy potentes en manejo de matrices, se pueden realizar muchas operaciones sobre matrices, pero escogí la descomposición en valores propios para realizar la prueba, esta es una operación relativamente pesada.

BarPlot de tiempos en calcular valores propios

Vemos que Julia es el más rápido, pero está muy cercano a R, por otro lado Python se escapa.

Por otro lado, la notación para los 3 casos es muy similar, pero la pondré de tomos modos.
R
mat = matrix(runif(1000*1000),nrow=1000)
svd(mat)

Julia
mat = rand(1000,1000)
svd(mat)

Python es un poco distinto por ser orientado a objetos
mat = np.random.rand(1000,1000)
np.linalg.svd(mat)

Experimento 4

Tiempo en modificar los elementos de una matriz dentro de un loop.

En este caso en un loop, llenaremos la matriz anterior con mat[i,j] = i + j, los tiempos quedan reflejados en el siguiente grafico:

Python es lejos el más lento, aunque ha mejorado en pyton 3.8, por otro lado dado que los objetos de R son inmutables, esperaba peores resultados.

Nuevamente los codigos son similares, pero quiero compartir una mención honrosa en python que permite iterar sobre 2 variables con un for:
import itertools
for i,j in itertools.product(range(1000),range(1000)):
mat[i,j] = i+j

Nota al Pie

Hice este análisis por que recordé que la ultima vez que intenté usar Julia, fue muy molesto el que los import de librerías tomaban mucho tiempo, esto mejoró, pero aun toman mucho, en especial en librerías grandes como Queryverse, de todos modos es un proyecto interesante.

Por otro lado, en general los lenguajes se parecen, pero creo que donde hay mas diferencia es en la orientación a objetos de python, que queda muy manifiesta en como se manipulan los DataFrames de Pandas.

Por último, aunque las diferencias en performance parezcan grandes, de todos modos al comparar con Excel, las 3 alternativas son rápidas y eficientes.

Saludos!

Print Friendly, PDF & Email