Opened 17 months ago

Closed 17 months ago

Last modified 15 months ago

#34517 closed Cleanup/optimization (fixed)

ImageField unnecessarily adds a post_init signal handler to the model

Reported by: Orhan Hirsch Owned by: Orhan Hirsch
Component: Database layer (models, ORM) Version: 4.2
Severity: Normal Keywords:
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

While debugging some performance issues in a Django app, I found a codepath where most of the time was being spent on initializing Django models after fetching from the DB. It turns out that 30% of the time was being spent on evaluating post_init signals because we were using ImageField. However, the post_init signal handler is a noop because we don't use the width_field / height_field.

If width_field and height_field are not set, removing the post_init signal should have no effect since the signal handler will return right away. Removing this signal handler gave us a 30-40% speedup on initializing models where ImageField was used.

Change History (7)

comment:1 by Orhan Hirsch, 17 months ago

Version: 4.14.2

comment:2 by Mariusz Felisiak, 17 months ago

Triage Stage: UnreviewedAccepted

Nice catch, thanks.

PR

comment:3 by Mariusz Felisiak, 17 months ago

Owner: changed from nobody to Orhan Hirsch
Status: newassigned

comment:4 by Mariusz Felisiak, 17 months ago

Needs tests: set

comment:5 by Mariusz Felisiak, 17 months ago

Needs tests: unset
Triage Stage: AcceptedReady for checkin

comment:6 by Mariusz Felisiak <felisiak.mariusz@…>, 17 months ago

Resolution: fixed
Status: assignedclosed

In ea53e7c:

Fixed #34517 -- Avoided connection post_init signal to ImageField without width/height fields.

comment:7 by Mariusz Felisiak <felisiak.mariusz@…>, 15 months ago

In bcacc63:

Refs #34517 -- Restored skipping ImageFileField.update_dimension_fields without width/height fields.

This avoids reading the image size when the dimensions fields
(image_width, image_height) do not exist, as that operation may be
expensive.

Partially reverts ea53e7c09f1b8864c20c65976bbeaeab77abdaec, that dropped
the check for the dimension fields in update_dimension_fields(), because
the post_init signal was no longer registered without dimension fields.

However, another code path to that function exists: when the
ImageFileField is save()d, the name from the storage is setattr()ed on
the field, and ImageFileDescriptor calls update_dimension_fields()
because the image size might have changed. Keep bailing out early when
dimensions are unused.

Besides, computing the image dimensions causes to close() the file,
resulting in a backward-incompatible change. The test protects against
that change.

Note: See TracTickets for help on using tickets.
Back to Top