Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preallocate pmap according to PRecord fields count #218

Merged
merged 1 commit into from
Jun 5, 2021

Conversation

kkpattern
Copy link

Since the fields in a PRecord is fixed, the total size of the PMap in the record is already known before allocating the map. We can use the length of _precord_fields to pre-allocate the map to avoid reallocating later.

For example, if we add a log in _reallocate and give the following test code:

from pyrsistent import field
from pyrsistent import PRecord


class DRecord(PRecord):
    a = field()
    b = field()
    c = field()
    d = field()
    e = field()
    f = field()
    g = field()
    h = field()
    i = field()
    j = field()
    k = field()
    m = field()
    n = field()
    o = field()
    p = field()
    q = field()


r = DRecord()
for k in ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "m", "n", "o", "p", "q"]:
    r = r.set(k, 1)
    print(r)

Without the pre-allocating, the output will be:

DRecord(a=1)
DRecord(b=1, a=1)
DRecord(c=1, b=1, a=1)
DRecord(c=1, b=1, d=1, a=1)
DRecord(c=1, b=1, e=1, d=1, a=1)
DRecord(f=1, c=1, b=1, e=1, d=1, a=1)
DRecord(f=1, c=1, g=1, b=1, e=1, d=1, a=1)
DRecord(f=1, c=1, g=1, b=1, h=1, e=1, d=1, a=1)
DRecord(f=1, c=1, g=1, i=1, b=1, h=1, e=1, d=1, a=1)
DRecord(f=1, c=1, g=1, i=1, b=1, j=1, h=1, e=1, d=1, a=1)
DRecord(f=1, c=1, g=1, i=1, b=1, k=1, j=1, h=1, e=1, d=1, a=1)
DRecord(f=1, c=1, g=1, i=1, b=1, k=1, j=1, h=1, e=1, d=1, a=1, m=1)
_reallocate
DRecord(g=1, i=1, b=1, h=1, d=1, a=1, n=1, f=1, c=1, k=1, j=1, e=1, m=1)
DRecord(g=1, i=1, b=1, h=1, d=1, a=1, n=1, f=1, c=1, k=1, j=1, e=1, o=1, m=1)
DRecord(g=1, i=1, b=1, p=1, h=1, d=1, a=1, n=1, f=1, c=1, k=1, j=1, e=1, o=1, m=1)
DRecord(g=1, i=1, b=1, p=1, h=1, d=1, a=1, q=1, n=1, f=1, c=1, k=1, j=1, e=1, o=1, m=1)

And with the pre-allocating, the reallocating is avoided:

DRecord(a=1)
DRecord(a=1, b=1)
DRecord(c=1, a=1, b=1)
DRecord(c=1, a=1, b=1, d=1)
DRecord(c=1, a=1, b=1, d=1, e=1)
DRecord(c=1, a=1, b=1, d=1, f=1, e=1)
DRecord(c=1, a=1, b=1, d=1, f=1, e=1, g=1)
DRecord(c=1, a=1, b=1, d=1, f=1, e=1, h=1, g=1)
DRecord(i=1, c=1, a=1, b=1, d=1, f=1, e=1, h=1, g=1)
DRecord(i=1, c=1, a=1, b=1, d=1, f=1, e=1, h=1, j=1, g=1)
DRecord(i=1, c=1, a=1, b=1, d=1, k=1, f=1, e=1, h=1, j=1, g=1)
DRecord(i=1, c=1, a=1, b=1, d=1, k=1, m=1, f=1, e=1, h=1, j=1, g=1)
DRecord(i=1, c=1, a=1, b=1, d=1, k=1, m=1, f=1, n=1, e=1, h=1, j=1, g=1)
DRecord(i=1, c=1, a=1, b=1, d=1, k=1, m=1, f=1, n=1, e=1, h=1, j=1, g=1, o=1)
DRecord(i=1, c=1, a=1, b=1, d=1, k=1, m=1, f=1, n=1, e=1, p=1, h=1, j=1, g=1, o=1)
DRecord(i=1, c=1, q=1, a=1, b=1, d=1, k=1, m=1, f=1, n=1, e=1, p=1, h=1, j=1, g=1, o=1)

@tobgu
Copy link
Owner

tobgu commented Jun 5, 2021

Thanks, nice little improvement!

@tobgu tobgu merged commit 97c6309 into tobgu:master Jun 5, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants