Observe que o lisp reader estende símbolos, de forma que as referências independentes a um determinado símbolo fornecem exatamente o mesmo objeto lisp e, consequentemente, você é capaz de compará-los eq
(que só precisa comparar os endereços dos objetos).
Por outro lado, strings independentes são sempre objetos lisp diferentes e, portanto, você deve comparar o conteúdo deles.
Portanto, você esperaria que a eq
comparação ganhasse pelo desempenho.
Curiosamente (estou certamente muito surpreso), alguns testes triviais benchmark-run
estão dando string=
a vitória por uma margem bastante. Isso me parece muito estranho. YMMV?
Edit: Então, eu apenas notei essa resposta (e seu comentário) novamente e me senti inspirado para ver se eu poderia recriar e explicar o resultado.
Nota: nada é compilado em bytes inicialmente.
A primeira constatação foi que meus símbolos eram quote
d e as seqüências não eram, e imediatamente descobri que quote
era o responsável pela maior parte da diferença de velocidade:
(benchmark-run 10000000
(string= "foo" "foo"))
é, para cadeias pequenas, consistentemente mais rápido que:
(benchmark-run 10000000
(eq 'foo 'foo))
no entanto, se também citarmos a string:
(benchmark-run 10000000
(string= '"foo" '"foo"))
que quase equilibra completamente as coisas.
No entanto, em média, a menos que a corda seja muito grande, a comparação de cordas ainda parece ganhar por um fio de cabelo.
Uma abordagem alternativa é vincular os objetos a variáveis:
(let ((foo 'test)
(bar 'test))
(benchmark-run 10000000
(eq foo bar)))
(let ((foo "test")
(bar "test"))
(benchmark-run 10000000
(string= foo bar)))
Mais uma vez, estou vendo a comparação das cordas mais rapidamente, em média.
Após a compilação de bytes, vejo apenas um resultado consistente para os casos de variáveis vinculadas, onde eq
é consistentemente mais rápido do que string=
(demorando cerca de 2/3 do tempo).
Para os outros exemplos, estou obtendo resultados sem sentido (para mim), como as seqüências de caracteres citadas, sendo mais rápidas do que as seqüências de caracteres não citadas, o que só posso supor é efetivamente ruído de outros aspectos da execução e / ou de benchmark-run
si próprio. Havia variedade suficiente entre execuções diferentes da mesma função para ocultar completamente quaisquer diferenças entre execuções de funções diferentes.
Minhas conclusões são:
(a) eq
comparações com um símbolo podem (de maneira um pouco contra-intuitiva) ser mais lenta que uma comparação de cadeias, se o símbolo for citado.
(b) A menos que as strings sejam bastante grandes, as diferenças práticas são totalmente desprezíveis e, portanto, eu não me incomodaria em converter uma na outra por razões puramente de desempenho.
eq
para comparar com um símbolo.