Palavras-chave: strings, otimização, concatenação
Para fazer uma concatenação de strings sem perder a performance do seu programa em Ruby, ao invés de fazer
s = "" puts ObjectSpace.each_object(String){} 1000.times {s += "x"} puts ObjectSpace.each_object(String){} puts s.length
faça
s = "" puts ObjectSpace.each_object(String){} 1000.times {s << "x"} puts ObjectSpace.each_object(String){} puts s.length
O operador << funciona adicionando a nova string no objeto corrente, sem criar um novo a cada chamada igual o +=.
Rodando esses dois programas vamos ter:
160 2161 1000 e 160 1161 1000
Uau! de 2161 para 1161 strings alocadas é uma boa vantagem. Vamos rodar usando o profiler do Ruby para vermos a diferença “nas internas” (somente as linhas que interessam):
% cumulative self self total time seconds seconds calls ms/call ms/call name 40.00 0.05 0.02 1000 0.02 0.02 String#+ e % cumulative self self total time seconds seconds calls ms/call ms/call name 75.00 0.03 0.03 1000 0.03 0.03 String#<<
Já tivemos alguma diferença nos milissegundos ali. Reparem que += gasta 40% do tempo e << 75%, mas mesmo assim é mais rápido (resultados variáveis!). O garbage collector agradece. ;-)
Agora, se a string adicionada for sempre a mesma, que tal se fizermos:
s = "" x = "x" puts ObjectSpace.each_object(String){} 1000.times {s << x} puts ObjectSpace.each_object(String){} puts s.length
Rodando o programa:
162 163 1000
O resultado no profiler vai ser praticamente igual, mas que economia de strings, hein?
Parabéns pela matéria ! Exposição bem didática.
Obrigado