Skip to content

Instantly share code, notes, and snippets.

@radix
Created February 4, 2015 20:26
Show Gist options
  • Select an option

  • Save radix/a3d3234122e1e553f431 to your computer and use it in GitHub Desktop.

Select an option

Save radix/a3d3234122e1e553f431 to your computer and use it in GitHub Desktop.
Pyrsistent PRecord vs POPO copy+mutate
from __future__ import print_function
import copy
from pyrsistent import PRecord, field
NUM_FIELDS = 20
def make_pfoo(attr_names):
field_decls = [' %s = field()' % (attr,) for attr in attr_names]
stmt = """
class PFoo(PRecord):
""" + '\n'.join(field_decls)
print(stmt)
return stmt
def make_sfoo(attr_names):
assignments = [' self.{arg} = {arg}'.format(arg=arg)
for arg in attr_names]
stmt = """
class SFoo(object):
def __init__(self, {args}):
{assignments}
""".format(args=', '.join(attr_names),
assignments='\n'.join(assignments))
print(stmt)
return stmt
def make_attr_names(num_attrs):
return ['field%s' % (x,) for x in xrange(num_attrs)]
attrs = make_attr_names(NUM_FIELDS)
exec make_pfoo(attrs)
exec make_sfoo(attrs)
def obj_assoc(obj, **changes):
new_obj = copy.copy(obj)
new_obj.__dict__.update(changes)
return new_obj
def standard_obj_updates():
obj = SFoo(*attrs)
for x in xrange(1000):
for attr in attrs:
new_obj = obj_assoc(obj, **{attr: 'newval'})
def pyrsistent_obj_updates():
kwargs = {name: name for name in attrs}
obj = PFoo(**kwargs)
for x in xrange(1000):
for attr in attrs:
new_obj = obj.set(**{attr: 'newval'})
import timeit
print("standard obj_assoc:", timeit.repeat(standard_obj_updates, number=10))
print("PRecord .set: ", timeit.repeat(pyrsistent_obj_updates, number=10))
@radix
Copy link
Copy Markdown
Author

radix commented Feb 5, 2015

Results on my laptop:

CPython, 5 fields:

standard obj_assoc: [0.32765984535217285, 0.3334388732910156, 0.32717204093933105]
PRecord .set:       [0.5966939926147461, 0.6018130779266357, 0.6318011283874512]

PyPy, 5 fields:

standard obj_assoc: [0.09314703941345215, 0.05125880241394043, 0.05225110054016113]
PRecord .set:       [0.3770010471343994, 0.09182596206665039, 0.10466790199279785]

CPython, 10 fields:

standard obj_assoc: [0.6919431686401367, 0.6766328811645508, 0.6735780239105225]
PRecord .set:       [1.1574161052703857, 1.1625089645385742, 1.1608970165252686]

PyPy, 10 fields:

standard obj_assoc: [0.22065401077270508, 0.17265105247497559, 0.18462610244750977]
PRecord .set:       [0.5249049663543701, 0.19779682159423828, 0.19316601753234863]

CPython, 20 fields:

standard obj_assoc: [1.373690128326416, 1.373378038406372, 1.3727550506591797]
PRecord .set:       [2.3381059169769287, 2.427654981613159, 2.313516855239868]

PyPy, 20 fields:

standard obj_assoc: [0.7498619556427002, 0.7101671695709229, 0.7196140289306641]
PRecord .set:       [0.706528902053833, 0.37665390968322754, 0.4166889190673828]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment