forked from sympy/sympy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sympy_time_cache.py
131 lines (92 loc) · 3.11 KB
/
sympy_time_cache.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
from __future__ import print_function
import timeit
class TreeNode(object):
def __init__(self, name):
self._name = name
self._children = []
self._time = 0
def __str__(self):
return "%s: %s" % (self._name, self._time)
__repr__ = __str__
def add_child(self, node):
self._children.append(node)
def children(self):
return self._children
def child(self, i):
return self.children()[i]
def set_time(self, time):
self._time = time
def time(self):
return self._time
total_time = time
def exclusive_time(self):
return self.total_time() - sum(child.time() for child in self.children())
def name(self):
return self._name
def linearize(self):
res = [self]
for child in self.children():
res.extend(child.linearize())
return res
def print_tree(self, level=0, max_depth=None):
print(" "*level + str(self))
if max_depth is not None and max_depth <= level:
return
for child in self.children():
child.print_tree(level + 1, max_depth=max_depth)
def print_generic(self, n=50, method="time"):
slowest = sorted((getattr(node, method)(), node.name()) for node in self.linearize())[-n:]
for time, name in slowest[::-1]:
print("%s %s" % (time, name))
def print_slowest(self, n=50):
self.print_generic(n=50, method="time")
def print_slowest_exclusive(self, n=50):
self.print_generic(n, method="exclusive_time")
def write_cachegrind(self, f):
if isinstance(f, str):
f = open(f, "w")
f.write("events: Microseconds\n")
f.write("fl=sympyallimport\n")
must_close = True
else:
must_close = False
f.write("fn=%s\n" % self.name())
f.write("1 %s\n" % self.exclusive_time())
counter = 2
for child in self.children():
f.write("cfn=%s\n" % child.name())
f.write("calls=1 1\n")
f.write("%s %s\n" % (counter, child.time()))
counter += 1
f.write("\n\n")
for child in self.children():
child.write_cachegrind(f)
if must_close:
f.close()
pp = TreeNode(None) # We have to use pp since there is a sage function
#called parent that gets imported
seen = set()
def new_import(name, globals={}, locals={}, fromlist=[]):
global pp
if name in seen:
return old_import(name, globals, locals, fromlist)
seen.add(name)
node = TreeNode(name)
pp.add_child(node)
old_pp = pp
pp = node
#Do the actual import
t1 = timeit.default_timer()
module = old_import(name, globals, locals, fromlist)
t2 = timeit.default_timer()
node.set_time(int(1000000*(t2 - t1)))
pp = old_pp
return module
old_import = __builtins__.__import__
__builtins__.__import__ = new_import
old_sum = sum
from sympy import *
sum = old_sum
sageall = pp.child(0)
sageall.write_cachegrind("sympy.cachegrind")
print("Timings saved. Do:\n$ kcachegrind sympy.cachegrind")