Hi all,

I've just uploaded a patch for #5390, which adds signals to
many-to-many modifying operations.

This is a ticket that was a low-priority accepted item for 1.1
(ORM-18), but got bumped due to time [1]. For some reason, it wasn't
resubmitted for 1.2.

The purpose of this post is twofold:

1) To establish if there are any objections to introducing this
signal. Historically, there has been a performance objection to adding
new signals, so I want to give some numbers of the performance impact
and see if anyone objects. and

2) To get feedback on the implementation.

Barring objections or major design changes, I'd like to commit this
early next week.

1. Performance
--------------

The last time signals came up [2], Jacob provided some helpful
baseline data on the speed of signals:

Doing Nothing: 0.00283 (0.000000028 per call)
Plain func call: 0.07054 (0.000000705 per call)
Signal; 0 handlers: 0.09331 (0.000000933 per call)
Signal; 1 handler : 0.79125 (0.000007912 per call)
Signal; 10 handlers: 3.36051 (0.000033605 per call)
Signal; 100 handlers: 27.56269 (0.000275627 per call)

* In Python, calling a function (``handle()``) takes 25 times as long
as doing nothing (``pass``).
* Dispatching a signal when there's no handlers is about 1.3 times a
function call.
* Dispatching a signal when there's one handler is about 11 times the
cost of a function call.
* Addition of additional receivers scales linearly.

The other (completely unscientific) test is the Django test suite
itself. I've run the test suite with and without the patch from #5390.
What I have observed is that the discrepancies in test runtime caused
by normal fluctuations in background system load are more significant
than the slowdown caused by adding m2m signals (that is - the vanilla
suite sometimes takes *longer* than the suite with the patch applied).

So - based on my this analysis, there is a performance impact, but it
isn't especially significant or noticeable.

2. Implementation
-----------------

The patch I have uploaded [3] introduces a single new signal -
m2m_changed. This decision is based on design feedback from Malcolm
[4].

The signal is attached to the m2m through class (the automatically
generated m2m class that is the result of the m2m refactor). This
class is the 'sender' of the signal.

The signal handler is provided with the sender, as well as:
 * The instance that contains the m2m field that is being modified
 * A string tag indicating if this is an "add", "remove" or "clear" call
 * A boolean indicating whether this is the 'forward' or 'reverse' relation.
 * The class of model that is being added/removed/cleared
 * The primary keys of the instances that are being added to the
relation (or None in the case of a call to clear the relation)

The docs and tests on the patch [3] give a more detailed description
and examples of the operation of the signal.

Any feedback on this design?

[1] http://code.djangoproject.com/wiki/Version1.1Features
[2] 
http://groups.google.com/group/django-developers/browse_thread/thread/5a39839e2aa8df53
[3] http://code.djangoproject.com/attachment/ticket/5390/t5390-r12120.1.diff
[4] 
http://groups.google.com/group/django-developers/browse_thread/thread/afe6ad7994d868ba

Yours,
Russ Magee %-)
-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.


Reply via email to