#14585: Make lazy_format and lazy_string faster
------------------------------+--------------------------
Reporter: SimonKing | Owner: robertwb
Type: defect | Status: needs_work
Priority: major | Milestone: sage-6.4
Component: coercion | Resolution:
Keywords: | Merged in:
Authors: Simon King | Reviewers:
Report Upstream: N/A | Work issues:
Branch: | Commit:
Dependencies: | Stopgaps:
------------------------------+--------------------------
Description changed by nbruin:
Old description:
> At [https://groups.google.com/forum/?fromgroups=#!topic/sage-devel
> /Gnw389Bd-0k sage-devel], Nils suggests to use some kind of lazy object
> for the error messages of errors that are deeply buried in the coercion
> model.
>
> This approach is similar to what we already do with
> `sage.structure.misc.AttributeErrorMassage`. However, this is
> specifically restricted to error messages of attribute errors. In the
> more general case, it makes sense to use either
> `sage.misc.lazy_format.LazyFormat` or
> `sage.misc.lazy_string.lazy_string`. The latter seems to be faster,
> according to these timings that are according to Nils' example:
> {{{
> sage: from sage.misc.lazy_string import lazy_string
> sage: f = lambda op,A,B:"unsupported operand parent(s) for '%s': '%s' and
> '%s'"%(op,A,B)
> sage: R = GF(5)
> sage: S = GF(3)
> sage: %timeit Exception(lazy_string(f, '+', R, S))
> 1000000 loops, best of 3: 1.47 us per loop
> sage: lazy_string(f, '+', R, S)
> l"unsupported operand parent(s) for '+': 'Finite Field of size 5' and
> 'Finite Field of size 3'"
> sage: %timeit Exception("unsupported operand parent(s) for '%s': '%s' and
> '%s'"%('+', R, S))
> 100000 loops, best of 3: 5.04 us per loop
> sage: from sage.misc.lazy_format import LazyFormat
> sage: ErrMess = LazyFormat("unsupported operand parent(s) for '%s': '%s'
> and '%s'")
> sage: %timeit Exception(ErrMess%('+', R, S))
> 10000 loops, best of 3: 23.1 us per loop
> sage: ErrMess%('+', R, S)
> unsupported operand parent(s) for '+': 'Finite Field of size 5' and
> 'Finite Field of size 3'
> }}}
>
> So, it would already make sense to replace all error messages using
> string formatting by a call to `lazy_string`, while `LazyFormat` seems to
> be quite sluggish.
>
> Two tasks:
> 1. Make `lazy_string` and `LazyFormat` a lot faster (perhaps by using
> Cython)
> 2. Use it for errors raised when trying to find coercions. The problem is
> particularly urgent if the string representation of an object is
> difficult to compute.
>
> '''__Note__'''
>
> For the second task, we meanwhile have #14592
>
> Apart from making coercion faster, there is the following problem that we
> would fix as well. Consider creation of a parent. It may happen that
> relatively early during initialisation, a coercion is needed, but only
> later, the string representation of the parent will become available.
> Hence, if there is an error raised (and caught) inside of the coercion
> system that relies on the string representation of the parent, then we
> are in trouble.
>
> __Apply__
>
> [attachment:trac14585-cythoned_lazy_string.patch]
New description:
At [https://groups.google.com/forum/?fromgroups=#!topic/sage-devel
/Gnw389Bd-0k sage-devel], Nils suggests to use some kind of lazy object
for the error messages of errors that are deeply buried in the coercion
model.
This approach is similar to what we already do with
`sage.structure.misc.AttributeErrorMassage`. However, this is specifically
restricted to error messages of attribute errors. In the more general
case, it makes sense to use either `sage.misc.lazy_format.LazyFormat` or
`sage.misc.lazy_string.lazy_string`. The latter seems to be faster,
according to these timings that are according to Nils' example:
{{{
sage: from sage.misc.lazy_string import lazy_string
sage: f = lambda op,A,B:"unsupported operand parent(s) for '%s': '%s' and
'%s'"%(op,A,B)
sage: R = GF(5)
sage: S = GF(3)
sage: %timeit Exception(lazy_string(f, '+', R, S))
1000000 loops, best of 3: 1.47 us per loop
sage: lazy_string(f, '+', R, S)
l"unsupported operand parent(s) for '+': 'Finite Field of size 5' and
'Finite Field of size 3'"
sage: %timeit Exception("unsupported operand parent(s) for '%s': '%s' and
'%s'"%('+', R, S))
100000 loops, best of 3: 5.04 us per loop
sage: from sage.misc.lazy_format import LazyFormat
sage: ErrMess = LazyFormat("unsupported operand parent(s) for '%s': '%s'
and '%s'")
sage: %timeit Exception(ErrMess%('+', R, S))
10000 loops, best of 3: 23.1 us per loop
sage: ErrMess%('+', R, S)
unsupported operand parent(s) for '+': 'Finite Field of size 5' and
'Finite Field of size 3'
}}}
We're better off making a fresh `LazyFormat` object every time, due to an
inefficiency in the copying operation required for rebinding such an
object:
{{{
sage: %timeit LazyFormat("unsupported operand parent(s) for '%s': '%s' and
'%s'")%('+', R, S)
1000000 loops, best of 3: 2.08 µs per loop
}}}
Luckily, present use of `LazyFormat` follows this pattern.
So, it would already make sense to replace all error messages using string
formatting by a call to `lazy_string`, while `LazyFormat` seems to be
quite sluggish.
Two tasks:
1. Make `lazy_string` and `LazyFormat` a lot faster (perhaps by using
Cython)
2. Use it for errors raised when trying to find coercions. The problem is
particularly urgent if the string representation of an object is difficult
to compute.
'''__Note__'''
For the second task, we meanwhile have #14592
Apart from making coercion faster, there is the following problem that we
would fix as well. Consider creation of a parent. It may happen that
relatively early during initialisation, a coercion is needed, but only
later, the string representation of the parent will become available.
Hence, if there is an error raised (and caught) inside of the coercion
system that relies on the string representation of the parent, then we are
in trouble.
__Apply__
[attachment:trac14585-cythoned_lazy_string.patch]
--
--
Ticket URL: <http://trac.sagemath.org/ticket/14585#comment:35>
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.
For more options, visit https://groups.google.com/d/optout.