Executando verificação de segurança...
5

Julia é rápida e posso provar!

Antes de ler o artigo: Meu nome é Lucas Valentim. Tenho 21 anos. Estou indo para o meu quarto período na faculdade de ciência da computação. Estou fazendo uma iniciação científica que utiliza Julia para otimização. Nunca tinha mexido com essa linguagem, dessa forma, meu orientador, para estudos, me deu o livro: “Julia High Performance” - Avik Sengupta. O texto abaixo é um resumo do seu primeiro capítulo. Pretendo, se a faculdade não me consumir antes, trazer o resumo de todo o livro. Obrigado!

Introdução:

De diversas formas, a história das linguagens de programação foi orientada pela necessidade de mexer com números e resolver problemas da área da ciência da computação. Portanto, Julia não é exceção.

Julia combina a facilidade de sintaxe que uma linguagem dinâmica proporciona (maior exemplo seria o Python) e a performance de uma linguagem estática e compilada(maior exemplo seria o C).

Esse resumo está dividido em 3 tópicos:

Julia - dinâmica e rápida
Desenhada para ser rápida
Quão rápido Julia pode ser?

Julia - dinâmica e rápida

Existe o problema das duas linguagens que resumidamente abrange o seguinte contexto: Se você quer produtividade utilize linguagens dinâmicas, mas se você quer velocidade e otimização utilize linguagens estaticamente tipadas. É muito difícil, principalmente em grandes projetos, se beneficiar das duas partes. Porém, a criação de Julia a torna a primeira linguagem moderna a tentar fortemente resolver esse problema, unindo os dois mundos.

Surpreendentemente, Julia possui um modelo de desempenho muito simples. Assim, escrever código rápido nessa linguagem se torna entender elementos chave da arquitetura de um computador e como seu compilador interage com eles.

Dessa forma, Julia abrange os dois lados do espectro da computação. Em uma mão, funciona muito bem na utilização em Raspberry Pi, por exemplo, o que cria uma ótima ambientação para ensinar programação. Em outra mão, Julia tem sido utilizada para executar, em larga escala, aplicações de machine learning em um dos maiores supercomputadores do mundo. Outro exemplo seria “The Celest” que utilizou Julia Build e o Atlas the Sky, onde os cálculos foram executados a uma impressionante taxa de 1,5 petaflops(1 petaflop é 10^15 operações de ponto flutuante por segundo), utilizando 1,3 milhão de threads. Se tornando a primeira linguagem de programação dinâmica a quebrar a barreira de petaflop.

Desenhada para ser rápida.

Quando os criadores de Julia lançaram a linguagem para o mundo, eles fizeram uma postagem em seu blog denominada “Why We Created Julia”. O seguinte trecho foi retirado dessa postagem e dizia o seguinte:

“Queremos uma linguagem de programação que seja de código aberto, com uma licença liberal. Desejamos a velocidade do C com a dinâmica do Ruby. Queremos uma linguagem homoicônica, com macros verdadeiros como o Lisp, mas com uma notação matemática clara e familiar, como o Matlab. Queremos algo tão utilizável para programação geral quanto o Python, tão fácil para estatísticas quanto o R, tão natural para processamento de strings quanto o Perl, tão poderoso para álgebra linear quanto o Matlab, tão bom em unir programas quanto o shell. Algo que seja extremamente simples de aprender, mas que mantenha os hackers mais sérios satisfeitos. Queremos que seja interativo e compilado.”

Link da postagem: https://julialang.org/blog/2012/02/why-we-created-julia/

Uma grande parte da biblioteca padrão de Julia, incluindo a mais básica operação de baixo nível, está escrita em Julia por si só. Como por exemplo a função de soma.

Além disso, os três elementos que permitem a essência da eficiência de Julia são: Compilador JIT (Just in time) de alta performance, LLVM para gerar código de máquina e um sistema de tipo que permite código expressivo.

Porém, somente adicionar LLVM em Julia não necessariamente a torna mais rápida. A forma com que Julia trata “types"! é o segredo da sua eficiência, pois sua sintaxe e semântica foram cuidadosamente desenhadas para permitir seu alto desempenho. Há muito sobre o que falar do cuidado com Julia com seus tipos, mas o capítulo atual irá se contentar somente com essa afirmação.

Porém, é possível dar um exemplo: O compilador de Julia compila códigos diferentes para a mesma função, dependendo do tipo que esta recebeu. Podemos considerar, por exemplo, a função que calcula a potenciação. Essa pode receber dois tipos diferentes, um inteiro ou um ponto flutuante. Porém, dependendo do input, a definição matemática se altera. Pois então, Julia irá compilar duas versões diferentes de código, uma para inteiros e outra para ponto flutuante . Dessa forma, inserirá a chamada apropriada, no código, durante a compilação do programa. Isso significa que, em tempo de execução, sem nenhuma verificação de tipo, o código será executado no CPU.

