Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

258
Views
¿Por qué es más rápido comparar cadenas que coinciden que cadenas que no lo hacen?

Aquí hay dos medidas:

 timeit.timeit('"toto"=="1234"', number=100000000) 1.8320042459999968 timeit.timeit('"toto"=="toto"', number=100000000) 1.4517491540000265

Como puede ver, comparar dos cadenas que coinciden es más rápido que comparar dos cadenas del mismo tamaño que no coinciden. Esto es bastante perturbador: durante una comparación de cadenas, creí que Python estaba probando cadenas carácter por carácter, por lo que "toto"=="toto" debería ser más largo para probar que "toto"=="1234" ya que requiere cuatro pruebas contra uno para la comparación no coincidente. Tal vez la comparación esté basada en hash, pero en este caso, los tiempos deberían ser los mismos para ambas comparaciones.

¿Por qué?

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Combinando mi comentario y el comentario de @khelwood:

TL;RD:
Al analizar el código de bytes para las dos comparaciones, revela que las cadenas de 'time' y 'time' están asignadas al mismo objeto. Por lo tanto, una verificación de identidad por adelantado (en el nivel C) es la razón del aumento de la velocidad de comparación.

El motivo de la misma asignación de objeto es que, como detalle de implementación , CPython interna cadenas que contienen solo 'caracteres de nombre' (es decir, caracteres alfabéticos y de subrayado). Esto habilita la verificación de identidad del objeto.


Código de bytes:

 import dis In [24]: dis.dis("'time'=='time'") 1 0 LOAD_CONST 0 ('time') # <-- same object (0) 2 LOAD_CONST 0 ('time') # <-- same object (0) 4 COMPARE_OP 2 (==) 6 RETURN_VALUE In [25]: dis.dis("'time'=='1234'") 1 0 LOAD_CONST 0 ('time') # <-- different object (0) 2 LOAD_CONST 1 ('1234') # <-- different object (1) 4 COMPARE_OP 2 (==) 6 RETURN_VALUE

Tiempo de asignación:

La 'aceleración' también se puede ver al usar la asignación para las pruebas de tiempo. La asignación (y comparación) de dos variables a la misma cadena es más rápida que la asignación (y comparación) de dos variables a cadenas diferentes. Apoyando aún más la hipótesis, la lógica subyacente está realizando una comparación de objetos. Esto se confirma en la siguiente sección.

 In [26]: timeit.timeit("x='time'; y='time'; x==y", number=1000000) Out[26]: 0.0745926329982467 In [27]: timeit.timeit("x='time'; y='1234'; x==y", number=1000000) Out[27]: 0.10328884399496019

Código fuente de Python:

Tal como lo proporcionaron amablemente @mkrieger1 y @Masklinn en sus comentarios, el código fuente de unicodeobject.c realiza primero una comparación de punteros y, si es True , regresa inmediatamente.

 int _PyUnicode_Equal(PyObject *str1, PyObject *str2) { assert(PyUnicode_CheckExact(str1)); assert(PyUnicode_CheckExact(str2)); if (str1 == str2) { // <-- Here return 1; } if (PyUnicode_READY(str1) || PyUnicode_READY(str2)) { return -1; } return unicode_compare_eq(str1, str2); }

Apéndice:

  • Respuesta de referencia que ilustra muy bien cómo leer la salida del código de bytes desmontado. Cortesía de @Delgan
  • Respuesta de referencia que describe muy bien la internación de cadenas de CPython. Cortesía de @ShadowRanger
over 4 years ago · Santiago Trujillo Report

0

No siempre es más rápido comparar cadenas que coinciden. En cambio, siempre es más rápido comparar cadenas que comparten la misma identificación. Una prueba de que la identidad es de hecho la razón de este comportamiento (como @S3DEV ha explicado brillantemente) es esta:

 >>> x = 'toto' >>> y = 'toto' >>> z = 'totoo'[:-1] >>> w = 'abcd' >>> x == y True >>> x == z True >>> x == w False >>> id(x) == id(y) True >>> id(x) == id(z) False >>> id(x) == id(w) False >>> timeit.timeit('x==y', number=100000000, globals={'x': x, 'y': y}) 3.893762200000083 >>> timeit.timeit('x==z', number=100000000, globals={'x': x, 'z': z}) 4.205321462000029 >>> timeit.timeit('x==w', number=100000000, globals={'x': x, 'w': w}) 4.15288594499998

Siempre es más rápido comparar objetos que tienen la misma identificación (como puede notar en el ejemplo, la comparación entre x y z es más lenta en comparación con la comparación entre x e y , y eso se debe a que x y z no comparten la misma identificación).

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!