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()
|
---|