With this patch, this command works:
python3 hg --profile --config profiling.statformat=chrome st
(and it works with s/python3/python2/ as well)
| pulkit |
| hg-reviewers |
With this patch, this command works:
python3 hg --profile --config profiling.statformat=chrome st
(and it works with s/python3/python2/ as well)
| Automatic diff as part of commit; lint not applicable. |
| Automatic diff as part of commit; unit tests not applicable. |
There's a lot more that's needed for python3 hg --config profiling.statformat=chrome --profile to work, so I'll probably put more changes in this patch soon.
| Path | Packages | |||
|---|---|---|---|---|
| M | mercurial/statprof.py (12 lines) |
| Status | Author | Revision | |
|---|---|---|---|
| Closed | martinvonz | ||
| Closed | martinvonz | ||
| Closed | martinvonz | ||
| Closed | martinvonz | ||
| Closed | martinvonz |
| _pathcache = {} | _pathcache = {} | ||||
| def simplifypath(path): | def simplifypath(path): | ||||
| '''Attempt to make the path to a Python module easier to read by | '''Attempt to make the path to a Python module easier to read by | ||||
| removing whatever part of the Python search path it was found | removing whatever part of the Python search path it was found | ||||
| on.''' | on.''' | ||||
| if path in _pathcache: | if path in _pathcache: | ||||
| return _pathcache[path] | return _pathcache[path] | ||||
| hgpath = pycompat.fsencode(encoding.__file__).rsplit(os.sep, 2)[0] | hgpath = encoding.__file__.rsplit(os.sep, 2)[0] | ||||
| for p in [hgpath] + sys.path: | for p in [hgpath] + sys.path: | ||||
| prefix = p + os.sep | prefix = p + os.sep | ||||
| if path.startswith(prefix): | if path.startswith(prefix): | ||||
| path = path[len(prefix):] | path = path[len(prefix):] | ||||
| break | break | ||||
| _pathcache[path] = path | _pathcache[path] = path | ||||
| return path | return path | ||||
| def stackid(stack): | def stackid(stack): | ||||
| if not stack: | if not stack: | ||||
| return | return | ||||
| if stack in stack2id: | if stack in stack2id: | ||||
| return stack2id[stack] | return stack2id[stack] | ||||
| parent = stackid(stack[1:]) | parent = stackid(stack[1:]) | ||||
| myid = len(stack2id) | myid = len(stack2id) | ||||
| stack2id[stack] = myid | stack2id[stack] = myid | ||||
| id2stack.append(dict(category=stack[0][0], name='%s %s' % stack[0])) | id2stack.append(dict(category=stack[0][0], name=r'%s %s' % stack[0])) | ||||
| if parent is not None: | if parent is not None: | ||||
| id2stack[-1].update(parent=parent) | id2stack[-1].update(parent=parent) | ||||
| return myid | return myid | ||||
| # The sampling profiler can sample multiple times without | # The sampling profiler can sample multiple times without | ||||
| # advancing the clock, potentially causing the Chrome trace viewer | # advancing the clock, potentially causing the Chrome trace viewer | ||||
| # to render single-pixel columns that we cannot zoom in on. We | # to render single-pixel columns that we cannot zoom in on. We | ||||
| # work around this by pretending that zero-duration samples are a | # work around this by pretending that zero-duration samples are a | ||||
| def poplast(): | def poplast(): | ||||
| oldsid = stackid(tuple(laststack)) | oldsid = stackid(tuple(laststack)) | ||||
| oldcat, oldfunc = laststack.popleft() | oldcat, oldfunc = laststack.popleft() | ||||
| oldtime, oldidx = lastseen.popleft() | oldtime, oldidx = lastseen.popleft() | ||||
| duration = sample.time - oldtime | duration = sample.time - oldtime | ||||
| if minthreshold <= duration <= maxthreshold: | if minthreshold <= duration <= maxthreshold: | ||||
| # ensure no zero-duration events | # ensure no zero-duration events | ||||
| sampletime = max(oldtime + clamp, sample.time) | sampletime = max(oldtime + clamp, sample.time) | ||||
| samples.append(dict(ph='E', name=oldfunc, cat=oldcat, sf=oldsid, | samples.append(dict(ph=r'E', name=oldfunc, cat=oldcat, sf=oldsid, | ||||
| ts=sampletime*1e6, pid=0)) | ts=sampletime*1e6, pid=0)) | ||||
| else: | else: | ||||
| blacklist.add(oldidx) | blacklist.add(oldidx) | ||||
| # Much fiddling to synthesize correctly(ish) nested begin/end | # Much fiddling to synthesize correctly(ish) nested begin/end | ||||
| # events given only stack snapshots. | # events given only stack snapshots. | ||||
| for sample in data.samples: | for sample in data.samples: | ||||
| stack = tuple((('%s:%d' % (simplifypath(frame.path), frame.lineno), | stack = tuple(((r'%s:%d' % (simplifypath(pycompat.sysstr(frame.path)), frame.lineno), | ||||
| frame.function) for frame in sample.stack)) | pycompat.sysstr(frame.function)) for frame in sample.stack)) | ||||
| qstack = collections.deque(stack) | qstack = collections.deque(stack) | ||||
| if laststack == qstack: | if laststack == qstack: | ||||
| continue | continue | ||||
| while laststack and qstack and laststack[-1] == qstack[-1]: | while laststack and qstack and laststack[-1] == qstack[-1]: | ||||
| laststack.pop() | laststack.pop() | ||||
| qstack.pop() | qstack.pop() | ||||
| while laststack: | while laststack: | ||||
| poplast() | poplast() | ||||
| for f in reversed(qstack): | for f in reversed(qstack): | ||||
| lastseen.appendleft((sample.time, len(samples))) | lastseen.appendleft((sample.time, len(samples))) | ||||
| laststack.appendleft(f) | laststack.appendleft(f) | ||||
| path, name = f | path, name = f | ||||
| sid = stackid(tuple(laststack)) | sid = stackid(tuple(laststack)) | ||||
| samples.append(dict(ph='B', name=name, cat=path, ts=sample.time*1e6, | samples.append(dict(ph=r'B', name=name, cat=path, ts=sample.time*1e6, | ||||
| sf=sid, pid=0)) | sf=sid, pid=0)) | ||||
| laststack = collections.deque(stack) | laststack = collections.deque(stack) | ||||
| while laststack: | while laststack: | ||||
| poplast() | poplast() | ||||
| events = [sample for idx, sample in enumerate(samples) | events = [sample for idx, sample in enumerate(samples) | ||||
| if idx not in blacklist] | if idx not in blacklist] | ||||
| frames = collections.OrderedDict((str(k), v) | frames = collections.OrderedDict((str(k), v) | ||||
| for (k,v) in enumerate(id2stack)) | for (k,v) in enumerate(id2stack)) | ||||