teclado - python separar string por caracter
ejecuciĆ³n de la cadena de python (6)
¿No debería ser exactamente al revés?
No necesariamente. No conozco los aspectos internos de Python lo suficiente como para comentar específicamente, pero algunas observaciones comunes son que su primer bucle utiliza un operador simple +
que se implementa de manera proverbial como primitivo en tiempo de ejecución. Por el contrario, los otros bucles primero tienen que resolver un nombre de módulo, resolver la variable / clase que se encuentra allí y luego llamar a una función miembro sobre eso.
Otra nota es que su bucle podría ser demasiado pequeño para producir números significativos. Teniendo en cuenta su bajo tiempo de ejecución general, esto probablemente haga que sus pruebas sean inútiles.
Además, su caso de prueba está altamente especializado en dos cadenas cortas. Tales casos nunca dan una imagen clara del rendimiento de la caja de borde.
Hay muchos artículos en Internet sobre el rendimiento de Python, lo primero que debe leer: las cadenas de concatenación no se deben hacer con ''+'': evite s1 + s2 + s3, en su lugar use str.join
Intenté lo siguiente: concatenar dos cadenas como parte de una ruta de directorio: tres enfoques:
- ''+'' que no debería hacer
- str.join
- os.path.join
Aquí está mi código:
import os,time
s1=''/part/one/of/dir''
s2=''part/two/of/dir''
N=10000
t=time.clock()
for i in xrange(N):
s=s1+os.sep+s2
print time.clock()-t
t=time.clock()
for i in xrange(N):
s=os.sep.join((s1,s2))
print time.clock()-t
t=time.clock()
for i in xrange(N):
s=os.path.join(s1,s2)
print time.clock()-t
Aquí los resultados (Python 2.5 WinXP)
0.0182201927899
0.0262544541275
0.120238186697
¿No debería ser exactamente al revés?
Es cierto que no deberías usar ''+''. Tu ejemplo es bastante especial, prueba el mismo código con:
s1=''*''*100000
s2=''+''*100000
Entonces, la segunda versión (str.join) es mucho más rápida.
La mayoría de los problemas de rendimiento con la concatenación de cadenas son de rendimiento asintótico, por lo que las diferencias se vuelven más significativas cuando se concatenan muchas cadenas largas. En su muestra, está realizando la misma concatenación muchas veces. No estás creando cadenas largas, y es posible que el intérprete de Python esté optimizando tus bucles. Esto explicaría por qué el tiempo aumenta cuando te mueves a str.join y path.join: son funciones más complejas que no se reducen tan fácilmente. (os.path.join realiza una gran cantidad de comprobaciones en las cadenas para ver si necesitan ser reescritas de alguna manera antes de que se concatenan. Esto sacrifica parte del rendimiento en aras de la portabilidad).
Por cierto, dado que las rutas de archivos no suelen ser muy largas, es casi seguro que quiera usar os.path.join por el bien de la portabilidad. Si el rendimiento de la concatenación es un problema, estás haciendo algo muy extraño con tu sistema de archivos.
La concatenación de cadenas ( +
) tiene una implementación optimizada en CPython. Pero este puede no ser el caso en otras arquitecturas como Jython o IronPython. Entonces, cuando desee que su código tenga un buen rendimiento en estos intérpretes, debe usar el método .join()
en las cadenas. os.path.join()
está específicamente destinado a unir rutas de sistema de archivos. También se ocupa de los diferentes separadores de ruta. Esta sería la forma correcta de construir un nombre de archivo.
Me gustaría agregar un enlace a la wiki de python, donde hay notas sobre la concatenación de cadenas y también que " esta sección es algo incorrecta con python2.5. La concatenación de cadenas de Python 2.5 es bastante rápida ".
Creo que la concatenación de cadenas tuvo una gran mejora desde 2.5, y que aunque str.join es aún más rápido (especialmente para cadenas grandes), no verá tanta mejora como en las versiones anteriores de Python.
http://wiki.python.org/moin/PythonSpeed/PerformanceTips#StringConcatenation
El consejo es sobre la concatenación de muchas cadenas.
Para calcular s = s1 + s2 + ... + sn,
1) usando +. Se crea una nueva cadena s1 + s2, luego se crea una nueva cadena s1 + s2 + s3, ..., etc., lo que implica una gran cantidad de operaciones de asignación y copia de memoria. De hecho, s1 se copia n-1 veces, s2 se copia n-2 vez, ..., etc.
2) usando "" .join ([s1, s2, ..., sn]). La concatenación se realiza en una pasada, y cada carácter en las cadenas se copia una sola vez.
En su código, se llama a join en cada iteración, por lo que es como usar +. La forma correcta es recoger los elementos en una matriz, luego llamar a unirse a ella.
editar: corrigió el error tipográfico