Ticket #4102: 4102-timings.2.py

File 4102-timings.2.py, 3.3 KB (added by SmileyChris, 8 years ago)

new properties method, faster than noop :)

Line 
1from timeit import Timer
2
3# A control model
4setup_a = '''
5class Model(object):
6    pass
7m = Model()
8'''
9
10# A model which has a __setattr__ which does nothing
11setup_b = '''
12class Model(object):
13    def __setattr__(self, name, value):
14        super(Model, self).__setattr__(name, value)
15m = Model()
16'''
17
18# A model which has a __setattr__ which matches this patch
19setup_c = '''
20class Model(object):
21    def __setattr__(self, name, value):
22        if name != '_modified_attrs' and (not hasattr(self, name) or
23                                          value != getattr(self, name)):
24            if hasattr(self, '_modified_attrs'):
25                if name not in self._modified_attrs:
26                    self._modified_attrs.add(name)
27            else:
28                self._modified_attrs = set((name,))
29        super(Model, self).__setattr__(name, value)
30m = Model()
31'''
32
33# Optimized for speed, and dropped the value check as Brian suggested
34setup_d = '''
35class Model(object):
36    def __setattr__(self, name, value):
37        try:
38            if name not in self._modified_attrs:
39                self._modified_attrs.add(name)
40        except AttributeError:
41            if name != '_modified_attrs':
42                self._modified_attrs = set((name,))
43        super(Model, self).__setattr__(name, value)
44m = Model()
45'''
46
47# A model which has uses properties to track changes
48# Bonus: only field access would be tracked this way
49setup_e = '''
50def track_property(klass, name):
51    p = '_p_%s' % name
52    def fget(o):
53        getattr(o, p)
54    def fset(o, value):
55        set_modified(o)
56        setattr(o, p, value)
57    def set_modified(o):
58        try:
59            if name not in o._modified_attrs:
60                o._modified_attrs.add(name)
61        except AttributeError:
62            o._modified_attrs = set((name,))
63    setattr(klass, name, property(fget, fset))
64class Model(object):
65    def __init__(self):
66        track_property(self.__class__, 'an_attribute')
67        track_property(self.__class__, 'another_attribute')
68m = Model()
69'''
70
71setup_a1 = setup_a + '''
72m.another_attribute="test"
73'''
74
75setup_b1 = setup_b + '''
76m.another_attribute="test"
77'''
78
79setup_c1 = setup_c + '''
80m.another_attribute="test"
81'''
82
83setup_d1 = setup_d + '''
84m.another_attribute="test"
85'''
86
87setup_e1 = setup_e + '''
88m.another_attribute="test"
89'''
90
91def timed(t, control=None):
92    if control is None:
93        return '%.3f' % (t)
94    return '%.3f (%.1fx)' % (t, t/control)
95
96print "Single Assignment"
97test = 'm.an_attribute="test"'
98control = Timer(test, setup_a).timeit()
99print "Control:  ", timed(control)
100print "noop:     ", timed(Timer(test, setup_b).timeit(), control)
101print "patch:    ", timed(Timer(test, setup_c).timeit(), control)
102print "optimized:", timed(Timer(test, setup_d).timeit(), control)
103print "property: ", timed(Timer(test, setup_e).timeit(), control)
104print
105print "Double Assignment"
106test = 'm.an_attribute="test";m.another_attribute="test"'
107control = Timer(test, setup_a).timeit()
108print "Control:  ", timed(control)
109print "noop:     ", timed(Timer(test, setup_b).timeit(), control)
110print "patch:    ", timed(Timer(test, setup_c).timeit(), control)
111print "optimized:", timed(Timer(test, setup_d).timeit(), control)
112print "property: ", timed(Timer(test, setup_e).timeit(), control)
Back to Top