Is it assymptotically 10% or is it 10% for the case in which you are 
testing it? In the first case I would be surprised in the second case it is 
not that weird.

See the late_import function in src/sage/rings/complex_field.py for how you 
can speed up the import statement for the cyclic import case.

On Friday, 15 September 2017 20:31:51 UTC+2, Martin R wrote:
>
> I am now trying to speed up Permutation.to_matrix, which is meanwhile one 
> of the worst offenders in my application.  After some profiling I found the 
> following, which is quite a mystery to me. Apparently it is possible that 
> importing a module in a method costs a significant amount of time!
>
> QUESTION: is this an oversight or is there a good reason to import modules 
> in a relatively fundamental method like MatrixSpace.matrix?
>
> (I checked, moving out the first import makes the whole thing 
> (Permutation.to_matrix()) 10% faster.  I'm not saying that this is huge, 
> but it seems like a significant improvement to me.  Unfortunately, the 
> second module cannot be easily moved out, because of an import loop)
>
> This is #23870
>
> Martin
>
> sage: l = [pi for pi in Permutations(8)]
> sage: %lprun -f Permutation.to_matrix -f MatrixSpace.matrix 
> [pi.to_matrix() for pi in l]
> Timer unit: 1e-06 s
>
> Total time: 41.8048 s
> File: 
> /home/martin/sage-develop/local/lib/python2.7/site-packages/sage/matrix/matrix_space.py
> Function: matrix at line 1354
>
> Line #      Hits         Time  Per Hit   % Time  Line Contents
> ==============================================================
>   1354                                               def matrix(self, x=0, 
> coerce=True, copy=True):
>   ...
>   1493    362880      2800013      7.7      6.7          if x is None or 
> isinstance(x, (int, integer.Integer)) and x == 0:
>   1494                                                       if 
> self._copy_zero: # faster to copy than to create a new one.
>   1495                                                           return 
> self.zero_matrix().__copy__()
>   1496                                                       else:
>   1497                                                           return 
> self.__matrix_class(self, None, False, False)
>   1498    362880      2344112      6.5      5.6          if isinstance(x, 
> (int, integer.Integer)) and x == 1:
>   1499                                                       return 
> self.identity_matrix().__copy__()
>   1500    362880      1577558      4.3      3.8          m, n, sparse = 
> self.__nrows, self.__ncols, self.__is_sparse
>   1501    362880      1462412      4.0      3.5          if 
> matrix.is_Matrix(x):
>   1502                                                       if x.parent() 
> is self:
>   1503                                                           if 
> x.is_immutable():
>   1504                                                               
> return x
>   1505                                                           else:
>   1506                                                               
> return x.__copy__()
>   1507                                                       else:
>   1508                                                           if 
> x.nrows() == m and x.ncols() == n:
>   1509                                                               if 
> (x.base_ring() == self.base_ring()
>   1510                                                                   
> and x.is_sparse() and not sparse):
>   1511                                                                   # 
> If x is sparse and large, calling x.dense_matrix()
>   1512                                                                   # 
> is much faster than calling x.list(). See #20470.
>   1513                                                                   
> return x.dense_matrix()
>   1514                                                               x = 
> x.list()
>   1515                                                           else:
>   1516                                                               raise 
> ValueError("a matrix from %s cannot be converted to "
>   1517                                                                     
>            "a matrix in %s!" % (x.parent(), self))
>   1518    362880      5492940     15.1     13.1          from 
> sage.groups.matrix_gps.group_element import \
>   1519                                                       
> is_MatrixGroupElement
>   1520    362880      4978054     13.7     11.9          from 
> sage.modular.arithgroup.arithgroup_element import \
>   1521                                                       
> ArithmeticSubgroupElement
>   1522    362880      2613184      7.2      6.3          if 
> is_MatrixGroupElement(x) or isinstance(x, ArithmeticSubgroupElement):
>   1523                                                       return 
> self(x.matrix(), copy=False)
>   1524    362880      2036306      5.6      4.9          if isinstance(x, 
> (types.GeneratorType,)):
>   1525                                                       x = list(x)
>   1526    362880      1226969      3.4      2.9          if not sparse and 
> isinstance(x, dict):
>   1527                                                       x = 
> dict_to_list(x, m, n)
>   1528                                                       coerce = True
>   1529                                                       copy = False
>   1530    362880      1354039      3.7      3.2          MC = 
> self.__matrix_class
>   1531    362880      2139861      5.9      5.1          if isinstance(x, 
> (list, tuple)) and x:
>   1532                                                       if len(x) == 
> m:     # Try unpacking elements
>   1533                                                           unpacked 
> = True
>   1534                                                           new_x = []
>   1535                                                           for v in 
> x:
>   1536                                                               l = 
> len(new_x)
>   1537                                                               try:
>   1538                                                                   
> from sage.structure.element import is_Vector
>   1539                                                                   
> if isinstance(v, (list, tuple)) or is_Vector(v):
>   1540                                                                     
>   # The isinstance check should prevent the "flattening"
>   1541                                                                     
>   # of v if v is an iterable but not meant to be
>   1542                                                                     
>   # iterated (e.g., an element of a combinatorial free
>   1543                                                                     
>   # module).
>   1544                                                                     
>   new_x.extend(v)
>   1545                                                                   
> else:
>   1546                                                                     
>   raise TypeError
>   1547                                                                   
> if len(new_x) - l != n:
>   1548                                                                     
>   raise TypeError
>   1549                                                               
> except TypeError:
>   1550                                                                   
> unpacked = False
>   1551                                                           if 
> unpacked:
>   1552                                                               try:
>   1553                                                                   
> if sparse:
>   1554                                                                     
>   return MC(self, list_to_dict(new_x, m, n),
>   1555                                                                     
>             copy=False, coerce=coerce)
>   1556                                                                   
> else:
>   1557                                                                     
>   return MC(self, new_x, copy=False, coerce=coerce)
>   1558                                                               
> except (TypeError, ValueError):
>   1559                                                                   
> pass
>   1560                                                       if len(x) != 
> m * n:
>   1561                                                           raise 
> TypeError("cannot construct an element of {} from {}!"
>   1562                                                                     
>       .format(self, x))
>   1563                                                       if sparse:
>   1564                                                           x = 
> list_to_dict(x, m, n)
>   1565                                                           copy = 
> False
>   1566    362880     13779340     38.0     33.0          return MC(self, 
> x, copy=copy, coerce=coerce)
>
>

-- 
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+unsubscr...@googlegroups.com.
To post to this group, send email to sage-devel@googlegroups.com.
Visit this group at https://groups.google.com/group/sage-devel.
For more options, visit https://groups.google.com/d/optout.

Reply via email to