| 1 |
import timeit |
|---|
| 2 |
from django.dispatch import dispatcher |
|---|
| 3 |
|
|---|
| 4 |
if False: |
|---|
| 5 |
print "old" |
|---|
| 6 |
signal_recv_test = object() |
|---|
| 7 |
signal_noargs_test = object() |
|---|
| 8 |
signal_onearg_test = object() |
|---|
| 9 |
signal_tenargs_test = object() |
|---|
| 10 |
else: |
|---|
| 11 |
print "new" |
|---|
| 12 |
from django.dispatch import dispatcher |
|---|
| 13 |
signal_recv_test = dispatcher.Signal(providing_args=['arg0']) |
|---|
| 14 |
signal_noargs_test = dispatcher.Signal(providing_args=[]) |
|---|
| 15 |
signal_onearg_test = dispatcher.Signal(providing_args=['arg0']) |
|---|
| 16 |
signal_tenargs_test = dispatcher.Signal(providing_args=['arg%s' % i for i in range(10)]) |
|---|
| 17 |
|
|---|
| 18 |
def no_op_kwargs(**kwargs): |
|---|
| 19 |
pass |
|---|
| 20 |
|
|---|
| 21 |
def no_op_no_args(sender): |
|---|
| 22 |
pass |
|---|
| 23 |
|
|---|
| 24 |
def no_op_onearg(sender, arg0): |
|---|
| 25 |
pass |
|---|
| 26 |
|
|---|
| 27 |
def no_op_tenargs(sender, arg0,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9): |
|---|
| 28 |
pass |
|---|
| 29 |
|
|---|
| 30 |
|
|---|
| 31 |
def call_(i, f): |
|---|
| 32 |
for i in range(i): |
|---|
| 33 |
f() |
|---|
| 34 |
|
|---|
| 35 |
receivers = [] |
|---|
| 36 |
|
|---|
| 37 |
x = """ |
|---|
| 38 |
can add params |
|---|
| 39 |
multi-reg idempotent |
|---|
| 40 |
strip extra args to recv based on set -> dict (extensibility later. worth it?) |
|---|
| 41 |
error from signal handler breaks all signals (any push-back?) |
|---|
| 42 |
|
|---|
| 43 |
it's mildly annoying that a signal doesn't know its own name. |
|---|
| 44 |
using a dict for receivers means signals out-of-order. never promised, but still to be avoided if not huge diff? |
|---|
| 45 |
switch all core and contrib to signal.send rather than dispatcher.send? |
|---|
| 46 |
|
|---|
| 47 |
|
|---|
| 48 |
original, including pyc generation |
|---|
| 49 |
0 receivers test 2.16365003586 |
|---|
| 50 |
1 receiver test 18.8934309483 1.24702501297 |
|---|
| 51 |
10 receivers test 101.300621986 4.43934082985 |
|---|
| 52 |
|
|---|
| 53 |
weak dict, weak=True, keithb "faster_signals.diff" Mar 18 2008 |
|---|
| 54 |
0 receivers test 4.87185907364 |
|---|
| 55 |
1 receiver test 11.0454790592 0.341604948044 |
|---|
| 56 |
10 receivers test 52.751529932 4.38265109062 |
|---|
| 57 |
|
|---|
| 58 |
weak dict, weak=False, keithb "faster_signals.diff" Mar 18 2008 |
|---|
| 59 |
0 receivers test 4.82329916954 |
|---|
| 60 |
1 receiver test 11.550688982 0.359184026718 |
|---|
| 61 |
10 receivers test 60.9468040466 4.46081781387 |
|---|
| 62 |
|
|---|
| 63 |
weak_dict, including pyc generation |
|---|
| 64 |
0 receivers test 1.70886898041 |
|---|
| 65 |
1 receiver test 11.0185530186 1.23874211311 |
|---|
| 66 |
10 receivers test 50.5068600178 4.67185306549 |
|---|
| 67 |
|
|---|
| 68 |
strong_dict, including pyc generation |
|---|
| 69 |
0 receivers test 1.86286401749 |
|---|
| 70 |
1 receiver test 6.80570101738 1.24223089218 |
|---|
| 71 |
10 receivers test 23.5818219185 4.7426469326 |
|---|
| 72 |
|
|---|
| 73 |
strong_list, including pyc generation |
|---|
| 74 |
0 receivers test 2.36390304565 |
|---|
| 75 |
1 receiver test 6.74138212204 0.336266994476 |
|---|
| 76 |
10 receivers test 18.7774899006 4.27188205719 |
|---|
| 77 |
|
|---|
| 78 |
strong_list, including pyc generation; no api enforcement |
|---|
| 79 |
0 receivers test 2.36659097672 |
|---|
| 80 |
1 receiver test 4.90005588531 0.337324142456 |
|---|
| 81 |
10 receivers test 16.6197218895 4.20589017868 |
|---|
| 82 |
|
|---|
| 83 |
|
|---|
| 84 |
----- |
|---|
| 85 |
separately, comparing performance of argument matching: |
|---|
| 86 |
|
|---|
| 87 |
with arg matching: |
|---|
| 88 |
0 arg bench 6.56428813934 |
|---|
| 89 |
1 arg bench 7.65555596352 |
|---|
| 90 |
10 arg bench 19.9225678444 |
|---|
| 91 |
without arg matching: |
|---|
| 92 |
0 arg bench 5.6941409111 |
|---|
| 93 |
1 arg bench 6.54712295532 |
|---|
| 94 |
10 arg bench 16.4016561508 |
|---|
| 95 |
""" |
|---|
| 96 |
|
|---|
| 97 |
prep_timeit = """ |
|---|
| 98 |
from django.dispatch import dispatcher |
|---|
| 99 |
from __main__ import call_, no_op_kwargs, no_op_no_args |
|---|
| 100 |
from __main__ import signal_recv_test |
|---|
| 101 |
from __main__ import signal_noargs_test |
|---|
| 102 |
from __main__ import signal_onearg_test |
|---|
| 103 |
from __main__ import signal_tenargs_test |
|---|
| 104 |
""" |
|---|
| 105 |
|
|---|
| 106 |
###1) vary on receivers, accepting kwargs |
|---|
| 107 |
###2) vary on number of args, not accepting kwargs |
|---|
| 108 |
|
|---|
| 109 |
|
|---|
| 110 |
####1) vary on receivers, accepting kwargs: 0, 1, 10, 100 |
|---|
| 111 |
print "0 receivers test", timeit.Timer("dispatcher.send(signal_recv_test, arg0=1)", prep_timeit).timeit() |
|---|
| 112 |
print "0 receivers test direct", timeit.Timer("signal_recv_test.send(None, arg0=1)", prep_timeit).timeit() |
|---|
| 113 |
|
|---|
| 114 |
dispatcher.connect(no_op_kwargs, signal_recv_test) |
|---|
| 115 |
print "1 receiver test", timeit.Timer("dispatcher.send(signal_recv_test, arg0=1)", prep_timeit).timeit(), timeit.Timer("no_op_kwargs()", prep_timeit).timeit() |
|---|
| 116 |
print "1 receiver test direct", timeit.Timer("signal_recv_test.send(None, arg0=1)", prep_timeit).timeit(), timeit.Timer("no_op_kwargs()", prep_timeit).timeit() |
|---|
| 117 |
|
|---|
| 118 |
for i in range(9): |
|---|
| 119 |
def no_op_kwargs(**kwargs): |
|---|
| 120 |
pass |
|---|
| 121 |
receivers.append(no_op_kwargs) |
|---|
| 122 |
dispatcher.connect(no_op_kwargs, signal_recv_test) |
|---|
| 123 |
print "10 receivers test", timeit.Timer("dispatcher.send(signal_recv_test, arg0=1)", prep_timeit).timeit(), timeit.Timer("call_(10, no_op_kwargs)", prep_timeit).timeit() |
|---|
| 124 |
|
|---|
| 125 |
#for i in range(90): |
|---|
| 126 |
# def no_op_kwargs(**kwargs): |
|---|
| 127 |
# pass |
|---|
| 128 |
# receivers.append(no_op_kwargs) |
|---|
| 129 |
# dispatcher.connect(no_op_kwargs, signal_recv_test) |
|---|
| 130 |
#print "100 receivers test", timeit.Timer("dispatcher.send(signal_recv_test, arg0=1)", prep_timeit).timeit(), timeit.Timer("call_(100, no_op_kwargs)", prep_timeit).timeit() |
|---|
| 131 |
# |
|---|
| 132 |
|
|---|
| 133 |
####2) vary on number of args, not accepting |
|---|
| 134 |
dispatcher.connect(no_op_no_args, signal_noargs_test) |
|---|
| 135 |
dispatcher.connect(no_op_no_args, signal_onearg_test) |
|---|
| 136 |
dispatcher.connect(no_op_no_args, signal_tenargs_test) |
|---|
| 137 |
print "0 API enforce bench", timeit.Timer("dispatcher.send(signal_noargs_test)", prep_timeit).timeit(), timeit.Timer("no_op_no_args(None)", prep_timeit).timeit() |
|---|
| 138 |
print "1 API enforce bench", timeit.Timer("dispatcher.send(signal_onearg_test, arg0=1)", prep_timeit).timeit(), timeit.Timer("no_op_no_args(None)", prep_timeit).timeit() |
|---|
| 139 |
|
|---|
| 140 |
bench = timeit.Timer("dispatcher.send(signal_tenargs_test, %s)" % ','.join([("arg%s=%s" % (i,i)) for i in range(10)]), prep_timeit).timeit() |
|---|
| 141 |
lower = timeit.Timer("no_op_no_args(None)", prep_timeit).timeit() |
|---|
| 142 |
print "10 API enforce bench", bench, lower |
|---|
| 143 |
# |
|---|
| 144 |
#dispatcher.disconnect(no_op_no_args, signal_noargs_test) |
|---|
| 145 |
#dispatcher.disconnect(no_op_no_args, signal_onearg_test) |
|---|
| 146 |
#dispatcher.disconnect(no_op_no_args, signal_tenargs_test) |
|---|
| 147 |
# |
|---|
| 148 |
###3) vary on number of args, accepting |
|---|
| 149 |
dispatcher.connect(no_op_no_args, signal_noargs_test) |
|---|
| 150 |
dispatcher.connect(no_op_onearg, signal_onearg_test) |
|---|
| 151 |
dispatcher.connect(no_op_tenargs, signal_tenargs_test) |
|---|
| 152 |
print "0 arg bench", timeit.Timer("dispatcher.send(signal_noargs_test)", prep_timeit).timeit() |
|---|
| 153 |
print "1 arg bench", timeit.Timer("dispatcher.send(signal_onearg_test, arg0=1)", prep_timeit).timeit() |
|---|
| 154 |
print "10 arg bench", timeit.Timer("dispatcher.send(signal_tenargs_test, %s)" % ','.join([("arg%s=%s" % (i,i)) for i in range(10)]), prep_timeit).timeit() |
|---|