Uma curiosidade é que Julia permite analisar o código nativo de uma função, nesse sentido podemos perceber na prática o exemplo acima:

julia> @code_native 3^2
        .text
        .file   "^"
        .globl  "julia_^_75"                    # -- Begin function julia_^_75
        .p2align        4, 0x90
        .type   "julia_^_75",@function
"julia_^_75":                           # @"julia_^_75"
; ┌ @ intfuncs.jl:310 within `^`
        .cfi_startproc
# %bb.0:                                # %top
        push    rbp
        .cfi_def_cfa_offset 16
        .cfi_offset rbp, -16
        mov     rbp, rsp
        .cfi_def_cfa_register rbp
        sub     rsp, 32
        movabs  rax, offset j_power_by_squaring_77
        call    rax
        add     rsp, 32
        pop     rbp
        ret
.Lfunc_end0:
        .size   "julia_^_75", .Lfunc_end0-"julia_^_75"
        .cfi_endproc
; └
                                        # -- End function
        .section        ".note.GNU-stack","",@progbits
julia> @code_native 4.1^2
        .text
        .file   "^"
        .section        .rodata.cst8,"aM",@progbits,8
        .p2align        3                               # -- Begin function julia_^_127
.LCPI0_0:
        .quad   0x3ff0000000000000              # double 1
        .text
        .globl  "julia_^_127"
        .p2align        4, 0x90
        .type   "julia_^_127",@function
"julia_^_127":                          # @"julia_^_127"
; ┌ @ math.jl:1246 within `^`
        .cfi_startproc
# %bb.0:                                # %top
        push    rbp
        .cfi_def_cfa_offset 16
        .cfi_offset rbp, -16
        mov     rbp, rsp
        .cfi_def_cfa_register rbp
        sub     rsp, 32
; │ @ math.jl:1247 within `^`
; │┌ @ promotion.jl:521 within `==`
        test    rdx, rdx
; │└
        je      .LBB0_1
# %bb.3:                                # %L4
; │ @ math.jl:1248 within `^`
        movabs  rax, offset j_pow_body_129
        call    rax
        jmp     .LBB0_2
.LBB0_1:
        movabs  rax, offset .LCPI0_0
        vmovsd  xmm0, qword ptr [rax]           # xmm0 = mem[0],zero
.LBB0_2:                                # %common.ret
; │ @ math.jl within `^`
        add     rsp, 32
        pop     rbp
        ret
.Lfunc_end0:
        .size   "julia_^_127", .Lfunc_end0-"julia_^_127"
        .cfi_endproc
; └
                                        # -- End function
        .section        ".note.GNU-stack","",@progbits

Percebe-se então que para a mesma função, porém tipos diferentes, temos compilações também distintas.

Quão rápido Julia pode ser?

O exemplo do livro é mais visual e, também, bastante simples. Porém a comparação é válida. Dessa forma, com o objetivo de não estender mais o assunto, deixo com os que chegaram até aqui e, portanto, os mais curiosos, o link de um artigo interessante mostrando a performance de Julia em comparação com as outras linguagens:

https://discourse.julialang.org/t/comparing-python-julia-and-c/17019

Carregando publicação patrocinada...
5

Julia é boa, é rápida e tem várias carcaterísticas interessanmtes. Curiosamente as pessoas não gostam porque nãoõ é tão fácil quanto Python ou outras linguagens até mais difíceis.

Julia não inventou nada, não é milagrosa. Ela essencialmente tem uma tipagem estática, sem isso não poderia ser rápida. Quando ela tem uma característica realmente dinâmica, ela não consegue ser rápida, porque isso seria impossível.

Ela tem otimnizações interessantes, que junto com a tipagem bem definina e impondo algumas restrições, que consegue otimizar algumas coisas mais difíceis em linguagens mais abertas. Curiosamente ela pode ter mais vantagens em cima de uma linguagem como C que a tipagem é muito aberta, do que uma linguagem que seja um pouco mais restrita.

Os resultados não mentem, mas quem usa mais profundamente sabe que não é assim para tudo. Se a pessoa começar abusar da tipagem ela vai degradando. Tem situações que ela tem resultados bem piores.

Essa comparações são furadas, só pegam o que interessa. Eu posso te garantir que Julia não consegue ser mais rápida que C++ naquele extao exemplo, pegaram uma implmentaçaõ ruim de C++ para comparar com uma boa de Julia. E os trouxam acceitam como verdade. O negócio é tão mal feito que quase perdeu para Pythin, uma das linguagens mais lentas do mercado. Tanto que uma mexidinha simples deu resultado bem melhor, outras poderiam ser feitas. E teve quem consegiu mais com Python que Julia, também é algo bem furado. Os testes seguintes mostram como dá para fazer melhor, e eu vi que tem espaço para melhorar bem mais o C++.

Faz sentido?


Farei algo que muitos pedem para aprender a programar corretamente, gratuitamente (não vendo nada, é retribuição na minha aposentadoria) (links aqui).

1

