Skip to content

Instantly share code, notes, and snippets.

@cswiercz
Created August 23, 2022 17:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cswiercz/066cec5f23ecc2b889bb06bdac8f2a94 to your computer and use it in GitHub Desktop.
Save cswiercz/066cec5f23ecc2b889bb06bdac8f2a94 to your computer and use it in GitHub Desktop.
Abelfunctions Performance Profile
Performance profile on the following Python script:
from sage.all_cmdline import * # import sage library
_sage_const_3 = Integer(3); _sage_const_2 = Integer(2); _sage_const_7 = Integer(7)
from abelfunctions import *
R = QQ['x, y']; (x, y,) = R._first_ngens(2)
X = RiemannSurface(y**_sage_const_3 + _sage_const_2 *x**_sage_const_3 *y - x**_sage_const_7 )
X.riemann_matrix()
Run using:
$ python -m cProfile -o output.profile ./riemann_matrix_perf_test.sage.py
$ python -m pstats ./output.profile
% sort cumulative
% stats 30
% sort time
% stats 30
========== Cumulative Time ==========
Tue Aug 23 09:59:26 2022 ./output.profile
209829119 function calls (209215439 primitive calls) in 170.681 seconds
Ordered by: cumulative time
List reduced from 10338 to 30 due to restriction <30>
ncalls tottime percall cumtime percall filename:lineno(function)
2445/1 0.017 0.000 170.687 170.687 {built-in method builtins.exec}
1 0.001 0.001 170.684 170.684 riemann_matrix_perf_test.sage.py:4(<module>)
1 0.001 0.001 166.831 166.831 riemann_surface.py:412(riemann_matrix)
1 0.000 0.000 166.375 166.375 riemann_surface.py:367(period_matrix)
1 0.000 0.000 165.341 165.341 riemann_surface.py:78(differentials)
1 0.000 0.000 165.341 165.341 riemann_surface.py:260(holomorphic_differentials)
1 0.000 0.000 165.341 165.341 differentials.py:225(differentials)
1 0.003 0.003 165.335 165.335 differentials.py:148(differentials_numerators)
7 0.032 0.005 164.374 23.482 differentials.py:55(mnuk_conditions)
123334/1120 1.277 0.000 162.012 0.145 unique_factorization_domains.py:128(_gcd_univariate_polynomial)
122214/4336 5.546 0.000 160.404 0.037 {method 'gcd' of 'sage.rings.polynomial.multi_polynomial.MPolynomial' objects}
493693/492517 3.114 0.000 105.133 0.000 rings.py:929(__getitem__)
504838/503338 4.037 0.000 101.327 0.000 polynomial_ring_constructor.py:51(PolynomialRing)
125 0.048 0.000 89.680 0.717 multi_polynomial_element.py:100(__call__)
504853 9.234 0.000 86.499 0.000 {built-in method sage.structure.category_object.normalize_names}
3141745 9.521 0.000 77.308 0.000 multi_polynomial_element.py:427(_repr_)
3141745 16.859 0.000 61.487 0.000 {method 'poly_repr' of 'sage.rings.polynomial.polydict.PolyDict' objects}
92108 1.037 0.000 27.379 0.000 multi_polynomial_element.py:1585(_floordiv_)
3141067 2.711 0.000 26.793 0.000 qqbar.py:3833(_neg_)
3746425 1.797 0.000 25.459 0.000 qqbar.py:4722(__init__)
3866050 7.548 0.000 24.742 0.000 qqbar.py:3592(__init__)
477 0.019 0.000 21.416 0.045 multi_polynomial_element.py:160(<listcomp>)
36 0.004 0.000 14.537 0.404 fraction_field.py:323(wrapper)
641591/641073 5.123 0.000 14.507 0.000 multi_polynomial_ring.py:176(__call__)
2129 0.105 0.000 13.869 0.007 qqbar_decorators.py:37(wrapper)
3748256 4.822 0.000 12.462 0.000 qqbar.py:6414(_interval_fast)
13622259 7.739 0.000 12.278 0.000 qqbar.py:4746(_richcmp_)
477 0.009 0.000 11.731 0.025 {sage.misc.misc_c.prod}
3342466 4.182 0.000 8.029 0.000 term_order.py:997(sortkey_degrevlex)
242379 1.240 0.000 6.815 0.000 polynomial_ring_constructor.py:754(_multi_variate)
========== Time ==========
Tue Aug 23 09:59:26 2022 ./output.profile
209829119 function calls (209215439 primitive calls) in 170.681 seconds
Ordered by: internal time
List reduced from 10338 to 30 due to restriction <30>
ncalls tottime percall cumtime percall filename:lineno(function)
3141745 16.859 0.000 61.487 0.000 {method 'poly_repr' of 'sage.rings.polynomial.polydict.PolyDict' objects}
3141745 9.521 0.000 77.308 0.000 multi_polynomial_element.py:427(_repr_)
504853 9.234 0.000 86.499 0.000 {built-in method sage.structure.category_object.normalize_names}
13622259 7.739 0.000 12.278 0.000 qqbar.py:4746(_richcmp_)
3866050 7.548 0.000 24.742 0.000 qqbar.py:3592(__init__)
44196401 6.505 0.000 6.507 0.000 {built-in method builtins.isinstance}
3984860 6.408 0.000 6.408 0.000 sets_cat.py:990(_element_constructor_from_element_class)
122214/4336 5.546 0.000 160.404 0.037 {method 'gcd' of 'sage.rings.polynomial.multi_polynomial.MPolynomial' objects}
641591/641073 5.123 0.000 14.507 0.000 multi_polynomial_ring.py:176(__call__)
3748256 4.822 0.000 12.462 0.000 qqbar.py:6414(_interval_fast)
3342466 4.182 0.000 8.029 0.000 term_order.py:997(sortkey_degrevlex)
504838/503338 4.037 0.000 101.327 0.000 polynomial_ring_constructor.py:51(PolynomialRing)
1014399/1014398 3.114 0.000 4.985 0.000 multi_polynomial_element.py:383(__init__)
493693/492517 3.114 0.000 105.133 0.000 rings.py:929(__getitem__)
3726542 2.827 0.000 3.411 0.000 qqbar.py:6346(__init__)
3141067 2.711 0.000 26.793 0.000 qqbar.py:3833(_neg_)
10364054 2.340 0.000 2.340 0.000 {built-in method sage.structure.richcmp.richcmp}
242905 1.979 0.000 3.982 0.000 term_order.py:570(__init__)
3141067 1.944 0.000 4.791 0.000 qqbar.py:6485(neg)
3047899/3017486 1.866 0.000 2.284 0.000 multi_polynomial_element.py:1554(__eq__)
3746425 1.797 0.000 25.459 0.000 qqbar.py:4722(__init__)
3787420 1.643 0.000 1.643 0.000 {built-in method sage.rings.real_mpfi.RealIntervalField}
3325365 1.560 0.000 2.778 0.000 term_order.py:885(sortkey)
3433818/3432726 1.299 0.000 1.351 0.000 {built-in method builtins.getattr}
11426729 1.294 0.000 1.294 0.000 {method 'parent' of 'sage.structure.element.Element' objects}
123334/1120 1.277 0.000 162.012 0.145 unique_factorization_domains.py:128(_gcd_univariate_polynomial)
51827 1.255 0.000 1.255 0.000 {built-in method select.select}
645587/645574 1.240 0.000 2.465 0.000 {method '_coerce_' of 'sage.structure.parent_old.Parent' objects}
242379 1.240 0.000 6.815 0.000 polynomial_ring_constructor.py:754(_multi_variate)
153813 1.177 0.000 1.787 0.000 {method '_mpoly_dict_recursive' of 'sage.rings.polynomial.polynomial_element.Polynomial' objects}
@cswiercz
Copy link
Author

A ton of time is spent doing arithmetic in QQbar and/or polynomial arithmetic. From what I remember a long while ago, the contents of differentials.py was a major performance choke point for the package. To clarify the timings, running

from abelfunctions import *
R.<x,y> = QQ[]
X = RiemannSurface(y**3 + 2*x**3*y - x**7)
X.holomorphic_differentials()

takes about 100s or about 60% of the Riemann matrix calculation time. Granted, this is half of requirements for computing the Riemann matrix but both analytic continuation and subsequent integration along the paths use the remaining 40% of time.

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