Tenga en cuenta que el lector lisp practica símbolos, de modo que las referencias independientes a un símbolo dado le dan exactamente el mismo objeto lisp , y en consecuencia puede compararlos eq
(que solo necesita comparar las direcciones de los objetos).
Por el contrario, las cadenas independientes son siempre objetos lisp diferentes y, por lo tanto, debe comparar sus contenidos.
Por lo tanto, esperaría que la eq
comparación gane por rendimiento.
Curiosamente (ciertamente estoy muy sorprendido), algunas pruebas triviales benchmark-run
están dando string=
la victoria por bastante margen. Esto me parece muy extraño. YMMV?
Editar: Así que acabo de notar esta respuesta (y su comentario) nuevamente, y me sentí inspirado para ver si podía recrear y explicar el resultado.
nb Nada se compila en bytes inicialmente.
La primera constatación fue que mis símbolos eran quote
d y las cadenas no, e inmediatamente descubrí que quote
era el responsable de la mayor parte de la diferencia de velocidad:
(benchmark-run 10000000
(string= "foo" "foo"))
es, para cadenas más pequeñas, consistentemente más rápido que:
(benchmark-run 10000000
(eq 'foo 'foo))
sin embargo, si también citamos la cadena:
(benchmark-run 10000000
(string= '"foo" '"foo"))
eso casi iguala las cosas por completo.
Sin embargo, en promedio, a menos que la cuerda sea bastante grande, la comparación de la cuerda todavía parece ganar por un pelo.
Un enfoque alternativo es vincular los objetos a las variables:
(let ((foo 'test)
(bar 'test))
(benchmark-run 10000000
(eq foo bar)))
(let ((foo "test")
(bar "test"))
(benchmark-run 10000000
(string= foo bar)))
Una vez más, estoy viendo la comparación de cuerdas más rápido por nariz, en promedio.
Después de la compilación de bytes, solo veo un resultado consistente para los casos variables de let-bound, donde eq
es consistentemente más rápido que string=
(toma alrededor de 2/3 del tiempo).
Para los otros ejemplos, obtengo resultados sin sentido (para mí) como que las cadenas entre comillas son más rápidas que las cadenas sin comillas, lo que solo puedo adivinar es efectivamente el ruido de otros aspectos de la ejecución y / o en benchmark-run
sí mismo. Había suficiente variedad entre diferentes ejecuciones de la misma función para ocultar por completo cualquier diferencia entre ejecuciones de diferentes funciones.
Mis conclusiones son:
(a) las eq
comparaciones con un símbolo pueden (algo contraintuitivamente) ser más lentas que una comparación de cadenas, si se cita el símbolo.
(b) A menos que las cadenas sean bastante grandes, las diferencias prácticas son completamente insignificantes, por lo que no me molestaría en convertir una a la otra por razones puramente de rendimiento.
eq
para comparar contra un símbolo.