Calcular tiempo de ejecución de un código

En un artículo anterior vimos como podemos usar async let para ejecutar procesos en paralelo. ¿Cómo podemos medir que en realidad está tomando menos tiempo la ejecución con este cambio?

La respuesta es usando Clock. Más específicamente, ContinuousClock un tipo de Clock introducido en Swift 5.7, que nos permite medir el tiempo de ejecución de manera continua tomando en cuenta cuando la aplicación esta en estado de suspensión.

¿Cómo usar ContinuousClock para medir tiempo de ejecución?

El siguiente código muestra como podemos medir el tiempo de ejecución de una función:

// 1
let clock = ContinuousClock()
// 2
let result = clock.measure {
// Llamar la función aquí
}
// 3
print(result)

Esto es lo que hace este código:

  1. Creamos una instancia de ContinuousClock y la guardamos en la variable clock.
  2. Usamos measure(_:) y asignamos el resultado de la llamada en la variable result.
  3. Por último imprimimos el contenido de result. Aquí se imprimiría el tiempo total que toma en ejecutar el código.

Un ejemplo con código

Usemos el siguiente código para medir el tiempo de ejecución:

func getInt() async -> Int {
try? await Task.sleep(for: .seconds(1))
return 1
}
func getString() async -> String {
try? await Task.sleep(for: .seconds(2))
return "Texto"
}
func getData() async {
async let numberOperation = getInt()
async let textOperation = getString()
let (number, text) = await (numberOperation, textOperation)
print("\(number) \(text)")
}

Aquí tenemos una getData() que ejecuta getInt() y getString() usando async let.

Note que cada una de estas funciones tiene un Task.sleep(for:) que provoca una pausa en tiempo de ejecución, en el caso de getInt() de un segundo y getString() de dos segundos. Sin embargo, como estamos usando async let la ejecución de getData() debería tomar alrededor de dos segundos no tres.

Pongamos esto a prueba. Usando ContinuousClock:

func measureExecution() {
Task {
let clock = ContinuousClock()
let result = await clock.measure {
await getData()
}
}
print("Tiempo ejecución \(result.components.seconds) segundos")
}

Hay varias cosas diferentes en este código con respecto a como explicamos en el principio que debía utilizarse:

  • Lo estamos envolviendo todo dentro un Task y cuando llamamos clock.measure lo precedimos con await. Estos cambios se deben a que estamos tratando de medir el tiempo de ejecución de una función asíncrona.
  • No estamos imprimiendo result, sino result.components.seconds, porque solo nos interesan los segundos que toma la ejecución.

El resultado

Si ejecutamos measureExecution() podremos ver los siguientes datos en consola:

Resultado impreso en Consola

Siendo la primera línea el resultado de print("\(number) \(text)") y la segunda la cantidad de segundos que toma ejecutar la función, emitido por print(result.components.seconds).

Así probamos nuestra hipótesis de que el tiempo total de ejecución es dos segundos en ves de tres gracias a async let.

Cosas a tomar en cuenta

  • La manera como el sistema operativo asigna los recursos no es controlada totalmente por nosotros. Por lo que en una aplicación real no podríamos garantizar cuanto tiempo tomará ejecutar algo. Para tratar de influir un poco en la prioridad que el sistema da a la ejecución de nuestro código podemos usar otras herramientas, como por ejemplo, utilizando la propiedad priority de los objetos Task.
  • Recuerda usar await cuando quieras medir el tiempo de ejecución de funciones asíncronas.
  • Clock y sus derivados están disponibles solo a partir de iOS 16.

Comparte este artículo

Subscríbete a nuestro Newsletter

Mantente al día en el mundo de las aplicaciones móviles con nuestro blog especializado.

Artículos semanales

Todas las semanas artículos nuevos sobre el mundo de las aplicaciones móviles.

No spam

No te enviaremos spam, solo contenido de calidad. Puedes darte de baja cuando quieras.

Contenido de calidad

Nada de contenido generado de manera automática usando ChatGPT.

Recomendaciones

Tips indispensables sobre mejores prácticas y metodologías.

© 2024 AsyncLearn