time<T> function

({Duration elapsed, T result}) time<T>(
  1. dynamic functionOrValue
)

Measures the execution time of a function, expression, or computation and returns a tuple containing both the result and the elapsed duration.

This function can be used in multiple ways:

  1. With a function reference: time(() => factorial(20))
  2. With a direct expression: time(factorial(20))
  3. With a callback that receives a measurement function: time((measure) => measure(factorial)(20))

Example 1 - With function reference:

final result = time(() => factorial(20));
print('Result: ${result.result}, Time: ${result.elapsed.inMilliseconds}ms');

Example 2 - With direct expression:

final result = time(factorial(20));
print('Result: ${result.result}, Time: ${result.elapsed.inMilliseconds}ms');

Example 3 - With measurement callback:

final result = time((measure) {
  final wrappedFactorial = measure(factorial);
  return wrappedFactorial(20);
});
print('Result: ${result.result}, Time: ${result.elapsed.inMilliseconds}ms');

Example 4 - Measuring multiple operations:

final result = time((measure) {
  final a = measure(() => operation1())(arg1);
  final b = measure(() => operation2())(arg2);
  return a + b;
});

The returned Duration can be inspected using properties like:

For more precise measurements of very fast operations, consider using Stopwatch directly with Stopwatch.elapsedMicroseconds.

Implementation

({T result, Duration elapsed}) time<T>(dynamic functionOrValue) {
  // Case 1: Measurement callback with access to measure function
  if (functionOrValue is Function(Function)) {
    final sw = Stopwatch()..start();

    // Create a measure function that wraps any function to track its execution time
    measure(fn) {
      return (fn is Function)
          ? ((dynamic args) {
              final innerSw = Stopwatch()..start();
              final result = args != null ? fn(args) : fn();
              innerSw.stop();
              print('Operation took: ${innerSw.elapsed.inMicroseconds}μs');
              return result;
            })
          : fn;
    }

    final result = functionOrValue(measure);
    sw.stop();
    return (result: result as T, elapsed: sw.elapsed);
  }
  // Case 2: Function was passed
  else if (functionOrValue is Function) {
    final sw = Stopwatch()..start();
    final result = functionOrValue();
    sw.stop();
    return (result: result as T, elapsed: sw.elapsed);
  }
  // Case 3: Direct value was passed
  else {
    return (result: functionOrValue as T, elapsed: Duration.zero);
  }
}