Unreasonably slow piecewise function

121 views
Skip to first unread message

Kwankyu Lee

unread,
May 1, 2024, 5:21:22 AMMay 1
to sage-devel
Hi,

I get

sage: f = piecewise([((0,1),1)])
sage: time f(0.1)
CPU times: user 135 ms, sys: 4.23 ms, total: 140 ms
Wall time: 146 ms
1
sage: time f(0.2)
CPU times: user 133 ms, sys: 3.56 ms, total: 136 ms
Wall time: 137 ms
1

This is painfully slow. Is this normal?

David Joyner

unread,
May 1, 2024, 9:38:36 AMMay 1
to sage-...@googlegroups.com
For another data point, on an ubuntu laptop:

sage: time [f(0.1*i) for i in range(1,10)]
CPU times: user 136 ms, sys: 0 ns, total: 136 ms
Wall time: 99.1 ms
[1, 1, 1, 1, 1, 1, 1, 1, 1]
sage: time f(0.1)
CPU times: user 13.6 ms, sys: 0 ns, total: 13.6 ms
Wall time: 13.5 ms
1
sage: version()
'SageMath version 10.3.rc1, Release Date: 2024-02-29'
> --
> You received this message because you are subscribed to the Google Groups "sage-devel" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to sage-devel+...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/sage-devel/af2161ba-1ee9-4636-9cea-98ea6031796bn%40googlegroups.com.

Nils Bruin

unread,
May 1, 2024, 11:37:44 AMMay 1
to sage-devel
Working on *why* it might be so slow a bit:

%prun for i in range(100r): f(0.1)
         798103 function calls (791903 primitive calls) in 1.327 seconds

   Ordered by: internal time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
     8000    0.556    0.000    0.628    0.000 maxima_lib.py:438(_eval_line)
      100    0.299    0.003    1.318    0.013 piecewise.py:188(_subs_)
    16000    0.059    0.000    0.067    0.000 {method 'random_element' of 'sage.rings.real_mpfi.RealIntervalField_class' objects}
     1700    0.054    0.000    0.060    0.000 maxima_lib.py:298(max_to_string)
   232200    0.032    0.000    0.048    0.000 calculus.py:2204(_is_function)
      900    0.028    0.000    0.050    0.000 calculus.py:2319(<dictcomp>)
     2700    0.024    0.000    0.024    0.000 {built-in method sage.libs.ecl.ecl_eval}
      900    0.021    0.000    0.047    0.000 calculus.py:2317(<dictcomp>)
   273700    0.018    0.000    0.018    0.000 {built-in method builtins.isinstance}
      900    0.015    0.000    0.033    0.000 {method 'parse_sequence' of 'sage.misc.parser.Parser' objects}

so, most stuff is happening in maxima and in _subs_, and somehow random elements of an intervalfield are needed ...
I don't think the design was primarily focused on numerical evaluation speed but rather on having symbolic piecewise functions.

Kwankyu Lee

unread,
May 1, 2024, 7:45:36 PMMay 1
to sage-devel
On Thursday, May 2, 2024 at 12:37:44 AM UTC+9 Nils Bruin wrote:
Working on *why* it might be so slow a bit:

%prun for i in range(100r): f(0.1)
         798103 function calls (791903 primitive calls) in 1.327 seconds

Impressive. Thanks.
 
so, most stuff is happening in maxima and in _subs_, and somehow random elements of an intervalfield are needed ...
I don't think the design was primarily focused on numerical evaluation speed but rather on having symbolic piecewise functions.

I wonder if they, maintainers of maxima, would regard this as a bug... 

 

Nils Bruin

unread,
May 1, 2024, 7:54:58 PMMay 1
to sage-devel
On Wednesday 1 May 2024 at 16:45:36 UTC-7 Kwankyu Lee wrote:

I wonder if they, maintainers of maxima, would regard this as a bug...

I'm pretty sure the piecewise functions are NOT borrowed from maxima. It probably gets called because there are some inequalities concerning the symbolic ring. So the performance observed here is not reduced to something that could be reported as a bug to maxima. I'd expect that performance can be significantly improved by optimizing the sage code.

Kwankyu Lee

unread,
May 2, 2024, 5:05:30 AMMay 2
to sage-devel


On Thursday, May 2, 2024 at 8:54:58 AM UTC+9 Nils Bruin wrote:
... I'd expect that performance can be significantly improved by optimizing the sage code.

Exactly. It is related with 

sage: time bool(x == 0.1)
CPU times: user 1.47 s, sys: 133 ms, total: 1.6 s
Wall time: 1.14 s
False

Kwankyu Lee

unread,
May 2, 2024, 5:13:40 AMMay 2
to sage-devel
Moreover,  this case seems to spur the need to introduce timing tests to watch out regressions in code performance without a failure.

Michael Orlitzky

unread,
May 2, 2024, 7:54:22 AMMay 2
to sage-...@googlegroups.com
On Thu, 2024-05-02 at 02:13 -0700, Kwankyu Lee wrote:
> Moreover, this case seems to spur the need to introduce timing tests to
> watch out regressions in code performance without a failure.
>

Shameless plug:

https://github.com/sagemath/sage/pull/36226

I see these regressions (old hardware), but AFAIK nobody else does.
This is largely due to the test suite reporting wall time. On fast
hardware, you won't notice if a test gets 2x slower because it's still
fast.

Reply all
Reply to author
Forward
0 new messages