Memoria extremadamente alta y uso de la CPU al cargar datos analizados JSON a Firebase en function de bucle

Esta es mi primera pregunta aquí, ¡así que ponte fácil conmigo!

Soy un codificador novato y actualmente estoy tratando de recorrer JSON, analizar los datos y hacer una copy de security de la información en mi server Firebase, usando Alamofire para solicitar la información JSON.

Swift 4, Alamofire 4.5.1, Firebase 4.2.0

El process funciona, pero no sin boost el uso de la memory del dispositivo y hasta el 200% de uso de la CPU. Al comentar las líneas, seleccioné la memory y el uso de la CPU hasta la línea de setValue de carga de Firebase en mi function de extracción de datos, que itera a través de una database JSON de longitud desconocida (al jalar un máximo de 1000 filas de datos a la vez). aumentando los valores de desplazamiento). La database de la que estoy obteniendo información es enorme, y con el creciente uso de la memory, la function se muele a un ritmo muy lento.

La function detecta si se encuentra un JSON vacío (final de los resultados), y luego termina o analiza el JSON, carga la información en Firebase, aumenta el valor de desplazamiento en 1000 filas y luego se repite con el nuevo valor de desplazamiento.

var offset: Int! = 0 var finished: Bool! = false func pullCities() { print("step 1") let call = GET_CITIES + "&offset=\(self.offset!)&rows=1000" let cityURL = URL(string: call)! Alamofire.request(cityURL).authenticate(user: USERNAME, password: PASSWORD).responseJSON { response in let result = response.result print("step 2") if let dict = result.value as? [Dictionary<String, Any>] { print("step 3") if dict.count == 0 { self.finished = true print("CITIES COMPLETE") } else { print("step 4") for item in dict { if let id = item["city"] as? String { let country = item["country"] as? String let ref = DataService.ds.Database.child("countries").child(country!).child("cities").child(id) ref.setValue(item) } } self.finished = false print("SUCCESS CITY \(self.offset!)") self.offset = self.offset! + 1000 } } if self.finished == true { return } else { self.pullCities() } } } 

Me parece que los datos que se suben a Firebase se están guardando en algún lugar y no se vacían una vez que se completa la carga. Aunque no pude encontrar mucha información sobre este tema al search en la web.

Cosas que he probado:

  • una repetición, mientras que la function (no es bueno, ya que solo quiero 1 repetición activa de cada bucle, y aún tenía alta memory, uso de la CPU)

  • monitoreo de performance (el tree de llamadas Xcode encontró que "CFString (inmutable)" y "__NSArrayM" fueron el motivo principal del aumento en el uso de la memory, ambos relacionados con la línea setValue anterior)

  • el uso de la memory grafica (muy claro que la memory de esta function no se vacía cuando se vuelve a girar, sin disminución de la memory)

  • bloques de autoreleasepool (según sugerencias, sin éxito)

  • La optimization de todo el module ya está habilitada (según las sugerencias, sin éxito)

¡Cualquier ayuda sería muy apreciada!

ACTUALIZAR

A continuación, se muestra el gráfico de Asignaciones después de una sola ejecución del ciclo (1,000 filas de datos). Muestra que lo que probablemente está sucediendo es que Firebase almacena en caching los datos de cada elemento en el resultado dict, pero parece que solo desasigna la memory como un solo bloque cuando cada carga ha terminado. Lo ideal sería que se networkingistribuya después de cada carga exitosa y no todos a la vez. ¡Si alguien puede dar algunos consejos sobre esto, estaría muy agradecido!

Gráfico de Asignaciones

ACTUALIZACIÓN FINAL

Si alguien debería encontrar esto con el mismo problema, no encontré una solución. Mis requisitos cambiaron, así que cambié el código a nodejs que funciona impecablemente. ¡Las requestes HTTP también son muy fáciles de codificar en javascript!

Tuve un problema similar al trabajar con datos en sitios web externos y la única manera de solucionarlo era envolver el ciclo en un bloque de autoreleasepool {} que obligaba a la memory a desaparecer en cada iteración. Dado ARC, podría pensar que dicha estructura no es necesaria en Swift, pero vea esta discusión SO:

¿Es necesario usar autoreleasepool en un progtwig Swift?

Espero que ayude.

a veces, el comstackdor no puede optimizar su código correctamente a less que habilite la optimization completa de modules en la configuration de compilation del proyecto. Esto generalmente ocurre cuando se usan generics.

intente encenderlo incluso para dep env y testing.