5 votos

arcpy tarda más y más en un bucle

Estoy haciendo un bucle a través de una cantidad de matrices de puntos, creando datos sobre la marcha.

Los rasgos/arreglos, son en gran medida similares en tamaño. Una cosa que he notado, es que cuando inicio el proceso, el tiempo que tarda en realizarse, aumenta de unos 8 segundos, a alrededor de 1 minuto. No puedo ver por qué está sucediendo esto, pero se puede ver los tiempos aumentan lentamente si se pone un temporizador alrededor del bucle.

¿Hay alguna manera de aumentar este rendimiento? ¿Existe un método de descarga? Creo que estoy manejando correctamente mis objetos y borrándolos después de su uso, pero no puedo por la vida de mí ver por qué está sucediendo?

¿Alguna idea?

El código está refactorizado, por lo que puede haber algunos errores tipográficos, etc.

def createGeom(geom,header,band,scratchDB,buffer, dist):

filetime = (str(time.time())).split(".")
outfile = "fc" + filetime[0]+filetime[1]
outpath =  scratchDB + "tmp.gdb/Polygon/"
print outpath
sCon = ["1", "16", "2.0"] 
ts = header.split(" ")
ti = ts[6]
Current = ts[9]
LL = ts[2][2:5]
LU = ts[2][8:11]

outFeatureAggClass = outpath+outfile+"_agg"
outFeatureClass = outpath+outfile

arcpy.AggregatePoints_cartography(geom, outFeatureAggClass, dist)
arcpy.Buffer_analysis(outFeatureAggClass, outFeatureClass, buffer)

arcpy.AddField_management(outFeatureClass, "Name", "Text")
arcpy.AddField_management(outFeatureClass, "ID", "SHORT")
arcpy.AddField_management(outFeatureClass, "LL", "SHORT")
arcpy.AddField_management(outFeatureClass, "LU", "SHORT")        
arcpy.AddField_management(outFeatureClass, "Tim", "SHORT") 
arcpy.AddField_management(outFeatureClass, "Band", "SHORT")
arcpy.AddField_management(outFeatureClass, "Lvl", "TEXT") 
arcpy.AddField_management(outFeatureClass, "Cur", "SHORT")

rows = arcpy.UpdateCursor(outFeatureClass)
for row in rows:
    row.name = outfile
    row.ID = 1000
    row.LL = int(LL)
    row.LU = int(LU)
    row.Tim = int(ti)   
    row.Band = int(band)
    row.Lvl = sCon[int(band)]
    row.Cur = Current
    rows.updateRow(row)

del row
del rows    

ACTUALIZACIÓN

Ahora estoy ejecutando esto en ArcMap, y está tomando significativamente menos tiempo, a un factor o alrededor de 3 o 4; lo que tomó 30 minutos, ahora toma 7.

¿De qué se trata?

EDITAR

El ESRI ha accedido a estudiar la cuestión. Aparcaré esto por ahora, dispuesto a actualizarlo con cualquier progreso.

5voto

Sork Puntos 26

Puede que quieras probar a poner del row dentro del bucle como la última llamada después de rows.updateRow{row} . Su eliminación de objetos no tiene lugar hasta que está fuera del bucle, por lo que podría ser sólo la colección bastante grande de objetos de fila que está creando. Yo pensaría que los objetos fila se están eliminando a medida que se sale del ámbito, pero podría no ser el caso.

También puede intentar utilizar el módulo de recolección de basura para depurar y/o solucionar el problema: http://docs.python.org/library/gc.html

Algunas otras cuestiones... haz todos tus lanzamientos fuera del bucle. Por ejemplo LL = int(LL) antes del bucle, de modo que dentro del bucle sólo se haga "row.LL = LL". Parece que no estás haciendo ningún cálculo dentro del bucle que cambie alguno de estos valores de fila a fila, así que no hay necesidad de hacer el casting dentro del bucle.

Editar: No me di cuenta de que estaba haciendo un bucle contra muchos archivos. El problema podría estar en su llamada de bucle exterior, no en su llamada a la función. Dado que funciona correctamente en ArcMap, pero no fuera de ArcMap, usted podría estar recargando arcpy o la creación de nuevos objetos geoprocesador con cada llamada a un archivo. Esta es una operación muy costosa que se vuelve mucho peor cuantas más veces se ejecute.

Me encontré con un problema similar con una operación que estaba tratando de llamar cada 20 segundos fuera de ArcMap. Cada vez que llamaba a la función interna desde el bucle de temporización externo, arcpy se recargaba a pesar de haber importado arcpy en el bucle de temporización externo. Como resultado, mi función interna se ejecutaba cada vez más lentamente y era imposible terminarla en 20 segundos. Para evitarlo, importé arcpy en el bucle de temporización externo, y luego pasó a arcpy como argumento en la función interna . Una vez que hice esto, mi función interna se ejecutaba en menos de 3 segundos cada vez.

Así que, para su función, podría intentar cambiar su definición a
def createGeom(geom,header,band,scratchDB,buffer, dist, arcpy): y luego, cuando lo llames, asegúrate de pasar arcpy como séptimo argumento.

Por lo que puedo decir, dentro de ArcMap, arcpy se carga una vez y luego se mantiene para cualquier llamada contra él, incluso si es llamado por una función interna. De ahí el rendimiento mucho mejor cuando se ejecuta en ArcMap.

3voto

Symmetric Puntos 158

Hmmm... parece que impar utilizar el del pero los documentos oficiales lo utilizan. Aparte de eso, no veo nada obvio. ¿Está recibiendo la ralentización mientras el bucle itera, o es cada vez que llama a su createGeom() ¿función?

Puedes intentar comentar el updateRow() llamada, sólo para ver si se está ralentizando o si es otra cosa. Además, ¿eres capaz de envolver el bucle en una transacción? Mi conocimiento de arcpy es limitado, pero en general las actualizaciones de tipo base de datos son más eficientes si todo está en una transacción.

1voto

mleykamp Puntos 491

Acabo de recibir respuesta de ESRI, que ha confirmado que se trata de un error que se ha reparado en el SP2 de ArcGIS 10.

Instalando el SP2 hoy, así que informaré. Los polígonos se dibujaban a los 5 segundos, terminando a los 50 segundos, así que esto representa una victoria considerable para nosotros, ya que todos se dibujarán alrededor de la marca de 5 segundos.

Gracias por los consejos, amigos.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X