Benchmarking Laravel Helpers: A Performance Comparison

mujiciok

mujiciok

Posted on April 30, 2023

Benchmarking Laravel Helpers: A Performance Comparison

Laravel is one of the most popular PHP frameworks available today, offering a vast array of built-in helpers to make developers' lives easier. However, when it comes to optimizing the performance of your Laravel application, it's essential to know which helper functions work best in different scenarios.

What are Laravel helpers?

Laravel helpers are simple functions that provide a convenient way to perform common tasks. They are included in the framework and can be called from anywhere in your application. Helpers are designed to be lightweight and easy to use, but their performance can vary depending on the task at hand.


How it started?

It all began with a simple pull request where I suggested a small change to the usage of a Laravel helper function, in order to make it a bit cleaner. In response, I was told that the suggested change was actually slower, which I agreed to.

But that opened a question for me -  how much slower it actually is? This question piqued my curiosity and I decided to run some benchmarks to see just how much slower it was. Some of the results were surprising to say the least.


In the following section, we'll dive into benchmarking Laravel helpers, outlining the steps I took to test and compare their performance against some alternative methods.

Creating a benchmark project

The first step was to create a Github repository - laravel-benchmarks - to host the benchmarking code. In order to benchmark Laravel helpers, I created a Laravel project using Laravel v10.9 and Sail. To run benchmarks on your local machine, follow the instructions from the Github repository.

Creating a benchmark class

To ensure consistent and accurate benchmarking, I created a class for each Laravel helper benchmark that I wanted to run. Each class contains some methods which will be tested and have benchmarks. I chose to test each Laravel helper against alternative methods, like regex functions or other native PHP functions.

Writing unit tests

For each benchmark class, I wrote a corresponding unit test, which runs on 10, 100, 1.000, 10.000, 100.000 and 1.000.000 iterations for each tested method. I used Laravel's Benchmark class to get average time, in nanoseconds, for each method.

    public function benchmark(string $haystack, string $needle): void
    {
        $logData = [];
        // a mapping of method names from BenchmarkService to output table rows names
        $methodsData = $this->getMethods();
        // a mapping of number of iterations to output table column names
        $iterationsData = $this->getIterations();
        // the tested service 
        $service = $this->getBenchmarkService();

        foreach ($methodsData as $methodName => $rowHeading) {
            foreach ($iterationsData as $iterations => $columnHeading) {
                // this Benchmark::measure will return the time spent on each method call for a given number of iterations
                $logData[$rowHeading][$columnHeading] =
                    Benchmark::measure(fn() => $service->{$methodName}($haystack, $needle), $iterations);
            }
        }

        // the function that converts received data into a README table format
        $this->logTable($logData);

        $this->assertTrue(true);
    }

Enter fullscreen mode Exit fullscreen mode

I also included a validation test to ensure that all methods in the benchmark class had the same functionality (at least for the tested cases).

Logging and sharing results

After running the benchmarks, I output the results to the Laravel's log file, which I then copied and inserted into a README file for each benchmark class. To present the benchmarking results in a clear and concise format, I created a small trait that converts the test results into a table format that is compatible with the README file (see example below).

x10 x100 x1_000 x10_000 x100_000 x1_000_000
Str::endsWith 0.0024561 0.00190203 0.001714902 0.0017067036 0.00171911167 0.0016987282409992
preg_match 0.0046733 0.00142272 0.001386046 0.0014287932 0.00145006377 0.0014515480600005
str_ends_with 0.0013112 0.00099935 0.000994674 0.0010140036 0.00100748115 0.0010328349029996

To make it easy for others to navigate the benchmarking results, I included links to each benchmark class README file in the main README for the repository.


I hope this article has been helpful in your quest for optimal performance in your Laravel applications. Don't be afraid to test the project locally and experiment with your own benchmarks. You're also welcome to suggest new benchmarks, test cases etc. Who knows, you might discover some surprising results (please share them) that will help you write even more efficient code!

Happy coding! 
:)

💖 💪 🙅 🚩
mujiciok
mujiciok

Posted on April 30, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related