Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Performance: adds application snapshot and minimizes App::make #980

Open
wants to merge 32 commits into
base: 2.x
Choose a base branch
from

Conversation

AlliBalliBaba
Copy link
Contributor

This PR extends on #888 and might be better intended for a 3.x version. I'm merging to this branch anyways since 3.x doesn't exist yet and I want to share my findings.

Octane really improves upon Laravel's performance by keeping the Application instance in memory, but there are still a lot of areas for possible improvement. After creating some Flamegraphs with xhprof and a Laravel Octane 'Hello World', I noticed that a lot of request time is spent on Application::make(). Calling Application::make() seems to be ~250 times slower (JIT enabled) than accessing an object from an array even if it's just an instance registered with the container.

During a simple api request Application::make() is called many times, most notably once for each Event Listener and twice for each Middleware. It accounts for roughly 40% of time spent:

Flamegraph 2.x

xhprof-laravel-original-flamegraph

This PR re-introduces the Application 'snapshot' approach from #888, removes the default event listeners and accesses all initially registered Service Providers directly:

Flamegraph this PR

xhprof-flamegraph

As you can see, most of the slowdown from Application::make is removed. It now only accounts for ~20% of the request time spent. The speed improvement is also notable in a quick local benchmark (almost 50% more RPS):

wrk -t2 -c 120 http://localhost/hello-world 20 CPU cores dunglas/frankenphp Docker on WSL Ubuntu

Hello World (api middleware) Requests/second
2.x ~16000
This PR: ~24000
Simple Eloquent PDO PgSQL query Requests/second
2.x ~11000
This PR: ~14000

Can this be even faster?

I think with Octane's unique request flow it should in principle be possible to completely remove most of the overhead coming from Application::make(). Laravel's container implementation could be tweaked for faster access in long running processes by making writing to the container more expensive while reading from the container more efficient. What such an implementation might look like, I don't know yet though.

BC break

This PR will not break applications that use Octane in it's default state. The following lines will only break if users have attempted to unpack these event listeners manually (since the underlying Event Listeners do not exist anymore)

octane/config/octane.php

Lines 73 to 77 in ee88fe3

RequestReceived::class => [
...Octane::prepareApplicationForNextOperation(),
...Octane::prepareApplicationForNextRequest(),
//
],

If someone did indeed unpack these listeners, it was likely for performance reasons anyways.

Registering the application via a snapshot will also reduce the likelihood of memory leaks since the app instance does not change in-between requests (as explained in #888). The only BC break here could occur if users created a custom Application that extends the Laravel base application. Custom private fields on that application instance would not reset anymore between requests (not sure if this is something people even do).

a.stecher added 30 commits May 13, 2024 15:37
# Conflicts:
#	src/Concerns/ProvidesDefaultConfigurationOptions.php
#	src/Listeners/GiveNewApplicationInstanceToRouter.php
#	src/OctaneServiceProvider.php
@AlliBalliBaba AlliBalliBaba marked this pull request as ready for review January 5, 2025 22:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant