`contrib.rest_framework.PictureField` serialization is slow
amureki opened this issue · comments
Greetings Johannes!
While doing bulk operations with images that involved this library, I noticed a noticeable difference in the serialization time compared to the standard DRF library.
Here is a quick snippet that I am trying:
import time
from django.db import models
from pictures.contrib.rest_framework import PictureField as PictureFieldRest
from rest_framework.fields import ImageField as DRFImageField
class MyPicture(models.Model):
image = PictureField(
aspect_ratios=["3/2", "1/1", "15/2"],
file_types=["WEBP", "JPEG"],
width_field="image_width",
height_field="image_height",
)
image_width = models.PositiveSmallIntegerField(editable=False)
image_height = models.PositiveSmallIntegerField(editable=False)
def test_serialization_speed():
items_count = 5000
start = time.time()
serialized = []
for item in MyPicture.objects.all()[:items_count]:
serialized.append(
DRFImageField().to_representation(item.image)
)
print("DRF ImageField serialization TIME: ", time.time() - start)
start = time.time()
serialized = []
for item in MyPicture.objects.all()[:items_count]:
serialized.append(
PictureFieldRest().to_representation(item.image)
)
print("PictureField serialization TIME: ", time.time() - start)
The results on my dev machine (MacBook M1, 16 Gb) are the following:
DRF ImageField serialization TIME: 0.11259627342224121
PictureField serialization TIME: 11.82898998260498
I believe that the issue comes from the serialization of this part:
https://github.com/codingjoe/django-pictures/blob/main/pictures/contrib/rest_framework.py#L25-L38
We have plenty of combinations of aspect ratios and containers, each of them has to be serialized from SimplePicture
object to its url, which leads to a heavy CPU-bound operation.
However, I cannot yet come up with the solution to that problem.
Would you have any ideas on this?
Best,
Rust
@amureki, as a see it, we currently render the ratios part of the payload twice if you declare a specific ratio. We first serialize everything and overwrite it later. Avoiding this could resolve in a considerable performance boost. Would you care to provide a patch?