Como paralelizar código no R

Computação paralela é um tema complexo e vasto, mas ainda pouco conhecido. Graças ao esforço da comunidade de R já foram criados diversos pacotes que tornam a paralelização de códigos muito mais fácil e segura. Neste texto abordamos alguns exemplos práticos e introdutórios para demonstrar os ganhos dessa abordagem.

O objetivo é apresentar instrumentos e demonstrar o ganho imediato de paralelizar o seu código de R. Para detalhes mais técnicos e uma discussão mais aprofundada do tema recomendamos o capítulo 4 do livro Data Science for Economists and Other Animals de McDermott & Rubin.

Os pacotes utilizados podem ser instalados/carregados conforme o código abaixo:

if(!require("pacman")) install.packages("pacman")
pacman::p_load(
"tictoc",
"purrr",
"future",
"parallelly",
"furrr"
)

Exemplo: raiz quadrada super lenta

Nosso exemplo prático vai ser o cálculo de uma raiz quadrada realizado de forma super lenta. Para isso criaremos a função abaixo que calcula a raiz quadrada de um número mas em uma versão "lenta", ou seja, obriga o computador a esperar 2 segundos antes de fazer qualquer coisa. Isso servirá apenas para fins didáticos de demonstração da paralelização que faremos à seguir:

raiz_lenta <- function(x) {
Sys.sleep(2)
x_sqrt <- sqrt(x)
return(x_sqrt)
}

Execução serial

Agora vamos usar essa função criada iterando uma sequência de números de forma serial, ou seja, os cálculos não serão executados em paralelo. Utilizaremos aqui abordagem do pacote purrr do tidyverse para iterações no R. A função map_dbl() retorna um vetor numérico com os resultados dos cálculos. Para contabilizar o tempo de execução do código utilizaremos o pacote tictoc:


tictoc::tic()
exemplo_serial <- purrr::map_dbl(1:10, raiz_lenta)
tictoc::toc(log = TRUE)

## 20.25 sec elapsed

Conforme esperado, a iteração durou 20 segundos para ser concluída, pois forçamos uma parada de 2 segundos na função raiz_lenta() a cada iteração serial. Isso significa que podemos facilmente acelerar esse código se rodarmos a iteração em paralelo.

Execução paralela

Para rodar o código em paralelo primeiro é importante saber que o procedimento depende do número de núcleos de processador disponíveis no computador. Uma maneira fácil de obter essa informação no R é através do código abaixo:


parallelly::availableCores()

## system
## 4

Em segundo lugar, é preciso configurar o R para executar o código em paralelo, e é neste ponto que o pacote future, criado pelo Henrik Bengtsson, entra em cena.

Neste exemplo sugerimos a utilização do pacote future pois o mesmo oferece uma sintaxe simples e intuitiva para quem já está acostumado com o tidyverse. Graças a este pacote, o único procedimento que devemos fazer é especificar uma estratégia, ou seja, executar o código de maneira serial, paralela, etc., através da função plan(). Como queremos executar em paralelo, especificamos a estratégia multisession() que cria várias sessões do R no computador para executar o código.

Geralmente recomenda-se alocar para utilização em paralelo a quantidade total de núcleos de processador deixando um livre para outras tarefas do computador - como, por exemplo, navegação na internet, editor de texto, etc. -, mas aqui utilizaremos 2 núcleos apenas. Para outras opções consulte a documentação da função multisession().


future::plan(
strategy = future::multisession(workers = 2)
)

Realizada a configuração do R para execução em paralelo, vamos voltar ao nosso exemplo de iteração do cálculo de raiz quadrada. Executaremos novamente essa iteração, mas dessa vez em paralelo. Para isso faremos uma modificação marginal no código que é utilizar uma variante da função purrr::map_dbl() específica para iteração em paralelo, que é a função furrr::future_map_dbl().


tictoc::tic()
exemplo_paralelo <- furrr::future_map_dbl(1:10, raiz_lenta)
tictoc::toc(log = TRUE)

## 10.58 sec elapsed

Um resultado empolgante: o tempo de execução caiu pela metade! Isso tudo com pouquíssimas alterações em nosso código, bastou configurar o R (através do future::plan) e alterar a função de iteração (furrr::future_map_dbl). Um ganho de performance fenomenal, não?!

Vamos verificar se o output é idêntico nos dois casos (serial e paralelo):


all.equal(exemplo_serial, exemplo_paralelo)

## [1] TRUE

Agora você já pode iniciar um olhar mais crítico sobre os seus códigos para identificar pontos de melhoria de performance.

 

_______________________
(*) Para entender mais sobre a linguagem R e suas ferramentas, confira nosso Curso de Introdução ao R para análise de dados.

Compartilhe esse artigo

Facebook
Twitter
LinkedIn
WhatsApp
Telegram
Email
Print

Comente o que achou desse artigo

Outros artigos relacionados

Resultado IPCA-15 - Novembro/2024

A Análise Macro apresenta os resultados do IPCA-15 de Novembro de 2024, com gráficos elaborados em Python para coleta, tratamento e visualização de dados. Todo o conteúdo, disponível exclusivamente no Clube AM, foi desenvolvido com base nos métodos ensinados nos cursos da Análise Macro, permitindo aos assinantes acesso aos códigos e replicação das análises.

Resultado PNADc Trimestral - 3° Trimestre/2024

A Análise Macro apresenta os resultados da PNADc Trimestral do 3º trimestre de 2024, com gráficos elaborados em Python para coleta, tratamento e visualização de dados. Todo o conteúdo, disponível exclusivamente no Clube AM, foi desenvolvido com base nos métodos ensinados nos cursos da Análise Macro, permitindo aos assinantes acesso aos códigos e replicação das análises.

Análise exploratória para modelagem preditiva no Python

Antes de desenvolver bons modelos preditivos é necessário organizar e conhecer muito bem os dados. Neste artigo, damos algumas dicas de recursos, como gráficos, análises e estatísticas, que podem ser usados para melhorar o entendimento sobre os dados usando Python.

Boletim AM

Receba diretamente em seu e-mail gratuitamente nossas promoções especiais e conteúdos exclusivos sobre Análise de Dados!

Boletim AM

Receba diretamente em seu e-mail gratuitamente nossas promoções especiais e conteúdos exclusivos sobre Análise de Dados!

como podemos ajudar?

Preencha os seus dados abaixo e fale conosco no WhatsApp

Boletim AM

Preencha o formulário abaixo para receber nossos boletins semanais diretamente em seu e-mail.