#14058: Weakly reference binary operation codomains
-----------------------------------+----------------------------------------
Reporter: robertwb | Owner: rlm
Type: enhancement | Status: needs_review
Priority: major | Milestone: sage-5.7
Component: memleak | Resolution:
Keywords: | Work issues:
Report Upstream: N/A | Reviewers:
Authors: Robert Bradshaw | Merged in:
Dependencies: | Stopgaps:
-----------------------------------+----------------------------------------
Comment (by nbruin):
Sadly, the performance hit is quite noticeable.
{{{
a=ZZ(1)
b=QQ(1)
c=ZZ['x'](1)
d=b+c
def test(x,y):
for i in xrange(10^6):
_=x+y
}}}
Within a run, timing `test` seems fairly consistent. However, between
different compiles of the same code I'm observing fluctuations of up to
`0.10s` in timings. Lucky/unlucky memory layout?
Anyway, with patch:
{{{
sage: %time test(a,b)
CPU times: user 2.15 s, sys: 0.00 s, total: 2.15 s
Wall time: 2.16 s
sage: %time test(a,c)
CPU times: user 2.25 s, sys: 0.00 s, total: 2.25 s
Wall time: 2.26 s
sage: %time test(b,c)
CPU times: user 16.83 s, sys: 0.00 s, total: 16.83 s
}}}
without patch
{{{
sage: %time test(a,b)
CPU times: user 1.54 s, sys: 0.00 s, total: 1.54 s
Wall time: 1.55 s
sage: %time test(a,c)
CPU times: user 1.64 s, sys: 0.00 s, total: 1.64 s
Wall time: 1.64 s
CPU times: user 15.68 s, sys: 0.00 s, total: 15.68 s
Wall time: 15.76 s
}}}
For `test(a,a)`, `test(b,b)`, `test(c,c)` there doesn't seem to be a
difference (luckily!)
The penalties seem to be about `0.6s`, `0.6s`, `1.2s`, which is rather
consistent with 1,1,2 extra lookups.
This indicates to me it may be worth trying storing a weakref to the
morphism instead, since that can probably be dereferenced faster than a
coercion lookup on the codomain. Logically this should be equivalent.
We're just storing a weakref to the object we're interested in rather than
instructions where to go and lookup the object we want.
Caveat:
For stored coercions of the type
`(R,S, ...): (None,<map S->R>)`
or
`(R,S, ...): (<map R->S>,None)`
the codomain is part of the key, so deletion of the codomain (which is a
prerequisite for the morphism being deleted and hence the weakref dying)
implies removal of the weak key entry in `TripleDict`.
However, for stored coercions of the type
`(R,S,...): (<map R->C>,<map S->C>)`
we could have that `C` and the weakrefs to the morphisms die, but that
would not trigger the removal from the `TripleDict`. So we could still
encounter dead weakrefs (but much less than one would perhaps initially
think!) It's not really much different from how [attachment:14058-weak-
binop.patch] handles dead weakrefs.
Major problem for immediately applying this idea:
{{{
sage: M=QQ.coerce_map_from(ZZ)
sage: import weakref
sage: weakref.ref(M)
TypeError: cannot create weak reference to 'sage.rings.rational.Z_to_Q'
object
}}}
--
Ticket URL: <http://trac.sagemath.org/sage_trac/ticket/14058#comment:4>
Sage <http://www.sagemath.org>
Sage: Creating a Viable Open Source Alternative to Magma, Maple, Mathematica,
and MATLAB
--
You received this message because you are subscribed to the Google Groups
"sage-trac" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sage-trac?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.