Processamento paralelo em R com furrr

Aproveitando o furrr para fluxos de trabalho organizados e paralelos

Aprenda a usar o pacote furrr para paralelizar seus fluxos de trabalho purrr no R. Este tutorial aborda a configuração de planos futuros, o uso de funções future_map e as melhores práticas para o processamento paralelo eficiente de dados, incluindo uma comparação entre os fluxos de trabalho padrão purrr e furrr paralelizados.

Programação
Autor
Afiliação
Data de Publicação

10 de fevereiro de 2024

Data de Modificação

29 de abril de 2025

Palavras-chave

Tutorial furrr, processamento paralelo em R, tidyverse paralelização, furrr em R, future_map R, purrr vs furrr

Introdução

O pacote furrr amplia a funcionalidade do purrr, permitindo o processamento paralelo usando futuros. Isso significa que você pode transformar facilmente seus fluxos de trabalho sequenciais e compatíveis com tidyverse em fluxos paralelizados, acelerando seus cálculos sem sacrificar a legibilidade do código. Neste tutorial, você aprenderá como configurar o furrr, definir planos futuros para execução paralela e aplicar funções como future_map() para processar dados simultaneamente.



Instalando e carregando furrr

Primeiro, certifique-se de que você tem furrr instalado. Você pode instalá-lo a partir do CRAN, se necessário:

#| label: install-furrr
install.packages("furrr")

# Carregue o pacote furrr
library(furrr)

Definindo um plano futuro

Antes de usar as funções furrr, você precisa definir um plano future que determine como as tarefas serão distribuídas. Por exemplo, para executar tarefas em paralelo usando várias sessões:

#| label: set-future-plan
library(future)
# Definir o plano para usar multissessão
1plan(multisession, workers = availableCores() - 1)
1
Defina o plano para usar várias sessões, com o número de trabalhadores igual aos núcleos disponíveis menos um. Isso é adequado para a maioria das máquinas locais.

Usando funções furrr

A função principal fornecida pelo furrr é future_map(), que funciona de maneira semelhante a purrr::map(), mas executa operações em paralelo.

Exemplo: mapeamento paralelo

#| label: future-map-example
# Crie um vetor simples
numbers <- 1:10

# Calcule o quadrado de cada número em paralelo
squared_numbers <- future_map(numbers, ~ .x^2)
print(squared_numbers)

Exemplo: retornando tipos específicos com future_map_dbl()

Se você espera uma saída numérica, pode usar future_map_dbl() para retornar um vetor duplo:

#| label: future-map-dbl-example
# Calcule raízes quadradas em paralelo, garantindo uma saída de vetor numérico
sqrt_values <- future_map_dbl(numbers, ~ sqrt(.x))
print(sqrt_values)

Comparando os fluxos de trabalho purrr e furrr

Para ilustrar os benefícios de desempenho do processamento paralelo, vamos comparar um fluxo de trabalho purrr padrão com sua versão paralelizada usando furrr. Nos exemplos abaixo, simularemos uma tarefa computacionalmente intensiva usando Sys.sleep().

Fluxo de trabalho padrão do purrr

#| label: purrr-workflow
library(purrr)

# Defina uma função computacionalmente intensiva
# Simule uma tarefa demorada
heavy_computation <- function(x) {
  Sys.sleep(6)  
  x^2
}

# Execução sequencial usando purrr::map
seq_time <- system.time({
  seq_result <- map(1:10, heavy_computation)
})
print("Sequential purrr execution time:")
print(seq_time)

Saída: tempo de execução sequencial do purrr

   user  system elapsed 
  0.188   0.000  60.226 

Fluxo de trabalho paralelizado com furrr

#| label: furrr-workflow
library(furrr)
# Definir o plano para usar multissessão
plan(multisession, workers = availableCores() - 1) 

# Execução paralela usando furrr::future_map
par_time <- system.time({
  par_result <- future_map(1:10, heavy_computation)
})
print("Parallel furrr execution time:")
print(par_time)

Saída: tempo de execução paralela do furrr

   user  system elapsed 
  4.973   0.083  27.949 
Nota

Ao comparar o desempenho, é importante se concentrar no tempo decorrido (tempo real) em vez de apenas no tempo de CPU do usuário.

Em nossos benchmarks, o fluxo de trabalho sequencial usando purrr levou cerca de 60,226 segundos de tempo decorrido, enquanto a versão paralelizada com furrr foi concluída em apenas 27,949 segundos.

Embora a abordagem furrr tenha apresentado maior tempo de CPU do usuário devido ao uso simultâneo de vários núcleos, a principal conclusão é que o tempo de espera geral experimentado pelo usuário foi quase reduzido pela metade.

Isso demonstra claramente a vantagem do processamento paralelo para reduzir o tempo total de execução de tarefas que consomem muitos recursos.

Práticas recomendadas

  • Defina um plano futuro adequado:
    Escolha um plano future que corresponda aos recursos do seu sistema (por exemplo, multisession para processamento paralelo local).

  • Monitore o uso de recursos:
    O processamento paralelo pode consumir recursos significativos. Ajuste o número de trabalhadores usando availableCores() para garantir que seu sistema permaneça responsivo.

  • Teste sequencialmente primeiro:
    Antes de paralelizar seu código com furrr, teste-o sequencialmente usando purrr para garantir a correção. Em seguida, mude para furrr para obter melhorias de desempenho.

  • Tratamento de erros:
    Considere usar wrappers de tratamento de erros (por exemplo, safely() ou possibly()) do purrr em conjunto com furrr para gerenciar erros potenciais em tarefas paralelas.

Conclusão

furrr oferece uma maneira perfeita de atualizar seus fluxos de trabalho tidyverse com recursos de processamento paralelo. Ao definir um plano futuro e usar funções como future_map() e future_map_dbl(), você pode melhorar significativamente o desempenho do seu código R sem sacrificar a legibilidade. A comparação entre os fluxos de trabalho purrr e furrr ilustra os ganhos de velocidade potenciais que podem ser obtidos por meio da paralelização.

Leitura adicional

Boa programação e aproveite o furrr para acelerar seus fluxos de trabalho R!

Explore mais artigos

Nota

Aqui estão mais artigos da mesma categoria para ajudá-lo a se aprofundar no tópico.

placeholder

placeholder
Nenhum item correspondente
De volta ao topo

Reuso

Citação

BibTeX
@online{kassambara2024,
  author = {Kassambara, Alboukadel},
  title = {Processamento paralelo em R com furrr},
  date = {2024-02-10},
  url = {https://www.datanovia.com/pt/learn/programming/r/advanced/furrr-for-parallel-processing.html},
  langid = {pt}
}
Por favor, cite este trabalho como:
Kassambara, Alboukadel. 2024. “Processamento paralelo em R com furrr.” February 10, 2024. https://www.datanovia.com/pt/learn/programming/r/advanced/furrr-for-parallel-processing.html.