Estou trabalhando com Ruby Koans.
O test_the_shovel_operator_modifies_the_original_string
Koan em about_strings.rb inclui o seguinte comentário:
Os programadores Ruby tendem a favorecer o operador de escavadeira (<<) sobre o operador de mais iguais (+ =) ao criar cadeias. Por quê?
Meu palpite é que envolve velocidade, mas não entendo a ação sob o capô que faria com que o operador da escavadeira fosse mais rápido.
Alguém poderia explicar os detalhes por trás dessa preferência?
ruby
string
optimization
erinbrown
fonte
fonte
Respostas:
Prova:
Portanto,
<<
altera a string original em vez de criar uma nova. A razão para isso é que, em ruby,a += b
é uma abreviação sintática paraa = a + b
(o mesmo vale para os outros<op>=
operadores), que é uma atribuição. Por outro lado,<<
existe um apelidoconcat()
que altera o receptor no local.fonte
Array#join
é mais lento que o uso<<
.Prova de desempenho:
fonte
Um amigo que está aprendendo Ruby como sua primeira linguagem de programação me fez a mesma pergunta enquanto passava por Strings in Ruby na série Ruby Koans. Expliquei a ele usando a seguinte analogia;
Você tem um copo de água pela metade e precisa recarregá-lo.
A primeira maneira de fazê-lo é pegar um copo novo, enchê-lo até a metade com água de uma torneira e usar esse segundo copo meio cheio para encher novamente o copo. Você faz isso toda vez que precisar encher seu copo.
A segunda maneira de pegar seu copo meio cheio e apenas enchê-lo com água diretamente da torneira.
No final do dia, você teria mais copos para limpar se escolher um copo novo toda vez que precisar recarregá-lo.
O mesmo se aplica ao operador de escavadeira e ao operador mais igual. Além disso, o operador igual escolhe um novo 'copo' toda vez que precisa reabastecer seu copo, enquanto o operador da escavadora apenas pega o mesmo copo e o recarrega. No final do dia, mais coleta de 'vidro' para o operador igual Plus.
fonte
Essa é uma pergunta antiga, mas eu a encontrei e não estou totalmente satisfeita com as respostas existentes. Há muitos pontos positivos sobre a pá ser mais rápida que a concatenação + =, mas também há uma consideração semântica.
A resposta aceita de @noodl mostra que << modifica o objeto existente, enquanto + = cria um novo objeto. Portanto, você deve considerar se deseja que todas as referências à sequência reflitam o novo valor ou se deseja deixar as referências existentes em paz e criar um novo valor para usar localmente. Se você precisar de todas as referências para refletir o valor atualizado, precisará usar <<. Se você quiser deixar outras referências em paz, precisará usar + =.
Um caso muito comum é que há apenas uma única referência à string. Nesse caso, a diferença semântica não importa e é natural preferir << devido à sua velocidade.
fonte
Porque é mais rápido / não cria uma cópia da cadeia de caracteres <-> o coletor de lixo não precisa ser executado.
fonte
malloc
/free
. Além disso, algumas implementações mais modernas do Ruby provavelmente otimizarão a alocação de objetos e a concatenação de cadeias completamente. OTOH, a mutação de objetos é terrível para o desempenho do GC.Embora a maioria das respostas
+=
seja mais lenta porque cria uma nova cópia, é importante ter isso em mente+=
e<<
não é intercambiável! Você deseja usar cada um em diferentes casos.O uso
<<
também altera as variáveis apontadasb
. Aqui também mudamosa
quando não queremos.Como
+=
faz uma nova cópia, também deixa inalteradas as variáveis que estão apontando para ela.Entender essa distinção pode economizar muitas dores de cabeça quando você está lidando com loops!
fonte
Embora não seja uma resposta direta à sua pergunta, o motivo pelo qual The Fully Upturned Bin sempre foi um dos meus artigos favoritos sobre Ruby. Ele também contém algumas informações sobre cadeias de caracteres em relação à coleta de lixo.
fonte