Ruby: Concatenação eficiente de strings

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?

Veja essa dica também em Python.

This entry was posted in Ruby. Bookmark the permalink.

One Response to Ruby: Concatenação eficiente de strings

  1. Santério Jr says:

    Parabéns pela matéria ! Exposição bem didática.
    Obrigado

Leave a Reply

Your email address will not be published. Required fields are marked *