| 1 |
from timeit import Timer |
|---|
| 2 |
|
|---|
| 3 |
# A control model |
|---|
| 4 |
setup_a = ''' |
|---|
| 5 |
class Model(object): |
|---|
| 6 |
pass |
|---|
| 7 |
m = Model() |
|---|
| 8 |
''' |
|---|
| 9 |
|
|---|
| 10 |
# A model which has a __setattr__ which does nothing |
|---|
| 11 |
setup_b = ''' |
|---|
| 12 |
class Model(object): |
|---|
| 13 |
def __setattr__(self, name, value): |
|---|
| 14 |
super(Model, self).__setattr__(name, value) |
|---|
| 15 |
m = Model() |
|---|
| 16 |
''' |
|---|
| 17 |
|
|---|
| 18 |
# A model which has a __setattr__ which matches this patch |
|---|
| 19 |
setup_c = ''' |
|---|
| 20 |
class 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) |
|---|
| 30 |
m = Model() |
|---|
| 31 |
''' |
|---|
| 32 |
|
|---|
| 33 |
# Optimized for speed, and dropped the value check as Brian suggested |
|---|
| 34 |
setup_d = ''' |
|---|
| 35 |
class 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) |
|---|
| 44 |
m = Model() |
|---|
| 45 |
''' |
|---|
| 46 |
|
|---|
| 47 |
setup_a1 = setup_a + ''' |
|---|
| 48 |
m.another_attribute="test" |
|---|
| 49 |
''' |
|---|
| 50 |
|
|---|
| 51 |
setup_b1 = setup_b + ''' |
|---|
| 52 |
m.another_attribute="test" |
|---|
| 53 |
''' |
|---|
| 54 |
|
|---|
| 55 |
setup_c1 = setup_c + ''' |
|---|
| 56 |
m.another_attribute="test" |
|---|
| 57 |
''' |
|---|
| 58 |
|
|---|
| 59 |
setup_d1 = setup_d + ''' |
|---|
| 60 |
m.another_attribute="test" |
|---|
| 61 |
''' |
|---|
| 62 |
|
|---|
| 63 |
print "Single Assignment" |
|---|
| 64 |
print "Control: ", Timer('m.an_attribute="test"', setup_a).timeit() |
|---|
| 65 |
print "noop: ", Timer('m.an_attribute="test"', setup_b).timeit() |
|---|
| 66 |
print "patch: ", Timer('m.an_attribute="test"', setup_c).timeit() |
|---|
| 67 |
print "optimized:", Timer('m.an_attribute="test"', setup_d).timeit() |
|---|
| 68 |
print |
|---|
| 69 |
print "Double Assignment" |
|---|
| 70 |
print "Control: ", Timer('m.an_attribute="test"', setup_a1).timeit() |
|---|
| 71 |
print "Noop: ", Timer('m.an_attribute="test"', setup_b1).timeit() |
|---|
| 72 |
print "Patch: ", Timer('m.an_attribute="test"', setup_c1).timeit() |
|---|
| 73 |
print "Optimized:", Timer('m.an_attribute="test"', setup_d1).timeit() |
|---|