#36858: Optimize `db_default` creation
-------------------------------------+-------------------------------------
Reporter: Adam | Owner: Adam Johnson
Johnson |
Type: | Status: assigned
Cleanup/optimization |
Component: Database | Version: dev
layer (models, ORM) |
Severity: Normal | Keywords:
Triage Stage: | Has patch: 1
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
Currently, `Field._get_default()` returns a `lambda` that instantiates a
new `DatabaseDefault` each time it is called. This expression is identical
each time, so this work is wasted. We can optimize it by creating a single
expression that is returned each time.
Thanks to Adam Sołtysik for the hint in https://forum.djangoproject.com/t
/faster-bulk-create-using-dictionaries/43891
Benchmarked with a quick modification to the test suite:
{{{#!diff
diff --git ./tests/bulk_create/tests.py ./tests/bulk_create/tests.py
index 397fcb9186..ddfe315c0c 100644
--- ./tests/bulk_create/tests.py
+++ ./tests/bulk_create/tests.py
@@ -877,6 +877,16 @@ def test_db_default_field_excluded(self):
2 if connection.features.can_return_rows_from_bulk_insert
else 1,
)
+
+ def test_benchmark(self):
+ import time
+ start = time.perf_counter()
+ DbDefaultModel.objects.bulk_create(
+ [DbDefaultModel(name=f"obj {i}") for i in range(100_000)]
+ )
+ end = time.perf_counter()
+ print(f"{end - start:.3f} seconds")
+
@skipUnlessDBFeature(
"can_return_rows_from_bulk_insert",
"supports_expression_defaults"
)
}}}
Run with:
{{{
./runtests.py --parallel 1
bulk_create.tests.BulkCreateTests.test_benchmark -v 0
System check identified no issues (0 silenced).
0.617 seconds
----------------------------------------------------------------------
Ran 1 test in 0.618s
OK
}}}
Results, best of 3:
Before: 0.691 seconds
After: 0.610 seconds
A ~12% speedup on this `bulk_create()` operation, on a model with a single
`db_default` field.
--
Ticket URL: <https://code.djangoproject.com/ticket/36858>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion visit
https://groups.google.com/d/msgid/django-updates/0107019baf6118cf-293d0496-f57f-47f7-8a39-c5c8a06b4f44-000000%40eu-central-1.amazonses.com.