Need for Speed: Removing speed bumps from your Symfony projects ⚡️
ukaszChruciel1
40 views
43 slides
Jun 07, 2024
Slide 1 of 88
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
About This Presentation
No one wants their application to drag like a car stuck in the slow lane! Yet it’s all too common to encounter bumpy, pothole-filled solutions that slow the speed of any application. Symfony apps are not an exception.
In this talk, I will take you for a spin around the performance racetrack. We’...
No one wants their application to drag like a car stuck in the slow lane! Yet it’s all too common to encounter bumpy, pothole-filled solutions that slow the speed of any application. Symfony apps are not an exception.
In this talk, I will take you for a spin around the performance racetrack. We’ll explore common pitfalls - those hidden potholes on your application that can cause unexpected slowdowns. Learn how to spot these performance bumps early, and more importantly, how to navigate around them to keep your application running at top speed.
We will focus in particular on tuning your engine at the application level, making the right adjustments to ensure that your system responds like a well-oiled, high-performance race car.
Size: 47.42 MB
Language: en
Added: Jun 07, 2024
Slides: 43 pages
Slide Content
Need for Speed
Removing speed bumps from your Symfony projects
Introduction
Weavers, Sylius
Why do we need to thinks
about performance?
~ Amazon
“100ms Faster
=
1% More Revenue.”
How?
Let’s start!
The most common performance bottlenecks
0
15
30
45
60
Amount of queries to DBCost of object serialization Latency Framework 54
28
56
Votes
Base
Algorithmic complexity
O(M) vs O(MN) vs O(M^2)
That’s why we usually forget
about it :/
Measure!
Understanding of tools
Tools are generally performant
But Your case is different
Project structure
Database turn
N+1
Product list
Let’s start small
{
"@context":"/api/contexts/Product",
"@id":"/api/products",
"@type":"hydra:Collection",
"hydra:totalItems":6,
"hydra:member":[
{
"@id":"/api/products/1",
"@type":"Product",
"id":1,
"name":"T-Shirt",
"price":1000
},
{
"@id":"/api/products/2",
"@type":"Product",
"id":2,
"name":"Trousers",
"price":5000
},
{
"“…“":"“…“"
}
]
}
Amount of products: 6
No associations between objects
Sample query on the left
O(1)
Order list
How many queries are executed here?
{
"@context": "/api/contexts/Order",
"@id": "/api/orders",
"@type": "hydra:Collection",
"hydra:totalItems": 3,
"hydra:member": [
{
"@id": "/api/orders/1",
"@type": "Order",
"id": 1,
"orderItems": [
"/api/order_items/1",
"/api/order_items/2"
]
},
{
“…”: “…“
}
]
}
Amount of orders: 3
Every order associated with 2 items
Sample query on the left
No total field
O(M)
Order list with additional field
How many queries are executed here?
{
"@context": "/api/contexts/Order",
"@id": "/api/orders",
"@type": "hydra:Collection",
"hydra:totalItems": 3,
"hydra:member": [
{
"@id": "/api/orders/1",
"@type": "Order",
"id": 1,
"orderItems": [
"/api/order_items/1",
"/api/order_items/2"
],
"total": 7000
},
{
“…”: “…“
}
]
}
Amount of orders: 3
Every order associated with 2 items
Sample query on the left
Added “total()” as a function of product
price and quantity of item
O(M*N) or O(M^2) !
How to spot it?
How to fix it?
Solution 1
#[ORM\OneToMany(fetch: ‘LAZY')]
#[ORM\OneToMany(fetch: ‘EXTRA_LAZY')]
#[ORM\OneToMany(fetch: ‘EAGER')]
What is the difference between them?
Profile Total time Network timeMemory usage Amount of queries
Reference build 1.1 s 562 ms 32.9 MB 500 ms / 134 rq
Profile with leftjoin 813 ms 511 ms 16.6 MB 456 ms / 54 rq
Profile with lazy translations833 ms 502 ms 27.3 MB 446 ms / 54 rq
Lazy vs Extra_Lazy
Straight of good
design
Huge objects are problem
Different representations
Minimising unnecessary
operations
Read model
shortcut
Saving data to different models
PUT REQUEST
Pre-computing
Sylius order
Saving read-optimised objects
Read models doesn’t have to
be models '
1. Store read models in key-value storage
2. Restore it by indexed key
Use “SELECT NEW” syntax
$query = $this->_em->createQuery(
'SELECT NEW OrderItemDTO(SUM(oi.quantity * p.price) FROM OrderItem oi JOIN oi.product p ’
);
$query->getResult(); // array of OrderItemDTO
Summary
Remember about algorithmic complexity of your queries
Do not hydrate too much data
Think out of the box of your “entities”