Em sx.el
, temos um caso em que precisamos verificar se passamos GET
ou POST
como argumento.
Atualmente, temos o argumento passando como uma string e estamos usando (string= "GET" url-method)
para compará-lo "GET"
.
Existe alguma vantagem de compilação elisp / byte para alterá-lo para um símbolo (equal url-method 'GET)
?
elisp
byte-compilation
Jonathan Leech-Pepin
fonte
fonte
eq
para comparar com um símbolo.eq
irá converter objetos do Emacsint
e compará-los. Compararint
s é muito mais rápido que compararstring
s.string=
funcionará como esperado, sejaurl-method
um símbolo ou uma string. OTOH se você usareq
ouequal
, precisará garantir que os argumentos sejam do mesmo tipo.Respostas:
Os novos usuários do Lisp que vêm de outros idiomas às vezes usam cadeias para tais fins por hábito.
Os símbolos podem ser comparados ao
eq
invés de apenasequal
.string=
usa código semelhante aequal
, para testar cada caractere até encontrar uma incompatibilidade. Então, sim, a comparação de símbolos pode ser um pouco mais rápida. Se você estiver usando a comparação em um loop, por exemplo, a diferença pode ser importante.Além disso, dependendo do código específico, muitas vezes pode tornar o código mais simples ou mais legível para usar símbolos em vez de cadeias. E há funções (e macros etc.) que esperam símbolos ou que comparam coisas usando
eq
(oueql
) por padrão. Para usar aqueles com strings, você precisa converter em símbolos.fonte
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 dandostring=
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 quequote
era o responsável pela maior parte da diferença de velocidade:é, para cadeias pequenas, consistentemente mais rápido que:
no entanto, se também citarmos a string:
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:
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 questring=
(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.
fonte
intern
+eq
contrastring=
. Ou possivelmente por algum motivo completamente diferente: é impossível saber sem ver seu código. Você deve postar seu código de teste como uma pergunta neste site.benchmark-run-compiled
(com a ideia de que isso reduziria o custo deintern
), mas várias vezes obtive tempos de resultados negativos. Eu acho que as duas operações são muito rápidas para medir com segurança.