I haven't done any "professional" profiling, but it seems to me that the 
10% are stable, i.e., roughly independent of the size of the permutation.

I just found a much faster alternative: simply bypass MatrixSpace.matrix 
completely:

        entries = { (v-1, i): 1 for i, v in enumerate(self) }
        M = MatrixSpace(ZZ, len(self), sparse = True)
        return Matrix_integer_sparse(M, entries, False, False)

I am not completely sure what's better in the long run...  It somehow feels 
stupid that in order to optimize a function I have to inline it by hand, 
even if it's only one line.  I really miss FriCAS/Aldor.

Martin

Am Freitag, 15. September 2017 21:31:05 UTC+2 schrieb Maarten Derickx:
>
> 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