Benchmark.php 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. <?php
  2. namespace Illuminate\Support;
  3. use Closure;
  4. use Illuminate\Support\Traits\Macroable;
  5. class Benchmark
  6. {
  7. use Macroable;
  8. /**
  9. * Measure a callable or array of callables over the given number of iterations.
  10. *
  11. * @param \Closure|array $benchmarkables
  12. * @param int $iterations
  13. * @return array|float
  14. */
  15. public static function measure(Closure|array $benchmarkables, int $iterations = 1): array|float
  16. {
  17. return Collection::wrap($benchmarkables)->map(function ($callback) use ($iterations) {
  18. return Collection::range(1, $iterations)->map(function () use ($callback) {
  19. gc_collect_cycles();
  20. $start = hrtime(true);
  21. $callback();
  22. return (hrtime(true) - $start) / 1_000_000;
  23. })->average();
  24. })->when(
  25. $benchmarkables instanceof Closure,
  26. fn ($c) => $c->first(),
  27. fn ($c) => $c->all(),
  28. );
  29. }
  30. /**
  31. * Measure a callable once and return the result and duration in milliseconds.
  32. *
  33. * @template TReturn of mixed
  34. *
  35. * @param (callable(): TReturn) $callback
  36. * @return array{0: TReturn, 1: float}
  37. */
  38. public static function value(callable $callback): array
  39. {
  40. gc_collect_cycles();
  41. $start = hrtime(true);
  42. $result = $callback();
  43. return [$result, (hrtime(true) - $start) / 1_000_000];
  44. }
  45. /**
  46. * Measure a callable or array of callables over the given number of iterations, then dump and die.
  47. *
  48. * @param \Closure|array $benchmarkables
  49. * @param int $iterations
  50. * @return never
  51. */
  52. public static function dd(Closure|array $benchmarkables, int $iterations = 1): never
  53. {
  54. $result = (new Collection(static::measure(Arr::wrap($benchmarkables), $iterations)))
  55. ->map(fn ($average) => number_format($average, 3).'ms')
  56. ->when($benchmarkables instanceof Closure, fn ($c) => $c->first(), fn ($c) => $c->all());
  57. dd($result);
  58. }
  59. }