[new attempt at filename display in html mode; clean up group names in json; more css on both views
Drew Perttula **20070207080851] {
hunk ./profileResults.html 4
-
+
hunk ./profileResults.html 19
+ function addFilenameLink(itemID, database, td) {
+ var filename = database.getObject(itemID, "filename");
+ td.innerHTML = "" + td.innerHTML + "";
+ }
+
hunk ./profileResults.html 34
+ self._columns[5].styler = addFilenameLink
hunk ./profileResults.html 43
-body {
- margin: 1em;
- }
- table {
- border: 0px solid black;
- border-collapse: collapse;
- }
- td {border: 0px solid black }
- div.bar {
- background:#72C8A1 none repeat scroll 0% 50%;
- }
-exhibit-tabularView-columnHeader {
- font-size: 50%;
-}
+ body {
+ margin: 1em;
+ background: #eee;
+ }
+
+ table {
+ border: 0px solid black;
+ border-collapse: collapse;
+ width: 100%;
+ }
+
+ td {border: 0px solid black }
+
+ div.bar {
+ background:#72C8A1 none repeat scroll 0% 50%;
+ }
+
+ exhibit-tabularView-columnHeader {
+ font-size: 50%;
+ }
+
+ span.exhibit-value {
+ margin: 0;
+ top: 0;
+ }
hunk ./profileResults.html 69
-span.exhibit-value {
- margin: 0;
- top: 0;
+ div.exhibit-facet-body {
+ height: 20em;
+ }
hunk ./profileResults.html 73
+.exhibit-ui-protection table {
+ font-size: 100%;
+}
+.exhibit-ui-protection tr {
+ vertical-align: top;
+}
+a img {
+ border: none;
+}
+
+div.exhibit-facet-body-frame {
+ background: #FDFBF0;
hunk ./profileResults.html 87
-div.exhibit-facet-body {
- height: 30em;
- width: 15em;
+div.exhibit-viewPanel {
+ background: white;
+ padding: 5px;
+ border: 1px solid black;
hunk ./profileResults.html 92
+
+
hunk ./profileResults.html 108
-
- ex:rowStyler="addBars"
-
+ ex:sortColumn="1"
+ ex:sortAscending="false"
hunk ./profileResults.html 114
-
+
hunk ./pstats2web 15
+from cPickle import dump, load
hunk ./pstats2web 17
-#import pstats
+import pstats
hunk ./pstats2web 20
+def getStats(filename):
+ """here is where to detect the difference between pstats and
+ hotshot stats and call the appropriate loader. But I haven't cared
+ about non-hotshot yet"""
+ return hotshot.stats.load(filename)
+ #return pstats.Stats(filename)
+
hunk ./pstats2web 52
- self.groups = [self.noFilename]
- else:
- self.groups = []
-
- for x in xrange(1, self.groupThreshold+1):
- dirlist = os.path.dirname(self.filename).split(os.sep)
- self.groups.append('/'.join(dirlist[-x:]))
-
- emptyGroups = reduce(lambda x, y: x and y,
- map(lambda x: x == '',
- self.groups))
+ self.groups = set([self.noFilename])
+ return
+
+ self.groups = set()
+ for x in xrange(1, self.groupThreshold+1):
+ dirlist = os.path.dirname(self.filename).split(os.sep)
+ tailParts = dirlist[-x:]
+ while (len(tailParts) > 1 and
+ tailParts[0] in ['lib', 'python2.4', 'site-packages',
+ 'build']):
+ tailParts.pop(0)
+ self.groups.add(os.sep.join(tailParts))
hunk ./pstats2web 65
- if emptyGroups:
- self.groups = [self.filename]
+ self.groups.difference_update(set([
+ 'python', 'lib/python2.4', 'python2.4'
+ ]))
+
+ if self.groups == set(['']):
+ self.groups = set([self.filename])
hunk ./pstats2web 80
-
-def style(filename):
- rgb = [int(x) / 10 for x in str(hash(filename))[-3:]]
- return "background: #%01x%01x%01x" % tuple(14 - x * 6 for x in rgb)
-
hunk ./pstats2web 81
+ """attempt to throw out large outliers in L. Currently, an outlier
+ is a vaule that's more than 5x the next smaller value.
+
+ current version is not great on [1,1,1,1,1,2,7,8], where i think
+ the answer is 2
+ """
hunk ./pstats2web 88
- return L[-4]
-
+ while len(L) > 2 and L[-1] > 5 * L[-2]:
+ L.pop()
+ return L[-1]
+
hunk ./pstats2web 96
-# s = pstats.Stats(filename)
- s = hotshot.stats.load(filename)
+ s = getStats(filename)
hunk ./pstats2web 104
+def rtrimTo(s, maxLen):
+ if len(s) > maxLen:
+ return "..." + s[-maxLen+3:]
+ return s
+
hunk ./pstats2web 117
- u'tottime' : func.tottime,
- u'cumtime' : func.cumtime,
+ u'tottime' : float("%.3f" % func.tottime),
+ u'cumtime' : float("%.3f" % func.cumtime),
+ u'tpercall' : float("%.4f" % func.tpercall),
hunk ./pstats2web 124
- u'label' : u'%s (%s:%s)' % (func.function, func.filename[-20:], func.linenum),
+ u'label' : u'%s (%s:%s)' % (func.function, rtrimTo(func.filename, 40), func.linenum),
hunk ./pstats2web 130
- if len(items) > 15:
- break
hunk ./pstats2web 134
- """return color,shortName for this filename:
+ cwd = os.path.abspath(os.getcwd()) + os.sep
hunk ./pstats2web 136
- /home/drewp/projects/ffg-http/Nevow/build/lib/nevow/flat/flatsax.py
- /usr/lib/python2.4/site-packages/twisted/python/reflect.py
- /usr/lib/python2.4/urllib.py
+ if filename == '':
+ return "stringCode", filename
hunk ./pstats2web 139
- """
- cwd = os.path.abspath(os.getcwd()) + '/'
- filename = os.path.abspath(filename)
- stdlib = '/usr/lib/python2.4/'
- if filename.startswith(stdlib) and not filename.startswith(stdlib + 'site-packages/'):
- label = "(stdlib )"
+ stdlib = os.path.dirname(os.__file__) + os.sep
+ if filename.startswith(stdlib) and not filename.startswith(stdlib + 'site-packages' + os.sep):
+ label = "(stdlib) "
hunk ./pstats2web 144
- return "blue", label + filename[len(stdlib):]
- sitePkg = '/usr/lib/python2.4/site-packages/'
+ return "stdlib", label + filename[len(stdlib):]
+
+ sitePkg = os.path.join(stdlib, 'site-packages/')
hunk ./pstats2web 148
- color = "green"
- nextDir = os.path.split(filename[len(sitePkg):])[0]
- if nextDir == 'twisted':
- color = "gray"
- return color, filename[len(sitePkg):]
- if '/nevow/' in filename: # special build that's not installed
- return "green", filename[filename.index('/nevow/')+1:]
- if filename.startswith(cwd):
- return "red", filename[len(cwd):]
- return "gray", filename
+ return "site-packages", filename[len(sitePkg):]
+
+ return "pkg-unknown", filename
+
+def style(filename):
+ rgb = [int(x) / 10 for x in str(hash(filename))[-3:]]
+ return "background: #%01x%01x%01x" % tuple(14 - x * 3 for x in rgb)
+
+def annotateCssNames(funcs):
+ """add more attributes to each func:
+
+ cssClass - 'stdlib', 'site-packages', 'pkg-unknown', 'pkg-{dirname}'
+ shortName - for displaying
+ suffix - internal use
+
+ returns additional CSS for coloring the pkg-{dirname} styles
+ """
+ prefixesToRemove = {} # prefix : count
+
+ for f in funcs:
+ cssClass, shortName = groupFilename(os.path.abspath(f.filename))
+ if cssClass == 'pkg-unknown':
+ parts = f.filename.split(os.sep)
+ # don't consider a single-piece prefix like 'foo/bar.py'
+ for i in range(2, len(parts)):
+ prefix = os.sep.join(parts[:i])
+ prefixesToRemove[prefix] = prefixesToRemove.get(prefix, 0) + 1
+
+ prefixes = sorted(prefixesToRemove, key=lambda p: -len(p))
+
+ classes = set()
+ for f in funcs:
+ suffix = f.filename
+ for prefix in prefixes:
+ if suffix.startswith(prefix):
+ prefix = prefix[:prefix[:-1].rfind(os.sep)]
+ suffix = suffix[len(prefix)+1:]
+ break
+ f.suffix = suffix
+
+ cssClass, shortName = groupFilename(f.suffix)
+
+ if cssClass == 'pkg-unknown' and os.sep in f.suffix:
+ cssClass = 'pkg-%s' % f.suffix[:f.suffix.find(os.sep)]
+ classes.add(cssClass)
+
+ f.cssClass = cssClass
+ f.shortName = shortName
+
+ css = ""
+ for cssClass in classes:
+ css += 'td.%s { %s }\n' % (cssClass, style(cssClass))
+ return css
hunk ./pstats2web 205
+
+ moreCss = annotateCssNames(funcs)
+
hunk ./pstats2web 210
- if f.function != 'profiler':
- #s = style(f.groups[0])
- color, shortName = groupFilename(f.filename)
+ if f.function != 'profiler':
+ location = [T.span(class_="fileLinenum")[
+ T.a(href=f.filename)[f.shortName], ":%d" % f.linenum],
+ " %s" % f.function]
hunk ./pstats2web 215
- T.td[bar(f.tottime, maxTottime)["%.3f" % f.tottime]],
+ T.td[bar(f.tottime, maxTottime)[
+ "%.3f" % f.tottime]],
hunk ./pstats2web 218
- T.td[bar(f.cumtime, maxCumtime)["%.3f" % f.cumtime]],
+ T.td[bar(f.cumtime, maxCumtime)[
+ "%.3f" % f.cumtime]],
hunk ./pstats2web 221
- T.td(style="background: %s" % color)["%s:%d(%s)" % (shortName, int(f.linenum), f.function)]],
+ T.td(class_=f.cssClass)[location]],
hunk ./pstats2web 234
+ padding: 2px;
+ white-space: nowrap;
hunk ./pstats2web 237
+
hunk ./pstats2web 241
- ''']
+ td.stdlib {
+ background: #99CCFF;
+ }
+ td.site-packages {
+ background: #E8C98B;
+ }
+
+ span.fileLinenum {
+ color: gray;
+ font-size: 90%;
+ }
+ span.fileLinenum a {
+ color: #444;
+ }
+ ''', moreCss]
hunk ./pstats2web 269
-
+
+def cacheFuncs(funcsGet):
+ """while you're working on this program, it's nice to not reload
+ the slow stats every time"""
+ f = "/tmp/stat"
+ if not os.path.exists(f):
+ funcs = funcsGet()
+ dump(funcs, open(f, "w"))
+ return funcs
+ return load(open(f))
hunk ./pstats2web 283
- parser.add_option("-j", "--output-json", help="output exhibit data to this file")
+ parser.add_option("-j", "--output-json",
+ help="output exhibit data to this file")
+ parser.add_option("-m", "--max-rows", type="int",
+ help="max rows to show, when sorted by decreasing total time")
hunk ./pstats2web 289
- funcs = parseProfile(sys.argv[1])
+ if 0: # for quick startups while testing
+ funcs = cacheFuncs(lambda: parseProfile(args[0]))
+ else:
+ funcs = parseProfile(args[0])
hunk ./pstats2web 294
- funcs.sort(key=lambda f: f.tottime,
- reverse=True)
+ funcs.sort(key=lambda f: f.tottime, reverse=True)
+ if opts.max_rows:
+ funcs = funcs[:opts.max_rows]
}