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

195
Views
¿Cómo se decide la optimización de concatenación de cadenas s=s+c?

Versión corta: si s es una cadena, entonces s = s + 'c' podría modificar la cadena en su lugar, mientras que t = s + 'c' no. Pero, ¿cómo sabe la operación s + 'c' qué escenario se encuentra?

Versión larga:

t = s + 'c' necesita crear una cadena separada porque el programa luego quiere tanto la cadena anterior como s como la nueva cadena como t .

s = s + 'c' puede modificar la cadena en su lugar si s es la única referencia, ya que el programa solo quiere que s sea la cadena extendida. CPython realmente hace esta optimización, si hay espacio al final para el carácter extra.

Considere estas funciones, que agregan un carácter repetidamente:

 def fast(n): s = '' for _ in range(n): s = s + 'c' t = s del t def slow(n): s = '' for _ in range(n): t = s + 'c' s = t del t

Resultados de referencia con n = 100_000 (¡ Pruébelo en línea! ):

 fast : 9 ms 9 ms 9 ms 9 ms 10 ms slow : 924 ms 927 ms 931 ms 933 ms 945 ms

Tenga en cuenta que el extra t = s o s = t hace que ambas variables sean referencias equivalentes a la cadena y luego del t deja solo s , por lo que en la siguiente iteración del bucle, s vuelve a ser la única referencia a la cadena. Por lo tanto, la única diferencia entre las dos funciones es el orden en que s + 'c' se asigna a s t .

Desmontemos también el código de bytes. Marqué las únicas tres diferencias con != en el medio. Como era de esperar, solo difieren las variables para STORE_FAST y LOAD_FAST . Pero hasta BINARY_ADD inclusive, el código de bytes es idéntico. Entonces, ¿cómo sabe BINARY_ADD si optimizar o no?

 import dis import dis dis.dis(fast) dis.dis(slow) --------------------------------------------------------------------------- 0 LOAD_CONST 1 ('') 0 LOAD_CONST 1 ('') 2 STORE_FAST 1 (s) 2 STORE_FAST 1 (s) 4 LOAD_GLOBAL 0 (range) 4 LOAD_GLOBAL 0 (range) 6 LOAD_FAST 0 (n) 6 LOAD_FAST 0 (n) 8 CALL_FUNCTION 1 8 CALL_FUNCTION 1 10 GET_ITER 10 GET_ITER >> 12 FOR_ITER 18 (to 32) >> 12 FOR_ITER 18 (to 32) 14 STORE_FAST 2 (_) 14 STORE_FAST 2 (_) 16 LOAD_FAST 1 (s) 16 LOAD_FAST 1 (s) 18 LOAD_CONST 2 ('c') 18 LOAD_CONST 2 ('c') 20 BINARY_ADD 20 BINARY_ADD 22 STORE_FAST 1 (s) != 22 STORE_FAST 3 (t) 24 LOAD_FAST 1 (s) != 24 LOAD_FAST 3 (t) 26 STORE_FAST 3 (t) != 26 STORE_FAST 1 (s) 28 DELETE_FAST 3 (t) 28 DELETE_FAST 3 (t) 30 JUMP_ABSOLUTE 12 30 JUMP_ABSOLUTE 12 >> 32 LOAD_CONST 0 (None) >> 32 LOAD_CONST 0 (None) 34 RETURN_VALUE 34 RETURN_VALUE
over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

Aquí está el código en cuestión , de la rama de Python 3.10 (en ceval.c , y llamado desde la implementación del mismo archivo del código de operación BINARY_ADD ). Como señaló @jasonharper en un comentario, mira hacia adelante para ver si el resultado de BINARY_ADD se vinculará a continuación con el mismo nombre del que proviene el sumando de la izquierda. En fast() , es (el operando proviene de s y el resultado se almacena en s ), pero en slow() no lo es (el operando proviene de s pero se almacena en t ).

Sin embargo, no hay garantía de que esta optimización persista. Por ejemplo, noté que su fast() no es más rápido que su slow() en la rama main de CPython de desarrollo actual (que es el trabajo en progreso actual hacia una versión final 3.11).

¿Debería la gente confiar en esto?

Como se señaló, no hay garantía de que esta optimización persistirá. Los programadores de Python "serios" deberían saber que no deben confiar en trucos dudosos específicos de CPython y, de hecho, PEP 8 advierte explícitamente contra confiar en este específico:

El código debe escribirse de manera que no perjudique a otras implementaciones de Python (PyPy, Jython, IronPython, Cython, Psyco, etc.).

Por ejemplo, no confíe en la implementación eficiente de CPython de la concatenación de cadenas en el lugar para declaraciones en la forma a += b o a = a + b ...

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!