On
http://trac.sagemath.org/sage_trac/ticket/14579 I noticed that sage
is doing something very fancy to produce a short "repr" of a large
matrix: It doesn't print the entries (I knew that), but it even goes
delving in the stack to see if it can find a name to which the matrix
might possibly be bound! That's a very expensive operation:
Example code:
def t(depth,N,n):
if depth:
return t(depth-1,N,n)
else:
G = matrix([[2 for u in range(N)] for v in range(N)])
for i in range(n):
print repr(G)
Already for printing a single matrix the result shows up in timings:
sage: %time t(0,19,1)
[2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2]
... removed lines for brevity ...
[2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2]
CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
sage: %time t(0,20,1)
20 x 20 dense matrix over Integer Ring
CPU times: user 0.03 s, sys: 0.00 s, total: 0.03 s
Wall time: 0.03 s
This routine uses sage.misc.sageinspect.sage_getvariablename, which
goes digging in the globals of the entire stack to find the variable
name. Since globals dictionaries tend to be rather well-populated
(certainly in sage), this is a rather expensive operation (also
because assembling a "stack frame object" is a rather expensive
operation):
sage: timeit('t(100,19,10)')
125 loops, best of 3: 3.09 ms per loop
sage: timeit('t(100,20,10)')
5 loops, best of 3: 2.46 s per loop
As you see, roughly 1000x slower(!).
I understand it's mildly convenient to get:
sage: G = matrix([[2 for u in range(20)] for v in range(20)])
sage: print repr(G)
20 x 20 dense matrix over Integer Ring (type 'print G.str()' to see
all of the entries)
but the price of printing "G" is excessive. OK, it's printing
operation, but as a rule I'd say one should only go digging in stacks
for debugging, not as part of normal operation.
How about just changing this to "(use str(...) to see all entries)",
where we rely on the intelligence of the user to interpret "..." to
mean 'whatever access you have to the matrix'.
Note that this expensive trick always gets executed and frequently has
no useful result anyway:
sage: G = [matrix([[2 for u in range(20)] for v in range(20)])]
sage: print G
[20 x 20 dense matrix over Integer Ring]
In these cases, a static message about 'str' would be more useful
anyway.