O outro lado do Ruby
Depois de explorarmos as características, recursos e vantagens do Ruby, é hora de discutir um pouco sobre seus pontos negativos!
Desempenho:
Comparado a linguagens de baixo nível como C++ ou Go, o Ruby pode ser mais lento em termos de velocidade de execução bruta. Isso pode ser uma preocupação para aplicativos que exigem alta performance.
Podemos utilizar a gem benchmark para medir o desempenho de diferentes partes do seu código em Ruby. Aqui está um exemplo simples de como você pode usar o benchmark para medir o tempo de execução de uma função:
require 'benchmark'
# Defina a função que você deseja testar
def minha_funcao
resultado = 0
1000000.times do
resultado += 1
end
return resultado
end
# Use o método benchmark para medir o tempo de execução da função
tempo = Benchmark.realtime do
minha_funcao
end
puts "Tempo de execução: #{tempo.round(4)} segundos"
Definimos uma função simples chamada minha_funcao que simplesmente soma 1 ao resultado um milhão de vezes.
Usamos o Benchmark.realtime para medir o tempo de execução da função. Imprimimos o tempo de execução resultante.
Simultaneidade e Paralelismo:
A implementação padrão do Ruby (MRI - Matz's Ruby Interpreter) tem limitações no tratamento de simultaneidade e paralelismo. Embora existam alternativas como JRuby e Rubinius que melhoram nessa área, ainda não são tão eficazes quanto linguagens projetadas com a simultaneidade em mente.
Simultaneidade: Refere-se à execução concorrente de várias tarefas em um único núcleo de CPU. Em Ruby, você pode usar threads para criar tarefas simultâneas.
Paralelismo:Refere-se à execução de várias tarefas ao mesmo tempo em diferentes núcleos de CPU. Em Ruby, isso é limitado devido ao GIL (Global Interpreter Lock), mas você ainda pode alcançar algum paralelismo em operações de E/S intensivas, como solicitações de rede
# Importa a biblioteca necessária
require 'net/http'
# Define uma lista de URLs para fazer solicitações simultâneas
urls = ['https://www.example.com', 'https://www.google.com', 'https://www.github.com']
# Define uma função para fazer uma solicitação HTTP e imprimir o status da resposta
def fazer_solicitacao(url)
uri = URI(url)
response = Net::HTTP.get_response(uri)
puts "URL: #{url}, Status: #{response.code}"
end
# Cria uma thread para cada URL na lista
threads = urls.map do |url|
Thread.new { fazer_solicitacao(url) }
end
# Aguarda todas as threads terminarem
threads.each(&:join)
Importamos a biblioteca net/http para fazer solicitações HTTP.
Definimos uma lista de URLs para fazer solicitações simultâneas.
Criamos uma função fazer_solicitacao que faz uma solicitação HTTP para uma URL e imprime o status da resposta.
Para cada URL na lista, criamos uma nova thread que chama a função fazer_solicitacao com essa URL.>Aguardamos todas as threads terminarem usando o método join.
Isso demonstra simultaneidade, pois várias solicitações HTTP são feitas simultaneamente em threads separadas, permitindo que o programa execute várias tarefas ao mesmo tempo em um único núcleo de CPU.
Uso de Memória:
O Ruby pode consumir muita memória, o que pode não ser ideal para projetos com restrições de memória ou aplicativos de grande escala.
Para analisarmos o consumo de memoria com ruby, podemos utilizar o exemplo abaixo, onde conseguimos ver a quantidade de memoria usada.
# Defina uma função para criar um grande array de strings
def criar_array_grande
array_grande = []
1000000.times do |i|
array_grande << "String #{i}"
end
return array_grande
end
# Chame a função para criar o array grande
array = criar_array_grande
# Imprima a quantidade de memória usada pelo programa
puts "Memória utilizada pelo programa: #{`ps -o rss= -p #{Process.pid}`.to_i} KB"
A função criar_array_grande cria um grande array de strings, contendo um milhão de elementos, onde cada elemento é uma string contendo o texto "String" seguido pelo número do índice.
Depois que o array é criado, usamos a sintaxe `` para executar um comando do sistema operacional que nos dá a quantidade de memória usada pelo processo Ruby.
Finalmente, imprimimos a quantidade de memória usada pelo programa.
Agora se compararmos com o go, utilizando a mesma logica, porem com o script abaixo:
package main
import (
"fmt"
"os"
"runtime"
)
// Função para criar uma grande fatia de strings
func criarSliceGrande() []string {
var sliceGrande []string
for i := 0; i < 1000000; i++ {
sliceGrande = append(sliceGrande, fmt.Sprintf("String %d", i))
}
return sliceGrande
}
func main() {
// Obtém estatísticas de memória
var m runtime.MemStats
runtime.ReadMemStats(&m)
// Imprime a quantidade de memória usada pelo programa
fmt.Printf("Memória utilizada pelo programa: %d KB\n", m.Alloc/1024)
// Força uma pausa para permitir que você veja o uso de memória antes de sair
fmt.Println("Pressione Enter para sair...")
fmt.Scanln()
// Garante que o programa termine com um status de saída zero
os.Exit(0)
}
Bloqueio Global de Intérprete (GIL):
O GIL no MRI pode limitar a utilização total de processadores multi-core, afetando o desempenho em aplicações fortemente simultâneas.
Curva de Aprendizado para Aplicações Complexas:
Embora o Ruby seja conhecido por sua sintaxe elegante, aplicativos complexos podem exigir um profundo conhecimento dos recursos e padrões de design avançados, o que pode resultar em uma curva de aprendizado mais íngreme.
Disponibilidade de Bibliotecas e Ferramentas:
Embora o ecossistema do Ruby seja robusto, pode não ser tão abrangente quanto o de outras linguagens, especialmente em nichos ou domínios especializados.
Suporte Limitado ao Desenvolvimento Móvel:
O Ruby não é amplamente utilizado para o desenvolvimento de aplicativos móveis, o que pode exigir a busca por outras linguagens ou frameworks para esses projetos.
Implantação e Hospedagem:
A configuração de um ambiente Ruby pode ser mais complexa em comparação com linguagens com procedimentos de implantação mais padronizados.
Comunidade e Suporte:
Embora tenha uma comunidade ativa, ela pode não ser tão grande quanto as de outras linguagens, afetando a disponibilidade de recursos e suporte.
Menos Popularidade em Alguns Domínios:
Em certos domínios especializados, Ruby pode não ser a primeira escolha devido à falta de bibliotecas ou ferramentas especializadas.
Comentários
Postar um comentário