Faz sentido. Só lembrando que minha publicação é um resumo do livro que estou lendo; nada escrito está embasado em o que eu acho, mas o que os prórprios fundadores de julia disseram! Obrigado pelo comentário.

1

Eu dei uma boa estudada na linguagem há alguns anos, eles são bons de marketing, sabem usar as palavras para indicar algo que no fundo não é bem aquilo. Não tira o mérito da linguagem, continua sendo bem interessante, mas eles fazem parecer que é algo mais milagroso que é.

Eles usam muito o JITter para mostrar que são dinâmicos. Não é uma completa mentira, mas as outras linmguagems não consideram assim.

3

Vou falar sobre a minha ótica de Data Scientist:

Já vi um pouco sobre Julia e me passou a impressão de ser uma linguagem realmente muito interessante. O problema, parafraseando um podcast que eu ouvi, é que 3 anos atrás Julia era uma linguagem com muito potencial, e hoje continua sendo uma linguagem com muito potencial, ou seja, apesar de ter potencial, ele não foi desenvolvido.

O próprio Yann LeCun (para aqueles que não conhecem, é O principal nome ao se falar de Deep Learning, hoje em dia foi contratado pela Meta) já fez declarações falando de Julia e de GoLang pra área de dados, que seria um ganho muito grande (ganho de performance e diminuição de energia). O MIT também desenvolve projetos complexos em Julia.

Ao meu ver o maior problema é que Julia chegou (ou as pessoas souberam que chegou) quando Python já estava no hype pra Data Science, e é muito difícil derrubar um hegemon (ainda mais quando boa parte dessa hegemonia deve-se a própria comunidade que decidiu abraçar aquilo) quando você é a alternativa dele. Até porque já existe muita coisa desenvolvida e muito madura pra Python, a principal lib usada para Machine Learning tradicional (scikit-learn) está em Python, as 2 principais libs para Deep Learning (Tensorflow e Pytorch) estão em Python (apesar do Tensorflow também existir para outras langs, é um projeto Python First do Google). Então acaba que as pessoas pensam "porque eu vou trocar pra outra lang que faz exatamente a mesma coisa, só que com ecossistema menos maduro?"

Não acho necessariamente que o Python seja melhor que Julia (nem vou ficar sendo infantil falando que lang A é melhor que lang B), mas o Python chegou primeiro e o principal: Python é mais popular (o que não tem nenhuma relação com ser melhor)

Em suma, acho Julia uma linguagem muito legal, sempre ouvi falar muito bem. Se eu tivesse algum tempo sobrando (o que não tenho rs) eu iria dar uma estudada na linguagem.

4

Eu sou estatístico e usuário de longa data de R e Python. Hoje estou fazendo doutorado em estatística e tenho usado o Julia na minha pesquisa. Eu acompanho o Julia há muito tempo e lembro que quando eu conheci o projeto lá por volta de 2014 eu achei que o projeto era muito ambicioso e não ia conseguir entregar o que prometia. Aliás, naquela época nem mesmo o R (ou Python) eram tão usados para análise de dados. O pessoal do Analytics nas empresas usava mesmo o SAS.

Mas agora mais recentemente o que eu posso dizer do Julia é que ele realmente entregou o que prometeu. Vejam, se você pensar em um analista que trabalha com inferência Bayesiana, com deep learning, com machine learning e análise de dados em geral ele vai ter que recorrer ao Stan, Jags, ao Tensorflow, ao Pytorch e etc. Todas esses frameworks e bibliotecas são implementados em C++ por questão de desempenho, e não em Python como disse o colega acima. O próprio numpy já não é mais Python no fim das contas. Assim que você tem um gargalo você tem que recorrer ao C ou ao C++ no Python e no R. No R em especial existe até pacotes para facilitar o uso do C++ dentro do R, como o Rcpp e o RcppArmadillo.

Agora em Julia não! Em Julia se você quer trabalhar com inferência Bayesiana você tem o Turing.jl que é o equivalente ao Stan no ecossistema Julia. O Turing.jl é somente Julia, não tem nem C e nem C++, é basicamente Julia. No caso do deep learning você tem o Flux.jl, também inteiramente escrito em Julia. Se você quer trabalhar com o chip gráfico, com as GPUs usando o CUDA.jl é banal e você consegue ganhos de performance enormes com uma pequena modificação no código. Pelo menos para um cientista de dados realmente o Julia resolve o problema das duas linguagens.

Há ainda diversas outras vantagens que fazem o Julia atrativo e ele vem ganhando popularidade na academia mas vou falar sobre isso em outro post.

2

Entendi garaujo. Estou dando meus primeiros passos ainda na linguagem. Espero que um dia Julia atinja o seu potencial. De qualquer maneira, acredito ser uma boa linguagem, principalmente para o meio acadêmico. Tentarei de alguma forma contribuir um pouco para a comunidade, principalmente brasileira, que possui tão pouco conteúdo. Obrigado por comentar!